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 410 - (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 :     and stackptrR = esp
59 :     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 :     fun emitInt32 i = emit(if i < 0 then "-"^Int32.toString(~i)
144 :     else Int32.toString i)
145 :     fun emit_src2 NONE = ()
146 :     | emit_src2(SOME i) = (emit "$"; emitInt32 i; emit ", ")
147 :    
148 :     fun emitScale 0 = emit "1"
149 :     | emitScale 1 = emit "2"
150 :     | emitScale 2 = emit "4"
151 :     | emitScale 3 = emit "8"
152 :     | emitScale _ = error "emitScale"
153 :    
154 :     and eImmed(I.Immed (i)) = emitInt32 i
155 :     | eImmed(I.Const c) = emit_const c
156 :     | eImmed(I.ImmedLabel lexp) = emit_labexp lexp
157 :     | eImmed _ = error "eImmed"
158 :    
159 :     and emit_operand opn =
160 :     case opn of
161 :     I.Immed i => (emit "$"; emitInt32 i)
162 :     | I.Const c => emit_const c
163 :     | I.ImmedLabel lexp => (emit "$"; emit_labexp lexp)
164 :     | I.LabelEA le => emit_labexp le
165 :     | I.Relative _ => error "emit_operand"
166 :     | I.Direct r => emit_GP r
167 :     | I.FDirect f =>
168 :     let val f' = regmap f
169 :     in if f' < (32+8) then emit_FP f' else emit_operand(memReg opn) end
170 :     | I.Displace{base,disp=I.Immed(0),mem,...} =>
171 :     (emit "("; emit_GP base; emit ")"; emit_region mem)
172 :     | I.Displace{base,disp,mem,...} =>
173 :     (eImmed disp; emit "("; emit_GP base; emit ")";
174 :     emit_region mem)
175 :     | I.Indexed{base=NONE,index,scale,disp,mem,...} =>
176 :     (emit "("; emit_GP index; comma(); emitScale scale; emit ")";
177 :     emit_region mem)
178 :     | I.Indexed{base=SOME base,index,scale,disp,mem,...} =>
179 :     (eOptionalDisp disp; emit "("; emit_GP base;
180 :     comma(); emit_GP index; emitScale scale; emit ")";
181 :     emit_region mem)
182 :     and eOptionalDisp(I.Immed 0) = ()
183 :     | eOptionalDisp(I.Const c) = emit(Constant.toString c)
184 :     | eOptionalDisp(I.Immed i) = emitInt32 i
185 :     | eOptionalDisp _ = error "eOptionalDisp"
186 :    
187 :     (* The gas assembler does not like the "$" prefix for immediate
188 :     * labels in certain instructions.
189 :     *)
190 :     fun stupidGas(I.ImmedLabel lexp) = emit_labexp lexp
191 :     | stupidGas(I.LabelEA _) = error "stupidGas"
192 :     | stupidGas opnd = emit_operand opnd
193 :    
194 :     val emit_dst = emit_operand
195 :     val emit_src = emit_operand
196 :     val emit_opnd = emit_operand
197 :     val emit_src1 = emit_operand
198 :     val emit_rsrc = emit_operand
199 :     val emit_lsrc = emit_operand
200 :     val emit_addr = emit_operand
201 :     end
202 :    
203 :     (* many of these instructions imply certain register usages *)
204 :     instruction
205 :     NOP
206 :     ``nop''
207 :    
208 :     | JMP of operand * Label.label list
209 :     ``jmp\t<stupidGas operand>''
210 :    
211 :     | JCC of {cond:cond, opnd:operand}
212 :     ``j<cond>, <stupidGas opnd>''
213 :    
214 :     | CALL of operand * C.cellset * C.cellset * Region.region
215 :     ``call\t<stupidGas operand><region>''
216 :    
217 :     | RET
218 :     ``ret''
219 :    
220 :     (* integer *)
221 :     | MOVE of {mvOp:move, src:operand, dst:operand}
222 :     ``<mvOp>\t<src>, <dst>''
223 :    
224 :     | LEA of {r32: $GP, addr: operand}
225 :     ``leal\t<addr>, <r32>''
226 :    
227 :     | CMP of {lsrc: operand, rsrc: operand}
228 :     ``cmpl\t<rsrc>, <lsrc>''
229 :    
230 :     | BINARY of {binOp:binaryOp, src:operand, dst:operand}
231 :     ``<binOp>l\t<src>, <dst>''
232 :    
233 :     | MULTDIV of {multDivOp:multDivOp, src:operand}
234 :     ``<multDivOp>l\t<src>''
235 :    
236 :     | MUL3 of {dst:int, src1:operand, src2: Int32.int option}
237 :     ``imul\t<src1>, <emit_src2 src2><dst>''
238 :    
239 :     | UNARY of {unOp:unaryOp, opnd:operand}
240 :     ``<unOp>l\t<opnd>''
241 :    
242 :     | PUSH of operand
243 :     ``pushl\t<operand>''
244 :    
245 :     | POP of operand
246 :     ``popl\t<operand>''
247 :    
248 :     | CDQ
249 :     ``cdq''
250 :    
251 :     | INTO
252 :     ``into''
253 :    
254 :     (* parallel copies *)
255 :     | COPY of {dst: $GP list, src: $GP list, tmp:operand option}
256 :     ``<emitInstrs (Shuffle.shuffle{regmap,tmp,dst,src})>''
257 :     | FCOPY of {dst: $FP list, src: $FP list, tmp:operand option}
258 :     ``<emitInstrs (Shuffle.shufflefp{regmap,tmp,dst,src})>''
259 :    
260 :    
261 :     (* floating *)
262 :     | FBINARY of {binOp:fbinOp, src:operand, dst:operand}
263 :     ``<binOp>\t<src>, <dst>''
264 :    
265 :     | FUNARY of funOp
266 :     ``<funOp>''
267 :    
268 :     | FUCOMPP
269 :     ``fucompp''
270 :    
271 :     | FXCH
272 :     ``fxch''
273 :    
274 :     | FSTP of operand
275 :     ``fstp\t<operand>''
276 :    
277 :     | FLD of operand
278 :     ``fld\t<operand>''
279 :    
280 :     | FILD of operand
281 :     ``fild\t<operand>''
282 :    
283 :     | FNSTSW
284 :     ``fnstsw''
285 :    
286 :     (* misc *)
287 :     | SAHF
288 :     ``sahf''
289 :    
290 :     (* annotations *)
291 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
292 :     ``<(emitInstr i; comment(Annotations.toString a))>''
293 :    
294 :     | GROUP of Annotations.annotation
295 :     ``<comment(Annotations.toString annotation)>''
296 :    
297 :     end
298 :    

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