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.)
   241   242   243   244   245   246   247   248   249   250   251