Page 272 - ARM 64 Bit Assembly Language
P. 272
Non-integral mathematics 261
Listing 8.2 Dividing x by 23 with 8 bits of precision.
1 // Assume that w0 already contains x, where -129 < x < 128
2 // and x1 is available to hold 1/23 * 2^3
3 ldr w1,=0b01011010 // Load 1/23 * 2^3 into r1
4 umull x1,w0,w1 // Perform multiply
5 asr x1,x1,#11 // shift result right by 8+3 bits
6 add x1,x1,x1,lsr #63 // add one if result is negative
Listing 8.3 Dividing x by 23 Using Only Shift and Add
1 // Assume that x0 already contains x, where -129 < x < 128
2 // and x1 is available to hold 1/23 * 2^3
3 add x0,x0,x0,lsl #2 // r0 <- x + x*4 = 5x
4 add x0,x0,x0,lsl #3 // r0 <- 5x + 5x*8 = 45x
5 asr x1,x1,#10 // shift result right
6 add x1,x1,x1,lsr #63 // add one if result is negative
how the 8-bit division code would be implemented in AArch64 assembly. Listing 8.3
shows an alternate implementation which uses shift and add operations rather than a multi-
ply.
8.4.4.2 Division by constant −50
The procedure is exactly the same for dividing by a negative constant. Suppose we want
efficient code to calculate x using 16-bit signed integers. We first convert 1 into bi-
−50 50
nary:
1
= 0.0000010100011110
50
The two’s complement of 1 is
50
1
= 1.1111101011100001
−50
We can represent 1 as the following S(1,21) fixed point number:
−50