SPARC NCG: Add support for hardware divide
[ghc-hetmet.git] / compiler / nativeGen / MachInstrs.hs
index 2ae4474..e16dbf3 100644 (file)
@@ -558,9 +558,23 @@ is_G_instr instr
 -- Int Arithmetic.
              | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
              | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
+
              | UMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
              | SMUL               Bool Reg RI Reg --     cc?, src1, src2, dst
-              | RDY           Reg      -- move contents of Y register to reg
+
+
+              -- The SPARC divide instructions perform 64bit by 32bit division
+             --   The Y register is xored into the first operand.
+
+             --   On _some implementations_ the Y register is overwritten by
+              --   the remainder, so we have to make sure it is 0 each time.
+
+              --   dst <- ((Y `shiftL` 32) `or` src1) `div` src2
+              | UDIV               Bool Reg RI Reg --     cc?, src1, src2, dst
+             | SDIV               Bool Reg RI Reg --     cc?, src1, src2, dst
+
+              | RDY           Reg                  -- move contents of Y register to reg
+              | WRY           Reg  Reg             -- Y <- src1 `xor` src2
 
 -- Simple bit-twiddling.
              | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
@@ -591,8 +605,8 @@ is_G_instr instr
              | FxTOy         Size Size Reg Reg -- src, dst
 
 -- Jumping around.
-             | BI            Cond Bool Imm -- cond, annul?, target
-             | BF            Cond Bool Imm -- cond, annul?, target
+             | BI            Cond Bool BlockId -- cond, annul?, target
+             | BF            Cond Bool BlockId -- cond, annul?, target
 
              | JMP           AddrMode     -- target
              | CALL          (Either Imm Reg) Int Bool -- target, args, terminal
@@ -617,9 +631,17 @@ moveSp n
    = ADD False False sp (RIImm (ImmInt (n * wORD_SIZE))) sp
 
 -- Produce the second-half-of-a-double register given the first half.
-fPair :: Reg -> Reg
-fPair (RealReg n) | n >= 32 && n `mod` 2 == 0  = RealReg (n+1)
-fPair other = pprPanic "fPair(sparc NCG)" (ppr other)
+fPair :: Reg -> Maybe Reg
+fPair (RealReg n) 
+       | n >= 32 && n `mod` 2 == 0  = Just (RealReg (n+1))
+
+fPair (VirtualRegD u)
+       = Just (VirtualRegHi u)
+
+fPair other 
+       = trace ("MachInstrs.fPair: can't get high half of supposed double reg " ++ show other) 
+               Nothing
+               
 #endif /* sparc_TARGET_ARCH */