Implement 2-word-multiply for x86_64
authorIan Lynagh <igloo@earth.li>
Fri, 24 Feb 2012 00:56:26 +0000 (00:56 +0000)
committerIan Lynagh <igloo@earth.li>
Fri, 24 Feb 2012 00:56:26 +0000 (00:56 +0000)
compiler/nativeGen/X86/CodeGen.hs
compiler/nativeGen/X86/Instr.hs
compiler/nativeGen/X86/Ppr.hs

index 5f58277..84f443e 100644 (file)
@@ -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)
index 6cd218c..18adee9 100644 (file)
@@ -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
index f2560fb..ffed2ec 100644 (file)
@@ -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