diff options
author | Ian Lynagh <igloo@earth.li> | 2012-02-24 00:56:26 +0000 |
---|---|---|
committer | Ian Lynagh <igloo@earth.li> | 2012-02-24 00:56:26 +0000 |
commit | d16c68110cc2bbb9aaa47a6ac11ed4e57527646d (patch) | |
tree | 121cf2e2a508d64cb1d997e9a40deac8be2e40a1 | |
parent | 45eb0a425bb134d41e47a90e73ec5279c23bbc27 (diff) | |
download | haskell-d16c68110cc2bbb9aaa47a6ac11ed4e57527646d.tar.gz |
Implement 2-word-multiply for x86_64
-rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 15 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Instr.hs | 3 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Ppr.hs | 1 |
3 files changed, 19 insertions, 0 deletions
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index 5f582774c2..84f443eef2 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -1854,6 +1854,21 @@ genCCall64 target dest_regs args = ADC size (OpImm (ImmInteger 0)) (OpReg reg_h) return code _ -> panic "genCCall64: Wrong number of arguments/results for add2" + (CmmPrim (MO_U_Mul2 width) _, [CmmHinted res_h _, CmmHinted res_l _]) -> + case args of + [CmmHinted arg_x _, CmmHinted arg_y _] -> + do (y_reg, y_code) <- getRegOrMem arg_y + x_code <- getAnyReg arg_x + let size = intSize width + reg_h = getRegisterReg True (CmmLocal res_h) + reg_l = getRegisterReg True (CmmLocal res_l) + code = y_code `appOL` + x_code rax `appOL` + toOL [MUL2 size y_reg, + MOV size (OpReg rdx) (OpReg reg_h), + MOV size (OpReg rax) (OpReg reg_l)] + return code + _ -> panic "genCCall64: Wrong number of arguments/results for add2" (CmmPrim _ (Just mkStmts), results) -> stmtsToInstrs (mkStmts results args) diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs index 6cd218cc1e..18adee9915 100644 --- a/compiler/nativeGen/X86/Instr.hs +++ b/compiler/nativeGen/X86/Instr.hs @@ -188,6 +188,7 @@ data Instr | SUB Size Operand Operand | MUL Size Operand Operand + | MUL2 Size Operand -- %edx:%eax = operand * %rax | IMUL Size Operand Operand -- signed int mul | IMUL2 Size Operand -- %edx:%eax = operand * %eax @@ -332,6 +333,7 @@ x86_regUsageOfInstr instr IMUL _ src dst -> usageRM src dst IMUL2 _ src -> mkRU (eax:use_R src []) [eax,edx] MUL _ src dst -> usageRM src dst + 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] AND _ src dst -> usageRM src dst @@ -473,6 +475,7 @@ x86_patchRegsOfInstr instr env 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 + MUL2 sz src -> patch1 (MUL2 sz) src IDIV sz op -> patch1 (IDIV sz) op DIV sz op -> patch1 (DIV sz) op AND sz src dst -> patch2 (AND sz) src dst diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs index f2560fb697..ffed2ec44a 100644 --- a/compiler/nativeGen/X86/Ppr.hs +++ b/compiler/nativeGen/X86/Ppr.hs @@ -609,6 +609,7 @@ pprInstr platform (IMUL2 sz op) = pprSizeOp platform (sLit "imul") sz op -- x86_64 only pprInstr platform (MUL size op1 op2) = pprSizeOpOp platform (sLit "mul") size op1 op2 +pprInstr platform (MUL2 size op) = pprSizeOp platform (sLit "mul") size op pprInstr platform (FDIV size op1 op2) = pprSizeOpOp platform (sLit "div") size op1 op2 |