1 -----------------------------------------------------------------------------
3 -- Machine-dependent assembly language
5 -- (c) The University of Glasgow 1993-2004
7 -----------------------------------------------------------------------------
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
28 import Constants ( wORD_SIZE )
53 -- -----------------------------------------------------------------------------
54 -- Machine's assembly language
56 -- We have a few common "instructions" (nearly all the pseudo-ops) but
57 -- mostly all of 'Instr' is machine-specific.
59 -- Register or immediate
68 -- some static data spat out during code
69 -- generation. Will be extracted before
71 | LDATA Section [CmmStatic]
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).
79 -- specify current stack offset for
80 -- benefit of subsequent passes
83 -- | spill this reg to a stack slot
86 -- | reload this reg from a stack slot
91 | LD Size AddrMode Reg -- size, src, dst
92 | ST Size Reg AddrMode -- size, src, dst
95 | ADD Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
96 | SUB Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
98 | UMUL Bool Reg RI Reg -- cc?, src1, src2, dst
99 | SMUL Bool Reg RI Reg -- cc?, src1, src2, dst
102 -- The SPARC divide instructions perform 64bit by 32bit division
103 -- The Y register is xored into the first operand.
105 -- On _some implementations_ the Y register is overwritten by
106 -- the remainder, so we have to make sure it is 0 each time.
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
112 | RDY Reg -- move contents of Y register to reg
113 | WRY Reg Reg -- Y <- src1 `xor` src2
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
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
143 | BI Cond Bool BlockId -- cond, annul?, target
144 | BF Cond Bool BlockId -- cond, annul?, target
146 | JMP AddrMode -- target
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.
152 | JMP_TBL AddrMode [BlockId]
154 | CALL (Either Imm Reg) Int Bool -- target, args, terminal
158 riZero (RIImm (ImmInt 0)) = True
159 riZero (RIImm (ImmInteger 0)) = True
160 riZero (RIReg (RealReg 0)) = True
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
169 = ADD False False fp (RIImm (ImmInt (n * wORD_SIZE))) dst
172 -- | Code to shift the stack pointer by n words.
173 moveSp :: Int -> Instr
175 = ADD False False sp (RIImm (ImmInt (n * wORD_SIZE))) sp
178 -- | Produce the second-half-of-a-double register given the first half.
179 fPair :: Reg -> Maybe Reg
181 | n >= 32 && n `mod` 2 == 0 = Just (RealReg (n+1))
183 fPair (VirtualRegD u)
184 = Just (VirtualRegHi u)
187 = trace ("MachInstrs.fPair: can't get high half of supposed double reg " ++ show other)