SPARC NCG: Split up into chunks, and fix warnings.
[ghc-hetmet.git] / compiler / nativeGen / SPARC / CodeGen / Amode.hs
diff --git a/compiler/nativeGen/SPARC/CodeGen/Amode.hs b/compiler/nativeGen/SPARC/CodeGen/Amode.hs
new file mode 100644 (file)
index 0000000..c3f4a28
--- /dev/null
@@ -0,0 +1,72 @@
+
+module SPARC.CodeGen.Amode (
+       getAmode
+)
+
+where
+
+import {-# SOURCE #-} SPARC.CodeGen.Gen32
+import SPARC.CodeGen.Base
+import SPARC.AddrMode
+import SPARC.Imm
+import SPARC.Instr
+import SPARC.Regs
+import SPARC.Base
+import NCGMonad
+import Size
+
+import Cmm
+
+import OrdList
+
+
+-- | Generate code to reference a memory address.
+getAmode 
+       :: CmmExpr      -- ^ expr producing an address
+       -> NatM Amode
+
+getAmode tree@(CmmRegOff _ _) 
+       = getAmode (mangleIndexTree tree)
+
+getAmode (CmmMachOp (MO_Sub _) [x, CmmLit (CmmInt i _)])
+  | fits13Bits (-i)
+  = do
+       (reg, code) <- getSomeReg x
+       let
+         off  = ImmInt (-(fromInteger i))
+       return (Amode (AddrRegImm reg off) code)
+
+
+getAmode (CmmMachOp (MO_Add _) [x, CmmLit (CmmInt i _)])
+  | fits13Bits i
+  = do
+       (reg, code) <- getSomeReg x
+       let
+        off  = ImmInt (fromInteger i)
+       return (Amode (AddrRegImm reg off) code)
+
+getAmode (CmmMachOp (MO_Add _) [x, y])
+  = do
+    (regX, codeX) <- getSomeReg x
+    (regY, codeY) <- getSomeReg y
+    let
+       code = codeX `appOL` codeY
+    return (Amode (AddrRegReg regX regY) code)
+
+getAmode (CmmLit lit)
+  = do
+       let imm__2      = litToImm lit
+       tmp1    <- getNewRegNat II32
+       tmp2    <- getNewRegNat II32
+
+       let code = toOL [ SETHI (HI imm__2) tmp1
+                       , OR    False tmp1 (RIImm (LO imm__2)) tmp2]
+               
+       return (Amode (AddrRegReg tmp2 g0) code)
+
+getAmode other
+  = do
+       (reg, code) <- getSomeReg other
+       let
+           off  = ImmInt 0
+       return (Amode (AddrRegImm reg off) code)