1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
module SPARC.CodeGen.Base (
InstrBlock,
CondCode(..),
ChildCode64(..),
Amode(..),
Register(..),
setSizeOfRegister,
getRegisterReg,
mangleIndexTree
)
where
import SPARC.Instr
import SPARC.Cond
import SPARC.AddrMode
import SPARC.Regs
import SPARC.RegPlate
import Size
import Reg
import OldCmm
import OldPprCmm ()
import Outputable
import OrdList
--------------------------------------------------------------------------------
-- | 'InstrBlock's are the insn sequences generated by the insn selectors.
-- They are really trees of insns to facilitate fast appending, where a
-- left-to-right traversal yields the insns in the correct order.
--
type InstrBlock
= OrdList Instr
-- | Condition codes passed up the tree.
--
data CondCode
= CondCode Bool Cond InstrBlock
-- | a.k.a "Register64"
-- Reg is the lower 32-bit temporary which contains the result.
-- Use getHiVRegFromLo to find the other VRegUnique.
--
-- Rules of this simplified insn selection game are therefore that
-- the returned Reg may be modified
--
data ChildCode64
= ChildCode64
InstrBlock
Reg
-- | Holds code that references a memory address.
data Amode
= Amode
-- the AddrMode we can use in the instruction
-- that does the real load\/store.
AddrMode
-- other setup code we have to run first before we can use the
-- above AddrMode.
InstrBlock
--------------------------------------------------------------------------------
-- | Code to produce a result into a register.
-- If the result must go in a specific register, it comes out as Fixed.
-- Otherwise, the parent can decide which register to put it in.
--
data Register
= Fixed Size Reg InstrBlock
| Any Size (Reg -> InstrBlock)
-- | Change the size field in a Register.
setSizeOfRegister
:: Register -> Size -> Register
setSizeOfRegister reg size
= case reg of
Fixed _ reg code -> Fixed size reg code
Any _ codefn -> Any size codefn
--------------------------------------------------------------------------------
-- | Grab the Reg for a CmmReg
getRegisterReg :: CmmReg -> Reg
getRegisterReg (CmmLocal (LocalReg u pk))
= RegVirtual $ mkVirtualReg u (cmmTypeSize pk)
getRegisterReg (CmmGlobal mid)
= case globalRegMaybe mid of
Just reg -> RegReal reg
Nothing -> pprPanic
"SPARC.CodeGen.Base.getRegisterReg: global is in memory"
(ppr $ CmmGlobal mid)
-- Expand CmmRegOff. ToDo: should we do it this way around, or convert
-- CmmExprs into CmmRegOff?
mangleIndexTree :: CmmExpr -> CmmExpr
mangleIndexTree (CmmRegOff reg off)
= CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)]
where width = typeWidth (cmmRegType reg)
mangleIndexTree _
= panic "SPARC.CodeGen.Base.mangleIndexTree: no match"
|