diff options
author | Peter Trommler <ptrommler@acm.org> | 2018-12-26 20:23:44 +0100 |
---|---|---|
committer | Peter Trommler <ptrommler@acm.org> | 2018-12-28 11:14:29 +0100 |
commit | da42c43cfcfb29276deb4c0ea2801a1b01d19e12 (patch) | |
tree | 0ffa27e7cbf0af60b23f6ce52e2ac3b4e28a1cfc | |
parent | e29adf0577f59bcd265ac6ff7a73f26d900d66f7 (diff) | |
download | haskell-da42c43cfcfb29276deb4c0ea2801a1b01d19e12.tar.gz |
PPC NCG: Fix signed 64-bit compare on 32-bitwip/T16094
-rw-r--r-- | compiler/nativeGen/PPC/CodeGen.hs | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs index 6c5d7d2915..d46bef7ba5 100644 --- a/compiler/nativeGen/PPC/CodeGen.hs +++ b/compiler/nativeGen/PPC/CodeGen.hs @@ -911,23 +911,45 @@ condIntCode cond width x y = do condIntCode' :: Bool -> Cond -> Width -> CmmExpr -> CmmExpr -> NatM CondCode -- simple code for 64-bit on 32-bit platforms -condIntCode' True cond W64 x y = do - ChildCode64 code_x x_lo <- iselExpr64 x - ChildCode64 code_y y_lo <- iselExpr64 y - let x_hi = getHiVRegFromLo x_lo - y_hi = getHiVRegFromLo y_lo - cmp = if condUnsigned cond then CMPL else CMP - end_lbl <- getBlockIdNat - let code = code_x `appOL` code_y `appOL` toOL - [ cmp II32 x_hi (RIReg y_hi) - , BCC NE end_lbl Nothing - , cmp II32 x_lo (RIReg y_lo) - , BCC ALWAYS end_lbl Nothing - - , NEWBLOCK end_lbl - ] - return (CondCode False cond code) - +condIntCode' True cond W64 x y + | condUnsigned cond + = do + ChildCode64 code_x x_lo <- iselExpr64 x + ChildCode64 code_y y_lo <- iselExpr64 y + let x_hi = getHiVRegFromLo x_lo + y_hi = getHiVRegFromLo y_lo + end_lbl <- getBlockIdNat + let code = code_x `appOL` code_y `appOL` toOL + [ CMPL II32 x_hi (RIReg y_hi) + , BCC NE end_lbl Nothing + , CMPL II32 x_lo (RIReg y_lo) + , BCC ALWAYS end_lbl Nothing + + , NEWBLOCK end_lbl + ] + return (CondCode False cond code) + | otherwise + = do + ChildCode64 code_x x_lo <- iselExpr64 x + ChildCode64 code_y y_lo <- iselExpr64 y + let x_hi = getHiVRegFromLo x_lo + y_hi = getHiVRegFromLo y_lo + end_lbl <- getBlockIdNat + cmp_lo <- getBlockIdNat + let code = code_x `appOL` code_y `appOL` toOL + [ CMP II32 x_hi (RIReg y_hi) + , BCC NE end_lbl Nothing + , CMP II32 x_hi (RIImm (ImmInt 0)) + , BCC LE cmp_lo Nothing + , CMPL II32 x_lo (RIReg y_lo) + , BCC ALWAYS end_lbl Nothing + , CMPL II32 y_lo (RIReg x_lo) + , BCC ALWAYS end_lbl Nothing + + , NEWBLOCK end_lbl + ] + return (CondCode False cond code) + -- optimize pointer tag checks. Operation andi. sets condition register -- so cmpi ..., 0 is redundant. condIntCode' _ cond _ (CmmMachOp (MO_And _) [x, CmmLit (CmmInt imm rep)]) |