.define .cif8
.cif8:
- addi sp, sp, -4 ! make space for the double
+ ! Conversion uses the pivot value
+ ! 1 << 52 = 0x4330 0000 0000 0000
+ !
+ ! From signed integer i, we compute
+ ! ((1 << 52) + (1 << 31) + i) - ((1 << 52) + (1 << 31))
+
+ lis r3, 0x4330
+ stwu r3, -4(sp) ! make space for the double
lwz r3, 4(sp)
xoris r3, r3, 0x8000
- stw r3, 4(sp) ! flip sign of integer value
-
- addis r3, r0, 0x4330
- stw r3, 0(sp) ! set high word to construct a double
+ stw r3, 4(sp) ! flip sign bit to get (1 << 31) + i
- lfd f0, 0(sp) ! load value
-
- lis r3, ha16[pivot]
- lfd f1, lo16[pivot](r3) ! load pivot value
- fsub f0, f0, f1 ! adjust
+ lfd f0, 0(sp) ! f0 = (1 << 52) + (1 << 31) + i
+ lis r3, 0x8000
+ stw r3, 4(sp)
+ lfd f1, 0(sp) ! f1 = (1 << 52) + (1 << 31)
+ fsub f0, f0, f1 ! finish conversion
stfd f0, 0(sp) ! save value again...
blr ! ...and return
-
-.sect .rom
-pivot:
- .data4 0x43300000
- .data4 0x80000000
.define .cuf8
.cuf8:
- addi sp, sp, -4 ! make space for the double
+ ! Conversion uses the pivot value
+ ! 1 << 52 = 0x4330 0000 0000 0000
+ !
+ ! From unsigned integer u, we compute
+ ! ((1 << 52) + u) - (1 << 52)
lis r3, 0x4330
- stw r3, 0(sp) ! set high word to construct a double
+ stwu r3, -4(sp) ! make space for the double
- lfd f0, 0(sp) ! load value
-
- lis r3, ha16[pivot]
- lfd f1, lo16[pivot](r3) ! load pivot value
- fsub f0, f0, f1 ! adjust
+ lfd f0, 0(sp) ! f0 = (1 << 52) + u
+ li r3, 0x0000
+ stw r3, 4(sp)
+ lfd f1, 0(sp) ! f1 = (1 << 52)
+ fsub f0, f0, f1 ! finish conversion
stfd f0, 0(sp) ! save value again...
blr ! ...and return
-
-.sect .rom
-pivot:
- .data4 0x43300000
- .data4 0x00000000
leaving
cal ".cfu8"
- /*
- * To convert integer to IEEE double, we pack the integer in
- * the low bits of the magic double
- * 1 << 52 == 0x 4330 0000 0000 0000
- *
- * For signed integer i, we flip its sign bit, then compute
- * ((1 << 52) + i) - ((1 << 52) + (1 << 31))
- */
+ /* Convert signed int to double */
pat loc loc cif $1==4 && $2==8
- with REG
- uses reusing %1, REG={XOR_RIS, %1, 0x8000},
- REG={CONST_HZ, 0x43300000},
- REG={CONST_HZ, 0x80000000},
- FREG, FREG
- gen
- stwu %b, {IND_RC_W, sp, 0-8}
- stw %a, {IND_RC_W, sp, 4}
- lfd %d, {IND_RC_D, sp, 0}
- stw %c, {IND_RC_W, sp, 4}
- lfd %e, {IND_RC_D, sp, 0}
- fsub %d, %d, %e
- addi sp, sp, {CONST, 8}
- yields %d
+ leaving
+ cal ".cif8"
- /*
- * To convert unsigned integer u to IEEE double, we compute
- * ((1 << 52) + u) - (1 << 52)
- */
+ /* Convert unsigned int to double */
pat loc loc cuf $1==4 && $2==8
- with REG
- uses REG={CONST_HZ, 0x43300000},
- REG={CONST_0000_7FFF, 0},
- FREG, FREG
- gen
- stwu %a, {IND_RC_W, sp, 0-8}
- stw %1, {IND_RC_W, sp, 4}
- lfd %c, {IND_RC_D, sp, 0}
- stw %b, {IND_RC_W, sp, 4}
- lfd %d, {IND_RC_D, sp, 0}
- fsub %c, %c, %d
- addi sp, sp, {CONST, 8}
- yields %c
+ leaving
+ cal ".cuf8"
pat fef $1==8 /* Split fraction, exponent */
leaving