diff options
author | Reid Barton <rwbarton@gmail.com> | 2014-08-11 09:33:13 -0400 |
---|---|---|
committer | Reid Barton <rwbarton@gmail.com> | 2014-08-11 09:33:20 -0400 |
commit | 71bd4e310793b9225767b66f3aa758156816632e (patch) | |
tree | be863eb6787aa61095877bf4e9b24e6b26e96656 /compiler/nativeGen | |
parent | 5f5d66298fbb6e50694d189767e69afa10e0dda0 (diff) | |
download | haskell-71bd4e310793b9225767b66f3aa758156816632e.tar.gz |
x86: Always generate add instruction in MO_Add2 (#9013)
Test Plan:
- ran validate
- ran T9013 test with all ways
- ran CarryOverflow test with all ways, for good measure
Reviewers: austin, simonmar
Reviewed By: simonmar
Differential Revision: https://phabricator.haskell.org/D137
Diffstat (limited to 'compiler/nativeGen')
-rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 5 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Instr.hs | 8 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Ppr.hs | 3 |
3 files changed, 14 insertions, 2 deletions
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index 04a1820749..d6fdee13f6 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -1912,9 +1912,10 @@ genCCall _ is32Bit target dest_regs args = do case args of [arg_x, arg_y] -> do hCode <- getAnyReg (CmmLit (CmmInt 0 width)) - lCode <- getAnyReg (CmmMachOp (MO_Add width) [arg_x, arg_y]) let size = intSize width - reg_l = getRegisterReg platform True (CmmLocal res_l) + lCode <- anyReg =<< trivialCode width (ADD_CC size) + (Just (ADD_CC size)) arg_x arg_y + let reg_l = getRegisterReg platform True (CmmLocal res_l) reg_h = getRegisterReg platform True (CmmLocal res_h) code = hCode reg_h `appOL` lCode reg_l `snocOL` diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs index 172ce93f50..b8b81aeba7 100644 --- a/compiler/nativeGen/X86/Instr.hs +++ b/compiler/nativeGen/X86/Instr.hs @@ -204,6 +204,12 @@ data Instr | DIV Size Operand -- eax := eax:edx/op, edx := eax:edx%op | IDIV Size Operand -- ditto, but signed + -- Int Arithmetic, where the effects on the condition register + -- are important. Used in specialized sequences such as MO_Add2. + -- Do not rewrite these instructions to "equivalent" ones that + -- have different effect on the condition register! (See #9013.) + | ADD_CC Size Operand Operand + -- Simple bit-twiddling. | AND Size Operand Operand | OR Size Operand Operand @@ -360,6 +366,7 @@ x86_regUsageOfInstr platform instr MUL2 _ src -> mkRU (eax:use_R src []) [eax,edx] DIV _ op -> mkRU (eax:edx:use_R op []) [eax,edx] IDIV _ op -> mkRU (eax:edx:use_R op []) [eax,edx] + ADD_CC _ src dst -> usageRM src dst AND _ src dst -> usageRM src dst OR _ src dst -> usageRM src dst @@ -533,6 +540,7 @@ x86_patchRegsOfInstr instr env MUL2 sz src -> patch1 (MUL2 sz) src IDIV sz op -> patch1 (IDIV sz) op DIV sz op -> patch1 (DIV sz) op + ADD_CC sz src dst -> patch2 (ADD_CC sz) src dst AND sz src dst -> patch2 (AND sz) src dst OR sz src dst -> patch2 (OR sz) src dst XOR sz src dst -> patch2 (XOR sz) src dst diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs index 15d29679b0..6e2da18719 100644 --- a/compiler/nativeGen/X86/Ppr.hs +++ b/compiler/nativeGen/X86/Ppr.hs @@ -563,6 +563,9 @@ pprInstr (ADC size src dst) pprInstr (SUB size src dst) = pprSizeOpOp (sLit "sub") size src dst pprInstr (IMUL size op1 op2) = pprSizeOpOp (sLit "imul") size op1 op2 +pprInstr (ADD_CC size src dst) + = pprSizeOpOp (sLit "add") size src dst + {- A hack. The Intel documentation says that "The two and three operand forms [of IMUL] may also be used with unsigned operands because the lower half of the product is the same regardless if |