Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/MLRISC/demo/demo-sparc.sml
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/demo/demo-sparc.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 713 - (view) (download)

1 : leunga 713 (*---------------------------------------------------------------------------
2 :     * Backend specific stuff. You'll need one instance of these things
3 :     * for each architecture.
4 :     *---------------------------------------------------------------------------*)
5 :    
6 :     (*
7 :     * The Sparc instruction set, specialized with respect to the
8 :     * user constant and region types.
9 :     *)
10 :     structure SparcInstr = SparcInstr
11 :     (structure LabelExp = LabelExp
12 :     structure Region = UserRegion
13 :     )
14 :    
15 :     (*
16 :     * How to serialize parallel copies
17 :     *)
18 :     structure SparcShuffle = SparcShuffle(SparcInstr)
19 :    
20 :     (*
21 :     * The assembler
22 :     *)
23 :     structure SparcAsm = SparcAsmEmitter
24 :     (structure Instr = SparcInstr
25 :     structure Stream = Stream
26 :     structure Shuffle = SparcShuffle
27 :     val V9 = false (* we'll generate V8 instructions for now *)
28 :     )
29 :    
30 :     (*
31 :     * The flowgraph (cluster) representation specialized to the sparc instruction
32 :     * set.
33 :     *)
34 :     structure SparcFlowGraph =
35 :     FlowGraph(structure I = SparcInstr
36 :     structure P = UserPseudoOps
37 :     )
38 :     (*
39 :     * Because of various Sparc related ugliness. Pseudo instructions
40 :     * related to integer multiplication/division are handled via callbacks.
41 :     * Here we can decide what actual code to generate. Here we only
42 :     * handle a subset of of the pseudo instructions.
43 :     *)
44 :     structure SparcPseudoInstrs =
45 :     struct
46 :     structure I = SparcInstr
47 :     structure C = SparcInstr.C
48 :    
49 :     type format1 =
50 :     {r:int, i:I.operand, d:int} *
51 :     (I.operand -> I.C.cell) -> I.instruction list
52 :    
53 :     type format2 =
54 :     {i:I.operand, d:int} *
55 :     (I.operand -> I.C.cell) -> I.instruction list
56 :    
57 :     fun error msg = MLRiscErrorMsg.impossible ("SparcPseudoInstrs."^msg)
58 :    
59 :     fun umul32({r, i, d}, reduceOpnd) = [I.ARITH{a=I.UMUL,r=r,i=i,d=d}]
60 :     fun smul32({r, i, d}, reduceOpnd) = [I.ARITH{a=I.SMUL,r=r,i=i,d=d}]
61 :     fun udiv32({r,i,d},reduceOpnd) =
62 :     [I.WRY{r=0,i=I.REG 0},I.ARITH{a=I.UDIV,r=r,i=i,d=d}]
63 :    
64 :     fun sdiv32({r,i,d},reduceOpnd) =
65 :     let val t1 = C.newReg()
66 :     in [I.SHIFT{s=I.SRA,r=r,i=I.IMMED 31,d=t1},
67 :     I.WRY{r=t1,i=I.REG 0},
68 :     I.ARITH{a=I.SDIV,r=r,i=i,d=d}
69 :     ]
70 :     end
71 :    
72 :     fun cvti2d({i,d},reduceOpnd) = error "cvti2d"
73 :     (* There is no data path between integer and floating point registers.
74 :     So we actually have to use some memory location for temporary
75 :     This is commented out for now.
76 :     *)
77 :     (*
78 :     [I.STORE{s=I.ST,r=C.stackptrR,i=floatTmpOffset,d=reduceOpnd i,mem=stack},
79 :     I.FLOAD{l=I.LDF,r=C.stackptrR,i=floatTmpOffset,d=d,mem=stack},
80 :     I.FPop1{a=I.FiTOd,r=d,d=d}
81 :     ]
82 :     *)
83 :     fun cvti2s _ = error "cvti2s"
84 :     fun cvti2q _ = error "cvti2q"
85 :    
86 :     fun smul32trap _ = error "smul32trap"
87 :     fun sdiv32trap _ = error "sdiv32trap"
88 :    
89 :     val overflowtrap32 = [] (* not needed *)
90 :     val overflowtrap64 = [] (* not needed *)
91 :     end
92 :    
93 :    
94 :     (*
95 :     * Instruction selection module for Sparc.
96 :     *)
97 :     structure SparcMLTreeComp =
98 :     Sparc(structure SparcInstr = SparcInstr
99 :     structure SparcMLTree = MLTree
100 :     structure PseudoInstrs = SparcPseudoInstrs
101 :     structure ExtensionComp = UserMLTreeExtComp
102 :     (structure I = SparcInstr
103 :     structure T = SparcMLTree
104 :     )
105 :     (* Some sparc specific parameters *)
106 :     val V9 = false
107 :     val muluCost = ref 5
108 :     val multCost = ref 3
109 :     val divuCost = ref 5
110 :     val divtCost = ref 5
111 :     val registerwindow = ref false
112 :     val useBR = ref false
113 :     )
114 :    
115 :    
116 :     (*---------------------------------------------------------------------------
117 :     * Okay. Finally, we can tie the front-end and back-end together.
118 :     *---------------------------------------------------------------------------*)
119 :     structure SparcBackEnd =
120 :     BackEnd
121 :     (structure I = SparcInstr
122 :     structure Flowgraph = SparcFlowGraph
123 :     structure InsnProps = SparcProps(SparcInstr)
124 :     structure Rewrite = SparcRewrite(SparcInstr)
125 :     structure Asm = SparcAsm
126 :     structure MLTreeComp = SparcMLTreeComp
127 :    
128 :     val sp = I.C.stackptrR
129 :     val spill = UserRegion.spill
130 :    
131 :     (* I'm assuming only r0 and the stack pointer is dedicated *)
132 :     fun range(from,to,step) = if from > to then []
133 :     else from::range(from+step,to,step)
134 :     val dedicatedRegs = [I.C.stackptrR, I.C.GPReg 0]
135 :     val dedicatedFRegs = []
136 :     val availRegs = SortedList.difference(
137 :     range(I.C.GPReg 0, I.C.GPReg 31, 1),
138 :     SortedList.uniq dedicatedRegs)
139 :     val availFRegs = range(I.C.FPReg 0, I.C.FPReg 31, 2)
140 :    
141 :     val initialSpillOffset = 0 (* This is probably wrong!!!!! *)
142 :     val spillAreaSize = 4000
143 :    
144 :     fun pure(I.ANNOTATION{i,...}) = pure i
145 :     | pure(I.LOAD _) = true
146 :     | pure(I.FLOAD _) = true
147 :     | pure(I.SETHI _) = true
148 :     | pure(I.SHIFT _) = true
149 :     | pure(I.FPop1 _) = true
150 :     | pure(I.FPop2 _) = true
151 :     | pure _ = false
152 :    
153 :     (* make copy *)
154 :     fun copyR((rds as [_], rss as [_]), _) =
155 :     I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=NONE}
156 :     | copyR((rds, rss), I.COPY{tmp, ...}) =
157 :     I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=tmp}
158 :     fun copyF((fds as [_], fss as [_]), _) =
159 :     I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=NONE}
160 :     | copyF((fds, fss), I.FCOPY{tmp, ...}) =
161 :     I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=tmp}
162 :    
163 :     (* spill copy temp *)
164 :     fun spillCopyTmp(I.COPY{dst,src,tmp,impl},offset) =
165 :     I.COPY{dst=dst, src=src, impl=impl,
166 :     tmp=SOME(I.Displace{base=sp, disp=offset})}
167 :     fun spillFcopyTmp(I.FCOPY{dst,src,tmp,impl},offset) =
168 :     I.FCOPY{dst=dst, src=src, impl=impl,
169 :     tmp=SOME(I.Displace{base=sp, disp=offset})}
170 :    
171 :     (* spill register *)
172 :     fun spillInstrR(d,offset) =
173 :     [I.STORE{s=I.ST, r=sp, i=I.IMMED offset, d=d, mem=spill}]
174 :     fun spillInstrF(d,offset) =
175 :     [I.FSTORE{s=I.STDF, r=sp, i=I.IMMED offset, d=d, mem=spill}]
176 :    
177 :     (* reload register *)
178 :     fun reloadInstrR(d,offset,rest) =
179 :     I.LOAD{l=I.LD, r=sp, i=I.IMMED offset, d=d, mem=spill}::rest
180 :     fun reloadInstrF(d,offset,rest) =
181 :     I.FLOAD{l=I.LDDF, r=sp, i=I.IMMED offset, d=d, mem=spill}::rest
182 :     )

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0