Experiment with conversions between integers and floats.
Switch some conversions from libem calls to inline code. The conversions from integers to floats are now too slow, because each conversion allocates 4 or 5 registers, and the register allocator is too slow. I might use these slow conversions to experiment with the register allocator. I add the missing conversions between 4-byte single floats and integers, simply by going through 8-byte double floats. (These replace the calls to nonexistant functions in libem.) I remove the placeholder for fef 4, because it doesn't exist in libem, and our language runtimes only use fef 8.
This commit is contained in:
parent
2e41c392fa
commit
1de1e8f7f0
|
@ -320,6 +320,7 @@ INSTRUCTIONS
|
||||||
fadds FSREG:wo, FSREG:ro, FSREG:ro cost(4, 5).
|
fadds FSREG:wo, FSREG:ro, FSREG:ro cost(4, 5).
|
||||||
fcmpo CR:wo, FREG:ro, FREG:ro cost(4, 5).
|
fcmpo CR:wo, FREG:ro, FREG:ro cost(4, 5).
|
||||||
fcmpo CR:wo, FSREG:ro, FSREG:ro cost(4, 5).
|
fcmpo CR:wo, FSREG:ro, FSREG:ro cost(4, 5).
|
||||||
|
fctiwz FREG:wo, FREG:ro.
|
||||||
fdiv FREG:wo, FREG:ro, FREG:ro cost(4, 35).
|
fdiv FREG:wo, FREG:ro, FREG:ro cost(4, 35).
|
||||||
fdivs FSREG:wo, FSREG:ro, FSREG:ro cost(4, 21).
|
fdivs FSREG:wo, FSREG:ro, FSREG:ro cost(4, 21).
|
||||||
fmr FPR:wo, FPR:ro cost(4, 5).
|
fmr FPR:wo, FPR:ro cost(4, 5).
|
||||||
|
@ -2198,30 +2199,45 @@ PATTERNS
|
||||||
with FSREG
|
with FSREG
|
||||||
yields %1.1
|
yields %1.1
|
||||||
|
|
||||||
pat loc loc cfu $1==INT32 && $2==INT32 /* Convert single to unsigned int */
|
/* Convert single to signed int */
|
||||||
with STACK
|
pat loc loc cfi $1==4 && $2==4
|
||||||
gen
|
leaving
|
||||||
bl {LABEL, ".cfu4"}
|
loc 4
|
||||||
|
loc 8
|
||||||
|
cff
|
||||||
|
loc 8
|
||||||
|
loc 4
|
||||||
|
cfi
|
||||||
|
|
||||||
pat loc loc cfi $1==INT32 && $2==INT32 /* Convert single to signed int */
|
/* Convert single to unsigned int */
|
||||||
with STACK
|
pat loc loc cfu $1==4 && $2==4
|
||||||
gen
|
leaving
|
||||||
bl {LABEL, ".cfi4"}
|
loc 4
|
||||||
|
loc 8
|
||||||
|
cff
|
||||||
|
loc 8
|
||||||
|
loc 4
|
||||||
|
cfu
|
||||||
|
|
||||||
pat loc loc cif $1==INT32 && $2==INT32 /* Convert integer to single */
|
/* Convert signed int to single */
|
||||||
with STACK
|
pat loc loc cif $1==4 && $2==4
|
||||||
gen
|
leaving
|
||||||
bl {LABEL, ".cif4"}
|
loc 4
|
||||||
|
loc 8
|
||||||
|
cif
|
||||||
|
loc 8
|
||||||
|
loc 4
|
||||||
|
cff
|
||||||
|
|
||||||
pat loc loc cuf $1==INT32 && $2==INT32 /* Convert unsigned int to single */
|
/* Convert unsigned int to single */
|
||||||
with STACK
|
pat loc loc cuf $1==4 && $2==4
|
||||||
gen
|
leaving
|
||||||
bl {LABEL, ".cuf4"}
|
loc 4
|
||||||
|
loc 8
|
||||||
pat fef $1==INT32 /* Split single */
|
cuf
|
||||||
with STACK
|
loc 8
|
||||||
gen
|
loc 4
|
||||||
bl {LABEL, ".fef4"}
|
cff
|
||||||
|
|
||||||
/* Double-precision */
|
/* Double-precision */
|
||||||
|
|
||||||
|
@ -2328,26 +2344,63 @@ PATTERNS
|
||||||
frsp %a, %1
|
frsp %a, %1
|
||||||
yields %a
|
yields %a
|
||||||
|
|
||||||
pat loc loc cfu $1==INT64 && $2==INT32 /* Convert double to unsigned int */
|
/* Convert double to signed int */
|
||||||
|
pat loc loc cfi $1==8 && $2==4
|
||||||
|
with FREG STACK
|
||||||
|
uses reusing %1, FREG
|
||||||
|
gen
|
||||||
|
fctiwz %a, %1
|
||||||
|
stfdu %a, {IND_RC_D, SP, 0-8}
|
||||||
|
addi SP, SP, {CONST, 4}
|
||||||
|
|
||||||
|
/* Convert double to unsigned int */
|
||||||
|
pat loc loc cfu $1==8 && $2==4
|
||||||
with STACK
|
with STACK
|
||||||
gen
|
gen
|
||||||
bl {LABEL, ".cfu8"}
|
bl {LABEL, ".cfu8"}
|
||||||
|
|
||||||
pat loc loc cfi $1==INT64 && $2==INT32 /* Convert double to signed int */
|
/*
|
||||||
with STACK
|
* 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))
|
||||||
|
*/
|
||||||
|
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
|
gen
|
||||||
bl {LABEL, ".cfi8"}
|
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
|
||||||
|
|
||||||
pat loc loc cif $1==INT32 && $2==INT64 /* Convert integer to double */
|
/*
|
||||||
with STACK
|
* To convert unsigned integer u to IEEE double, we compute
|
||||||
kills ALL
|
* ((1 << 52) + u) - (1 << 52)
|
||||||
|
*/
|
||||||
|
pat loc loc cuf $1==4 && $2==8
|
||||||
|
with REG
|
||||||
|
uses REG={CONST_HZ, 0x43300000},
|
||||||
|
REG={CONST_0000_7FFF, 0},
|
||||||
|
FREG, FREG
|
||||||
gen
|
gen
|
||||||
bl {LABEL, ".cif8"}
|
stwu %a, {IND_RC_W, SP, 0-8}
|
||||||
|
stw %1, {IND_RC_W, SP, 4}
|
||||||
pat loc loc cuf $1==INT32 && $2==INT64 /* Convert unsigned int to double */
|
lfd %c, {IND_RC_D, SP, 0}
|
||||||
with STACK
|
stw %b, {IND_RC_W, SP, 4}
|
||||||
gen
|
lfd %d, {IND_RC_D, SP, 0}
|
||||||
bl {LABEL, ".cuf8"}
|
fsub %c, %c, %d
|
||||||
|
addi SP, SP, {CONST, 8}
|
||||||
|
yields %c
|
||||||
|
|
||||||
pat fef $1==INT64 /* Split exponent, fraction */
|
pat fef $1==INT64 /* Split exponent, fraction */
|
||||||
with GPR3 GPR4
|
with GPR3 GPR4
|
||||||
|
|
Loading…
Reference in a new issue