summaryrefslogtreecommitdiff
path: root/4/practice_problem_4_3_iaddq.c
blob: 4e8add2dddda3eac7b6b7cd16d4a17d1549d2b3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <stdio.h>

long sum(long *start, long count)
{
	long sum = 0;
	while (count) {
		sum += *start;
		start++;
		count--;
	}
	return sum;
}

int main() {
	long start[] = { 42, 11, 12 };
	return printf("%d\n", sum(start, (long)1));
}

/*
long sum(long *start, long count)
start in %rdi, count in %rsi
sum:
	movl $0, %eax		sum = 0
	jmp .12			Goto test
.L3:				loop:
	addq (%rdi), %rax 		Add *start
	addq $8, %rdi 			start++
	subq $1, %rsi 			count--
.L2: 				test:
	testq %rsi, %rsi 		Test sum
	jne .L3 			If !=O, goto loop
	rep; ret			Return
*/

/*
long sum(long *start, long count)
start in %rdi, count in %rsi
sum:
	irmovq $8,%r8 		Constant 8
	irmovq $1,%r9 		Constant 1
	xorq %rax,%rax		sum = 0
	andq %rsi,%rsi		Set cc
	jmp test		Goto test
loop:
	mrmovq (%rdi), %r10 	Get *start
	addq %r10,%rax		Add to sum
	addq %r8,%rdi 		start++
	subq %r9,%rsi 		count--. Set CC
test:
	jne loop		Stop when 0
	ret
*/

/* Using iaddq
First byte
- C, 12
- 0, first variant of iadd

Second byte
- F, 15, absence of first argument
- rB, register number 0-15 to add V to

Other 0-8 bytes V

long sum(long *start, long count)
start in %rdi, count in %rsi
sum:
	xorq %rax,%rax		sum = 0
	andq %rsi,%rsi		Set cc (nop), ZF=0 if count != 0 else 1, SF=0 if count > 0, OF=0
	jmp test		Goto test
loop:
	mrmovq (%rdi), %r10 	Get *start
	addq %r10,%rax		Add to sum
	iaddq $8,%rdi 		start++
	iaddq $-1,%rsi 		count--. Set CC
test:
	jne loop		Stop when 0, (~ZF)
	ret
*/