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/x86/x86.md
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/x86/x86.md

Parent Directory Parent Directory | Revision Log Revision Log


Revision 429 - (view) (download)
Original Path: sml/branches/SMLNJ/src/MLRISC/x86/x86.md

1 : monnier 409 (*
2 :     * 32bit, x86 instruction set.
3 :     *)
4 :     architecture X86 =
5 :     struct
6 :    
7 :     name "X86"
8 :    
9 :     superscalar
10 :    
11 :     little endian (* is this right??? *)
12 :    
13 :     lowercase assembly
14 :    
15 :     (*
16 :     * Assembly note:
17 :     * Note: we are using the AT&T syntax (for Linux) and not the intel syntax
18 :     * memory operands have the form:
19 :     * section:disp(base, index, scale)
20 :     * Most of the complication is actually in emiting the correct
21 :     * operand syntax.
22 :     *)
23 :    
24 :     (* Note: While the x86 has only 8 integer and 8 floating point registers,
25 :     * the SMLNJ compiler fakes it by assuming that it has 32 integer
26 :     * and 32 floating point registers. That's why we
27 :     *)
28 :    
29 :     storage
30 :     GP = 32 cells of 32 bits in cellset called "register"
31 :     assembly as
32 :     (fn 0 => "%eax"
33 :     | 1 => "%ecx"
34 :     | 2 => "%edx"
35 :     | 3 => "%ebx"
36 :     | 4 => "%esp"
37 :     | 5 => "%ebp"
38 :     | 6 => "%esi"
39 :     | 7 => "%edi"
40 :     | r => "%"^Int.toString r
41 :     )
42 :     | FP = 32 cells of 80 bits in cellset called "floating point register"
43 :     assembly as (fn f => if f >= 0 andalso f < 8
44 :     then "%st("^Int.toString f^")"
45 :     else "%f"^Int.toString f (* fake register *)
46 :     )
47 :     | CC = cells of 32 bits in cellset called "condition code register"
48 :     assembly as "cc"
49 :     locations
50 :     eax = $GP[0]
51 :     and ecx = $GP[1]
52 :     and edx = $GP[2]
53 :     and ebx = $GP[3]
54 :     and esp = $GP[4]
55 :     and ebp = $GP[5]
56 :     and esi = $GP[6]
57 :     and edi = $GP[7]
58 : monnier 429 and stackptrR = $GP[4]
59 : monnier 409 and asmTmpR = ~1 (* not used *)
60 :     and fasmTmp = ~1 (* not used *)
61 :    
62 :     structure Cells =
63 :     struct
64 :     fun zeroReg _ = NONE
65 :     end
66 :    
67 :    
68 :     (*
69 :     semantics X86 =
70 :     struct
71 :     include "MD++/basis.md"
72 :     open Basis
73 :     structure Int32 = struct type int end
74 :     type 'a option
75 :     end *)
76 :    
77 :     structure Instruction = struct
78 :     (* An effective address can be any combination of
79 :     * base + index*scale + disp
80 :     * or
81 :     * B + I*SCALE + DISP
82 :     *
83 :     * where any component is optional. The operand datatype captures
84 :     * all these combinations.
85 :     *
86 :     * DISP == Immed | ImmedLabel | Const
87 :     * B == Displace{base=B, disp=0}
88 :     * B+DISP == Displace{base=B, disp=DISP}
89 :     * I*SCALE+DISP == Indexed{base=NONE, index=I, scale=SCALE, disp=D}
90 :     * B+I*SCALE+DISP == Indexed{base=SOME B, index=I, scale=SCALE, disp=DISP}
91 :     *
92 :     * Note1: The index register cannot be EBP.
93 :     * The disp field must be one of Immed, ImmedLabel, or Const.
94 :     *)
95 :    
96 :     (* Note: Relative is only generated after sdi resolution *)
97 :     datatype operand =
98 :     Immed of Int32.int
99 :     | Const of Constant.const
100 :     | ImmedLabel of LabelExp.labexp
101 :     | Relative of int
102 :     | LabelEA of LabelExp.labexp
103 :     | Direct of $GP
104 :     | FDirect of $FP
105 :     | Displace of {base: $GP, disp:operand, mem:Region.region}
106 :     | Indexed of {base: $GP option, index: $GP, scale:int, disp:operand,
107 :     mem:Region.region}
108 :    
109 :     type ea = operand
110 :    
111 :     datatype binaryOp! = ADD | SUB | AND | OR | XOR | SHL | SAR | SHR
112 :    
113 :     datatype multDivOp! = UMUL | IDIV | UDIV
114 :    
115 :     datatype unaryOp! = DEC | INC | NEG | NOT
116 :    
117 :     datatype move! = MOVL | MOVZX | MOVB
118 :    
119 :     datatype cond! =
120 :     EQ | NE | LT | LE | GT | GE
121 :     | B | BE (* below *) | A | AE (* above *)
122 :     | C | NC (* if carry *)| P | NP (* if parity *)
123 :     | O | NO (* overflow *)
124 :    
125 :     (* The Intel manual is incorrect on the description of FDIV and FDIVR *)
126 :     datatype fbinOp! =
127 :     FADDP | FADD
128 :     | FMULP | FMUL
129 :     | FSUBP | FSUB (* ST(1) := ST-ST(1); [pop] *)
130 :     | FSUBRP | FSUBR (* ST(1) := ST(1)-ST; [pop] *)
131 :     | FDIVP | FDIV (* ST(1) := ST/ST(1); [pop] *)
132 :     | FDIVRP | FDIVR (* ST(1) := ST(1)/ST; [pop] *)
133 :    
134 :     datatype funOp! = FABS | FCHS
135 :    
136 :     end (* struct Instruction *)
137 :    
138 :     (* A bunch of routines for emitting assembly *)
139 :     functor Assembly
140 :     (structure MemRegs : MEMORY_REGISTERS where I = Instr) =
141 :     struct
142 :     val memReg = MemRegs.memReg regmap
143 : monnier 429 fun emitInt32 i =
144 :     let val s = Int32.toString i
145 :     val s = if i >= 0 then s else "-"^String.substring(s,1,size s-1)
146 :     in emit s end
147 :    
148 : monnier 409 fun emit_src2 NONE = ()
149 :     | emit_src2(SOME i) = (emit "$"; emitInt32 i; emit ", ")
150 :    
151 :     fun emitScale 0 = emit "1"
152 :     | emitScale 1 = emit "2"
153 :     | emitScale 2 = emit "4"
154 :     | emitScale 3 = emit "8"
155 :     | emitScale _ = error "emitScale"
156 :    
157 :     and eImmed(I.Immed (i)) = emitInt32 i
158 :     | eImmed(I.Const c) = emit_const c
159 :     | eImmed(I.ImmedLabel lexp) = emit_labexp lexp
160 :     | eImmed _ = error "eImmed"
161 :    
162 :     and emit_operand opn =
163 :     case opn of
164 :     I.Immed i => (emit "$"; emitInt32 i)
165 :     | I.Const c => emit_const c
166 :     | I.ImmedLabel lexp => (emit "$"; emit_labexp lexp)
167 :     | I.LabelEA le => emit_labexp le
168 :     | I.Relative _ => error "emit_operand"
169 :     | I.Direct r => emit_GP r
170 :     | I.FDirect f =>
171 :     let val f' = regmap f
172 :     in if f' < (32+8) then emit_FP f' else emit_operand(memReg opn) end
173 :     | I.Displace{base,disp=I.Immed(0),mem,...} =>
174 :     (emit "("; emit_GP base; emit ")"; emit_region mem)
175 :     | I.Displace{base,disp,mem,...} =>
176 :     (eImmed disp; emit "("; emit_GP base; emit ")";
177 :     emit_region mem)
178 :     | I.Indexed{base=NONE,index,scale,disp,mem,...} =>
179 :     (emit "("; emit_GP index; comma(); emitScale scale; emit ")";
180 :     emit_region mem)
181 :     | I.Indexed{base=SOME base,index,scale,disp,mem,...} =>
182 :     (eOptionalDisp disp; emit "("; emit_GP base;
183 : monnier 429 comma(); emit_GP index; comma(); emitScale scale; emit ")";
184 : monnier 409 emit_region mem)
185 :     and eOptionalDisp(I.Immed 0) = ()
186 :     | eOptionalDisp(I.Const c) = emit(Constant.toString c)
187 :     | eOptionalDisp(I.Immed i) = emitInt32 i
188 :     | eOptionalDisp _ = error "eOptionalDisp"
189 :    
190 :     (* The gas assembler does not like the "$" prefix for immediate
191 :     * labels in certain instructions.
192 :     *)
193 :     fun stupidGas(I.ImmedLabel lexp) = emit_labexp lexp
194 :     | stupidGas(I.LabelEA _) = error "stupidGas"
195 :     | stupidGas opnd = emit_operand opnd
196 :    
197 :     val emit_dst = emit_operand
198 :     val emit_src = emit_operand
199 :     val emit_opnd = emit_operand
200 :     val emit_src1 = emit_operand
201 :     val emit_rsrc = emit_operand
202 :     val emit_lsrc = emit_operand
203 :     val emit_addr = emit_operand
204 :     end
205 :    
206 :     (* many of these instructions imply certain register usages *)
207 :     instruction
208 :     NOP
209 :     ``nop''
210 :    
211 :     | JMP of operand * Label.label list
212 :     ``jmp\t<stupidGas operand>''
213 :    
214 :     | JCC of {cond:cond, opnd:operand}
215 :     ``j<cond>, <stupidGas opnd>''
216 :    
217 :     | CALL of operand * C.cellset * C.cellset * Region.region
218 :     ``call\t<stupidGas operand><region>''
219 :    
220 : monnier 429 | RET of operand option
221 :     ``ret<case operand of NONE => ()
222 :     | SOME e => (emit "\t"; emit_operand e)>''
223 : monnier 409
224 :     (* integer *)
225 :     | MOVE of {mvOp:move, src:operand, dst:operand}
226 :     ``<mvOp>\t<src>, <dst>''
227 :    
228 :     | LEA of {r32: $GP, addr: operand}
229 :     ``leal\t<addr>, <r32>''
230 :    
231 :     | CMP of {lsrc: operand, rsrc: operand}
232 :     ``cmpl\t<rsrc>, <lsrc>''
233 :    
234 :     | BINARY of {binOp:binaryOp, src:operand, dst:operand}
235 :     ``<binOp>l\t<src>, <dst>''
236 :    
237 :     | MULTDIV of {multDivOp:multDivOp, src:operand}
238 :     ``<multDivOp>l\t<src>''
239 :    
240 :     | MUL3 of {dst:int, src1:operand, src2: Int32.int option}
241 :     ``imul\t<src1>, <emit_src2 src2><dst>''
242 :    
243 :     | UNARY of {unOp:unaryOp, opnd:operand}
244 :     ``<unOp>l\t<opnd>''
245 :    
246 :     | PUSH of operand
247 :     ``pushl\t<operand>''
248 :    
249 :     | POP of operand
250 :     ``popl\t<operand>''
251 :    
252 :     | CDQ
253 :     ``cdq''
254 :    
255 :     | INTO
256 :     ``into''
257 :    
258 :     (* parallel copies *)
259 :     | COPY of {dst: $GP list, src: $GP list, tmp:operand option}
260 :     ``<emitInstrs (Shuffle.shuffle{regmap,tmp,dst,src})>''
261 :     | FCOPY of {dst: $FP list, src: $FP list, tmp:operand option}
262 :     ``<emitInstrs (Shuffle.shufflefp{regmap,tmp,dst,src})>''
263 :    
264 :    
265 :     (* floating *)
266 :     | FBINARY of {binOp:fbinOp, src:operand, dst:operand}
267 :     ``<binOp>\t<src>, <dst>''
268 :    
269 :     | FUNARY of funOp
270 :     ``<funOp>''
271 :    
272 :     | FUCOMPP
273 :     ``fucompp''
274 :    
275 :     | FXCH
276 :     ``fxch''
277 :    
278 :     | FSTP of operand
279 :     ``fstp\t<operand>''
280 :    
281 :     | FLD of operand
282 :     ``fld\t<operand>''
283 :    
284 :     | FILD of operand
285 :     ``fild\t<operand>''
286 :    
287 :     | FNSTSW
288 :     ``fnstsw''
289 :    
290 :     (* misc *)
291 :     | SAHF
292 :     ``sahf''
293 :    
294 :     (* annotations *)
295 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
296 :     ``<(emitInstr i; comment(Annotations.toString a))>''
297 :    
298 :     | GROUP of Annotations.annotation
299 :     ``<comment(Annotations.toString annotation)>''
300 :    
301 :     end
302 :    

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