diff options
Diffstat (limited to 'compiler/nativeGen')
-rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 71 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Instr.hs | 3 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Ppr.hs | 7 |
3 files changed, 60 insertions, 21 deletions
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index abd87ed087..a4115a0b6d 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -391,6 +391,21 @@ iselExpr64 (CmmMachOp (MO_Add _) [e1,e2]) = do ADC II32 (OpReg r2hi) (OpReg rhi) ] return (ChildCode64 code rlo) +iselExpr64 (CmmMachOp (MO_Sub _) [e1,e2]) = do + ChildCode64 code1 r1lo <- iselExpr64 e1 + ChildCode64 code2 r2lo <- iselExpr64 e2 + (rlo,rhi) <- getNewRegPairNat II32 + let + r1hi = getHiVRegFromLo r1lo + r2hi = getHiVRegFromLo r2lo + code = code1 `appOL` + code2 `appOL` + toOL [ MOV II32 (OpReg r1lo) (OpReg rlo), + SUB II32 (OpReg r2lo) (OpReg rlo), + MOV II32 (OpReg r1hi) (OpReg rhi), + SBB II32 (OpReg r2hi) (OpReg rhi) ] + return (ChildCode64 code rlo) + iselExpr64 (CmmMachOp (MO_UU_Conv _ W64) [expr]) = do fn <- getAnyReg expr r_dst_lo <- getNewRegNat II32 @@ -1272,24 +1287,23 @@ getCondCode (CmmMachOp mop [x, y]) MO_F_Lt W64 -> condFltCode LTT x y MO_F_Le W64 -> condFltCode LE x y - MO_Eq _ -> condIntCode EQQ x y - MO_Ne _ -> condIntCode NE x y - - MO_S_Gt _ -> condIntCode GTT x y - MO_S_Ge _ -> condIntCode GE x y - MO_S_Lt _ -> condIntCode LTT x y - MO_S_Le _ -> condIntCode LE x y - - MO_U_Gt _ -> condIntCode GU x y - MO_U_Ge _ -> condIntCode GEU x y - MO_U_Lt _ -> condIntCode LU x y - MO_U_Le _ -> condIntCode LEU x y - - _other -> pprPanic "getCondCode(x86,x86_64)" (ppr (CmmMachOp mop [x,y])) + _ -> condIntCode (machOpToCond mop) x y getCondCode other = pprPanic "getCondCode(2)(x86,x86_64)" (ppr other) - +machOpToCond :: MachOp -> Cond +machOpToCond mo = case mo of + MO_Eq _ -> EQQ + MO_Ne _ -> NE + MO_S_Gt _ -> GTT + MO_S_Ge _ -> GE + MO_S_Lt _ -> LTT + MO_S_Le _ -> LE + MO_U_Gt _ -> GU + MO_U_Ge _ -> GEU + MO_U_Lt _ -> LU + MO_U_Le _ -> LEU + _other -> pprPanic "machOpToCond" (pprMachOp mo) -- @cond(Int|Flt)Code@: Turn a boolean expression into a condition, to be @@ -1538,7 +1552,31 @@ genCondJump -> CmmExpr -- the condition on which to branch -> NatM InstrBlock -genCondJump id bool = do +genCondJump id expr = do + is32Bit <- is32BitPlatform + genCondJump' is32Bit id expr + +genCondJump' :: Bool -> BlockId -> CmmExpr -> NatM InstrBlock + +-- 64-bit integer comparisons on 32-bit +genCondJump' is32Bit true (CmmMachOp mop [e1,e2]) + | is32Bit, Just W64 <- maybeIntComparison mop = do + ChildCode64 code1 r1_lo <- iselExpr64 e1 + ChildCode64 code2 r2_lo <- iselExpr64 e2 + let r1_hi = getHiVRegFromLo r1_lo + r2_hi = getHiVRegFromLo r2_lo + cond = machOpToCond mop + Just cond' = maybeFlipCond cond + false <- getBlockIdNat + return $ code1 `appOL` code2 `appOL` toOL [ + CMP II32 (OpReg r2_hi) (OpReg r1_hi), + JXX cond true, + JXX cond' false, + CMP II32 (OpReg r2_lo) (OpReg r1_lo), + JXX cond true, + NEWBLOCK false ] + +genCondJump' _ id bool = do CondCode is_float cond cond_code <- getCondCode bool use_sse2 <- sse2Enabled if not is_float || not use_sse2 @@ -1569,7 +1607,6 @@ genCondJump id bool = do ] return (cond_code `appOL` code) - -- ----------------------------------------------------------------------------- -- Generating C calls diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs index 2f6196227b..0d85376868 100644 --- a/compiler/nativeGen/X86/Instr.hs +++ b/compiler/nativeGen/X86/Instr.hs @@ -196,6 +196,7 @@ data Instr | ADD Size Operand Operand | ADC Size Operand Operand | SUB Size Operand Operand + | SBB Size Operand Operand | MUL Size Operand Operand | MUL2 Size Operand -- %edx:%eax = operand * %rax @@ -365,6 +366,7 @@ x86_regUsageOfInstr platform instr ADD _ src dst -> usageRM src dst ADC _ src dst -> usageRM src dst SUB _ src dst -> usageRM src dst + SBB _ src dst -> usageRM src dst IMUL _ src dst -> usageRM src dst IMUL2 _ src -> mkRU (eax:use_R src []) [eax,edx] MUL _ src dst -> usageRM src dst @@ -543,6 +545,7 @@ x86_patchRegsOfInstr instr env ADD sz src dst -> patch2 (ADD sz) src dst ADC sz src dst -> patch2 (ADC sz) src dst SUB sz src dst -> patch2 (SUB sz) src dst + SBB sz src dst -> patch2 (SBB sz) src dst IMUL sz src dst -> patch2 (IMUL sz) src dst IMUL2 sz src -> patch1 (IMUL2 sz) src MUL sz src dst -> patch2 (MUL sz) src dst diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs index cc39557f1d..2b3711751c 100644 --- a/compiler/nativeGen/X86/Ppr.hs +++ b/compiler/nativeGen/X86/Ppr.hs @@ -570,11 +570,10 @@ pprInstr (ADD size (OpImm (ImmInt (-1))) dst) = pprSizeOp (sLit "dec") size dst pprInstr (ADD size (OpImm (ImmInt 1)) dst) = pprSizeOp (sLit "inc") size dst -pprInstr (ADD size src dst) - = pprSizeOpOp (sLit "add") size src dst -pprInstr (ADC size src dst) - = pprSizeOpOp (sLit "adc") size src dst +pprInstr (ADD size src dst) = pprSizeOpOp (sLit "add") size src dst +pprInstr (ADC size src dst) = pprSizeOpOp (sLit "adc") size src dst pprInstr (SUB size src dst) = pprSizeOpOp (sLit "sub") size src dst +pprInstr (SBB size src dst) = pprSizeOpOp (sLit "sbb") size src dst pprInstr (IMUL size op1 op2) = pprSizeOpOp (sLit "imul") size op1 op2 pprInstr (ADD_CC size src dst) |