Page 246 - ARM 64 Bit Assembly Language
P. 246
234 Chapter 7
4 bigint_negate:
5 stp x29, x30, [sp, #-32]! // Save FP & Link Register x30
6 stp x19, x20, [sp, #16] // Save non-volatile regs
7 mov x19, x0 // x19 = bigint b
8 ldr w20, [x19, #8] // w20 = b->size
9 // initialize bigint struct to hold result
10 mov w0, 0x10000000 // w0 = -MAX_INT
11 cmp w20, w0
12 cinc w20, w20, EQ // increment size if -MAX_INT
13 mov w0, w20
14 bl bigint_alloc // x0 = bigint_alloc(b->size)
15 str w20, [x0, #8] // new->size = b->size
16 ldr x3, [x19] // x3 = b->blks (src chunks)
17 ldr x4, [x0] // x4 = new->blks(dest chunks)
18 // loop from least significant chunk to most significant
19 cmp w20, wzr // for(w20=size; w20>0; w20--)
20 ble endloop
21 negs xzr, xzr // set carry flag to 1
22 loop:
23 #ifdef EIGHT_BIT
24 ldrsb w6, [x3], #1 // load chunk from source
25 mvn w6, w6 // complement it (1’s comp.)
26 adc w6, w6, wzr // add carry flag
27 tst w6, 0x10
28 cneg xzr, xzr, NE // set carry flag on overflow
29 strb w6, [x4], #1 // store chunk in destination
30 #else
31 #ifdef SIXTEEN_BIT
32 ldrsh w6, [x3], #2 // load chunk from source
33 mvn w6, w6 // complement it (1’s comp.)
34 adc w6, w6, wzr // add carry flag
35 tst w6, 0x10000
36 cneg xzr, xzr, NE // set carry flag on overflow
37 strh w6, [x4], #2 // store chunk in destination
38 #else
39 #ifdef THIRTYTWO_BIT
40 ldr w6, [x3], #4 // load chunk from source
41 mvn w6, w6 // complement it (1’s comp.)
42 adcs w6, w6, wzr // add carry flag, set flags
43 str w6, [x4], #4 // store chunk in destination
44 #else
45 #ifdef SIXTYFOUR_BIT
46 ldr x6, [x3], #8 // load chunk from source
47 mvn x6, x6 // complement it (1’s comp.)
48 adcs x6, x6, xzr // add carry flag, set flags
49 str x6, [x4], #8 // store chunk in destination
50 #else /* default to 32 bits */
51 ldr w6, [x3], #4 // load chunk from source
52 mvn w6, w6 // complement it (1’s comp.)