From: George Koehler Date: Sun, 12 Feb 2017 04:23:47 +0000 (-0500) Subject: Experiment with conversions between integers and floats. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1de1e8f;p=ack.git 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. --- diff --git a/mach/powerpc/ncg/table b/mach/powerpc/ncg/table index 569f3dde4..f8bb205e3 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -320,6 +320,7 @@ INSTRUCTIONS fadds FSREG:wo, FSREG:ro, FSREG:ro cost(4, 5). fcmpo CR:wo, FREG:ro, FREG: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). fdivs FSREG:wo, FSREG:ro, FSREG:ro cost(4, 21). fmr FPR:wo, FPR:ro cost(4, 5). @@ -2198,30 +2199,45 @@ PATTERNS with FSREG yields %1.1 - pat loc loc cfu $1==INT32 && $2==INT32 /* Convert single to unsigned int */ - with STACK - gen - bl {LABEL, ".cfu4"} - - pat loc loc cfi $1==INT32 && $2==INT32 /* Convert single to signed int */ - with STACK - gen - bl {LABEL, ".cfi4"} - - pat loc loc cif $1==INT32 && $2==INT32 /* Convert integer to single */ - with STACK - gen - bl {LABEL, ".cif4"} - - pat loc loc cuf $1==INT32 && $2==INT32 /* Convert unsigned int to single */ - with STACK - gen - bl {LABEL, ".cuf4"} - - pat fef $1==INT32 /* Split single */ - with STACK - gen - bl {LABEL, ".fef4"} + /* Convert single to signed int */ + pat loc loc cfi $1==4 && $2==4 + leaving + loc 4 + loc 8 + cff + loc 8 + loc 4 + cfi + + /* Convert single to unsigned int */ + pat loc loc cfu $1==4 && $2==4 + leaving + loc 4 + loc 8 + cff + loc 8 + loc 4 + cfu + + /* Convert signed int to single */ + pat loc loc cif $1==4 && $2==4 + leaving + loc 4 + loc 8 + cif + loc 8 + loc 4 + cff + + /* Convert unsigned int to single */ + pat loc loc cuf $1==4 && $2==4 + leaving + loc 4 + loc 8 + cuf + loc 8 + loc 4 + cff /* Double-precision */ @@ -2328,26 +2344,63 @@ PATTERNS frsp %a, %1 yields %a - pat loc loc cfu $1==INT64 && $2==INT32 /* Convert double to unsigned int */ - with STACK + /* Convert double to signed int */ + pat loc loc cfi $1==8 && $2==4 + with FREG STACK + uses reusing %1, FREG gen - bl {LABEL, ".cfu8"} + fctiwz %a, %1 + stfdu %a, {IND_RC_D, SP, 0-8} + addi SP, SP, {CONST, 4} - pat loc loc cfi $1==INT64 && $2==INT32 /* Convert double to signed int */ + /* Convert double to unsigned int */ + pat loc loc cfu $1==8 && $2==4 with STACK gen - bl {LABEL, ".cfi8"} + bl {LABEL, ".cfu8"} - pat loc loc cif $1==INT32 && $2==INT64 /* Convert integer to double */ - with STACK - kills ALL - gen - bl {LABEL, ".cif8"} + /* + * 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 + 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 cuf $1==INT32 && $2==INT64 /* Convert unsigned int to double */ - with STACK - gen - bl {LABEL, ".cuf8"} + /* + * To convert unsigned integer u to IEEE double, we compute + * ((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 + 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 pat fef $1==INT64 /* Split exponent, fraction */ with GPR3 GPR4