NCG: Rename MachRegs, MachInstrs -> Regs, Instrs to reflect arch specific naming
[ghc-hetmet.git] / compiler / nativeGen / SPARC / Instr.hs
1 -----------------------------------------------------------------------------
2 --
3 -- Machine-dependent assembly language
4 --
5 -- (c) The University of Glasgow 1993-2004
6 --
7 -----------------------------------------------------------------------------
8
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
11
12 module SPARC.Instr (
13         Cond(..),
14         RI(..),
15         Instr(..),
16         riZero,
17         fpRelEA,
18         moveSp,
19         fPair,
20 )
21
22 where
23
24 import BlockId
25 import Regs
26 import Cmm
27 import Outputable
28 import Constants        ( wORD_SIZE )
29 import FastString
30
31 import GHC.Exts
32
33
34 data Cond
35         = ALWAYS
36         | EQQ
37         | GE
38         | GEU
39         | GTT
40         | GU
41         | LE
42         | LEU
43         | LTT
44         | LU
45         | NE
46         | NEG
47         | NEVER
48         | POS
49         | VC
50         | VS
51         deriving Eq
52
53 -- -----------------------------------------------------------------------------
54 -- Machine's assembly language
55
56 -- We have a few common "instructions" (nearly all the pseudo-ops) but
57 -- mostly all of 'Instr' is machine-specific.
58
59 -- Register or immediate
60 data RI 
61         = RIReg Reg
62         | RIImm Imm
63
64 data Instr
65         -- comment pseudo-op
66         = COMMENT FastString            
67
68         -- some static data spat out during code
69         -- generation.  Will be extracted before
70         -- pretty-printing.
71         | LDATA   Section [CmmStatic]   
72
73         -- start a new basic block.  Useful during
74         -- codegen, removed later.  Preceding 
75         -- instruction should be a jump, as per the
76         -- invariants for a BasicBlock (see Cmm).
77         | NEWBLOCK BlockId              
78
79         -- specify current stack offset for
80         -- benefit of subsequent passes
81         | DELTA   Int
82
83         -- | spill this reg to a stack slot
84         | SPILL   Reg Int
85
86         -- | reload this reg from a stack slot
87         | RELOAD  Int Reg
88
89
90         -- Loads and stores.
91         | LD            Size AddrMode Reg               -- size, src, dst
92         | ST            Size Reg AddrMode               -- size, src, dst
93
94         -- Int Arithmetic.
95         | ADD           Bool Bool Reg RI Reg            -- x?, cc?, src1, src2, dst
96         | SUB           Bool Bool Reg RI Reg            -- x?, cc?, src1, src2, dst
97
98         | UMUL          Bool Reg RI Reg                 --     cc?, src1, src2, dst
99         | SMUL          Bool Reg RI Reg                 --     cc?, src1, src2, dst
100
101
102         -- The SPARC divide instructions perform 64bit by 32bit division
103         --   The Y register is xored into the first operand.
104
105         --   On _some implementations_ the Y register is overwritten by
106         --   the remainder, so we have to make sure it is 0 each time.
107
108         --   dst <- ((Y `shiftL` 32) `or` src1) `div` src2
109         | UDIV          Bool Reg RI Reg                 --     cc?, src1, src2, dst
110         | SDIV          Bool Reg RI Reg                 --     cc?, src1, src2, dst
111
112         | RDY           Reg                             -- move contents of Y register to reg
113         | WRY           Reg  Reg                        -- Y <- src1 `xor` src2
114         
115         -- Simple bit-twiddling.
116         | AND           Bool Reg RI Reg                 -- cc?, src1, src2, dst
117         | ANDN          Bool Reg RI Reg                 -- cc?, src1, src2, dst
118         | OR            Bool Reg RI Reg                 -- cc?, src1, src2, dst
119         | ORN           Bool Reg RI Reg                 -- cc?, src1, src2, dst
120         | XOR           Bool Reg RI Reg                 -- cc?, src1, src2, dst
121         | XNOR          Bool Reg RI Reg                 -- cc?, src1, src2, dst
122         | SLL           Reg RI Reg                      -- src1, src2, dst
123         | SRL           Reg RI Reg                      -- src1, src2, dst
124         | SRA           Reg RI Reg                      -- src1, src2, dst
125         | SETHI         Imm Reg                         -- src, dst
126         | NOP                                           -- Really SETHI 0, %g0, but worth an alias
127
128         -- Float Arithmetic.
129         -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single
130         -- instructions right up until we spit them out.
131         | FABS          Size Reg Reg                    -- src dst
132         | FADD          Size Reg Reg Reg                -- src1, src2, dst
133         | FCMP          Bool Size Reg Reg               -- exception?, src1, src2, dst
134         | FDIV          Size Reg Reg Reg                -- src1, src2, dst
135         | FMOV          Size Reg Reg                    -- src, dst
136         | FMUL          Size Reg Reg Reg                -- src1, src2, dst
137         | FNEG          Size Reg Reg                    -- src, dst
138         | FSQRT         Size Reg Reg                    -- src, dst
139         | FSUB          Size Reg Reg Reg                -- src1, src2, dst
140         | FxTOy         Size Size Reg Reg               -- src, dst
141
142         -- Jumping around.
143         | BI            Cond Bool BlockId               -- cond, annul?, target
144         | BF            Cond Bool BlockId               -- cond, annul?, target
145
146         | JMP           AddrMode                        -- target
147
148         -- With a tabled jump we know all the possible destinations. Tabled
149         -- jump includes its list of destinations so we can work out what regs
150         -- are live across the jump.
151         -- 
152         | JMP_TBL       AddrMode [BlockId]
153
154         | CALL          (Either Imm Reg) Int Bool       -- target, args, terminal
155
156
157 riZero :: RI -> Bool
158 riZero (RIImm (ImmInt 0))           = True
159 riZero (RIImm (ImmInteger 0))       = True
160 riZero (RIReg (RealReg 0))          = True
161 riZero _                            = False
162
163
164 -- | Calculate the effective address which would be used by the
165 --      corresponding fpRel sequence.  fpRel is in MachRegs.lhs,
166 --      alas -- can't have fpRelEA here because of module dependencies.
167 fpRelEA :: Int -> Reg -> Instr
168 fpRelEA n dst
169    = ADD False False fp (RIImm (ImmInt (n * wORD_SIZE))) dst
170
171
172 -- | Code to shift the stack pointer by n words.
173 moveSp :: Int -> Instr
174 moveSp n
175    = ADD False False sp (RIImm (ImmInt (n * wORD_SIZE))) sp
176
177
178 -- | Produce the second-half-of-a-double register given the first half.
179 fPair :: Reg -> Maybe Reg
180 fPair (RealReg n) 
181         | n >= 32 && n `mod` 2 == 0  = Just (RealReg (n+1))
182
183 fPair (VirtualRegD u)
184         = Just (VirtualRegHi u)
185
186 fPair other 
187         = trace ("MachInstrs.fPair: can't get high half of supposed double reg " ++ show other) 
188                 Nothing