1 -----------------------------------------------------------------------------
3 -- Machine-dependent assembly language
5 -- (c) The University of Glasgow 1993-2004
7 -----------------------------------------------------------------------------
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
29 import Constants ( wORD_SIZE )
54 -- -----------------------------------------------------------------------------
55 -- Machine's assembly language
57 -- We have a few common "instructions" (nearly all the pseudo-ops) but
58 -- mostly all of 'Instr' is machine-specific.
60 -- Register or immediate
69 -- some static data spat out during code
70 -- generation. Will be extracted before
72 | LDATA Section [CmmStatic]
74 -- start a new basic block. Useful during
75 -- codegen, removed later. Preceding
76 -- instruction should be a jump, as per the
77 -- invariants for a BasicBlock (see Cmm).
80 -- specify current stack offset for
81 -- benefit of subsequent passes
84 -- | spill this reg to a stack slot
87 -- | reload this reg from a stack slot
92 | LD Size AddrMode Reg -- size, src, dst
93 | ST Size Reg AddrMode -- size, src, dst
96 | ADD Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
97 | SUB Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
99 | UMUL Bool Reg RI Reg -- cc?, src1, src2, dst
100 | SMUL Bool Reg RI Reg -- cc?, src1, src2, dst
103 -- The SPARC divide instructions perform 64bit by 32bit division
104 -- The Y register is xored into the first operand.
106 -- On _some implementations_ the Y register is overwritten by
107 -- the remainder, so we have to make sure it is 0 each time.
109 -- dst <- ((Y `shiftL` 32) `or` src1) `div` src2
110 | UDIV Bool Reg RI Reg -- cc?, src1, src2, dst
111 | SDIV Bool Reg RI Reg -- cc?, src1, src2, dst
113 | RDY Reg -- move contents of Y register to reg
114 | WRY Reg Reg -- Y <- src1 `xor` src2
116 -- Simple bit-twiddling.
117 | AND Bool Reg RI Reg -- cc?, src1, src2, dst
118 | ANDN Bool Reg RI Reg -- cc?, src1, src2, dst
119 | OR Bool Reg RI Reg -- cc?, src1, src2, dst
120 | ORN Bool Reg RI Reg -- cc?, src1, src2, dst
121 | XOR Bool Reg RI Reg -- cc?, src1, src2, dst
122 | XNOR Bool Reg RI Reg -- cc?, src1, src2, dst
123 | SLL Reg RI Reg -- src1, src2, dst
124 | SRL Reg RI Reg -- src1, src2, dst
125 | SRA Reg RI Reg -- src1, src2, dst
126 | SETHI Imm Reg -- src, dst
127 | NOP -- Really SETHI 0, %g0, but worth an alias
130 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single
131 -- instructions right up until we spit them out.
132 | FABS Size Reg Reg -- src dst
133 | FADD Size Reg Reg Reg -- src1, src2, dst
134 | FCMP Bool Size Reg Reg -- exception?, src1, src2, dst
135 | FDIV Size Reg Reg Reg -- src1, src2, dst
136 | FMOV Size Reg Reg -- src, dst
137 | FMUL Size Reg Reg Reg -- src1, src2, dst
138 | FNEG Size Reg Reg -- src, dst
139 | FSQRT Size Reg Reg -- src, dst
140 | FSUB Size Reg Reg Reg -- src1, src2, dst
141 | FxTOy Size Size Reg Reg -- src, dst
144 | BI Cond Bool BlockId -- cond, annul?, target
145 | BF Cond Bool BlockId -- cond, annul?, target
147 | JMP AddrMode -- target
149 -- With a tabled jump we know all the possible destinations. Tabled
150 -- jump includes its list of destinations so we can work out what regs
151 -- are live across the jump.
153 | JMP_TBL AddrMode [BlockId]
155 | CALL (Either Imm Reg) Int Bool -- target, args, terminal
159 riZero (RIImm (ImmInt 0)) = True
160 riZero (RIImm (ImmInteger 0)) = True
161 riZero (RIReg (RealReg 0)) = True
165 -- | Calculate the effective address which would be used by the
166 -- corresponding fpRel sequence. fpRel is in MachRegs.lhs,
167 -- alas -- can't have fpRelEA here because of module dependencies.
168 fpRelEA :: Int -> Reg -> Instr
170 = ADD False False fp (RIImm (ImmInt (n * wORD_SIZE))) dst
173 -- | Code to shift the stack pointer by n words.
174 moveSp :: Int -> Instr
176 = ADD False False sp (RIImm (ImmInt (n * wORD_SIZE))) sp
179 -- | Produce the second-half-of-a-double register given the first half.
180 fPair :: Reg -> Maybe Reg
182 | n >= 32 && n `mod` 2 == 0 = Just (RealReg (n+1))
184 fPair (VirtualRegD u)
185 = Just (VirtualRegHi u)
188 = trace ("MachInstrs.fPair: can't get high half of supposed double reg ")