2 Defines the architecture (regs and insts) for X86
3 Copyright (C) 2001 Justin David Smith, Caltech
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 (*** Instruction type file ***)
27 (*** Declare ML type names ***)
33 (*** Register set and context ***)
37 (* Integer registers *)
51 (* Context variables *)
62 (* Special program labels *)
64 lbl migrate_fun_label;
66 (* Instruction listbufs for use with kupo *)
73 int31 callee_header_stack;
86 $size_pred_aggr_mask32;
87 $size_pred_block_mask32;
95 $arity_tag_pred_mask32;
98 (*** Instruction set ***)
101 (* Trivial operators *)
102 instructions trivial_inst:
103 nop -> NOP : pairu pairv;
106 (* Basic memory operations *)
107 instructions pairu pairv:
108 mov pre, dst, src -> MOV (pre, dst, src);
109 movb dst, src -> MOV (IB, dst, src);
110 movw dst, src -> MOV (IW, dst, src);
111 movl dst, src -> MOV (IL, dst, src);
112 movz pre, dst, src -> MOVZ (pre, dst, src);
113 movzb dst, src -> MOVZ (IB, dst, src);
114 movzw dst, src -> MOVZ (IW, dst, src);
115 movs pre, dst, src -> MOVS (pre, dst, src);
116 movsb dst, src -> MOVS (IB, dst, src);
117 movsw dst, src -> MOVS (IW, dst, src);
118 lea pre, dst, src -> LEA (pre, dst, src);
119 leal dst, src -> LEA (IL, dst, src);
122 rmovs pre -> RMOVS pre;
129 not pre, dst -> NOT (pre, dst) : pairu pairv;
130 neg pre, dst -> NEG (pre, dst) : pairu pairv;
131 inc pre, dst -> INC (pre, dst) : pairu pairv;
132 dec pre, dst -> DEC (pre, dst) : pairu pairv;
133 add pre, dst, src -> ADD (pre, dst, src) : pairu pairv;
134 sub pre, dst, src -> SUB (pre, dst, src) : pairu pairv;
135 notl dst -> NOT (IL, dst) : pairu pairv;
136 negl dst -> NEG (IL, dst) : pairu pairv;
137 incl dst -> INC (IL, dst) : pairu pairv;
138 decl dst -> DEC (IL, dst) : pairu pairv;
139 addl dst, src -> ADD (IL, dst, src) : pairu pairv;
140 subl dst, src -> SUB (IL, dst, src) : pairu pairv;
142 adc pre, dst, src -> ADC (pre, dst, src) : pairu;
143 sbb pre, dst, src -> SBB (pre, dst, src) : pairu;
144 adcl dst, src -> ADC (IL, dst, src) : pairu;
145 sbbl dst, src -> SBB (IL, dst, src) : pairu;
148 imul pre, dst, src -> IMUL (pre, dst, src);
149 mul pre, dst -> MUL (pre, dst);
150 idiv pre, dst -> IDIV (pre, dst);
151 div pre, dst -> DIV (pre, dst);
152 imull dst, src -> IMUL (IL, dst, src);
153 mull dst -> MUL (IL, dst);
154 idivl dst -> IDIV (IL, dst);
155 divl dst -> DIV (IL, dst);
157 and pre, dst, src -> AND (pre, dst, src) : pairu pairv;
158 or pre, dst, src -> OR (pre, dst, src) : pairu pairv;
159 xor pre, dst, src -> XOR (pre, dst, src) : pairu pairv;
160 andb dst, src -> AND (IB, dst, src) : pairu pairv;
161 orb dst, src -> OR (IB, dst, src) : pairu pairv;
162 xorb dst, src -> XOR (IB, dst, src) : pairu pairv;
163 andw dst, src -> AND (IW, dst, src) : pairu pairv;
164 orw dst, src -> OR (IW, dst, src) : pairu pairv;
165 xorw dst, src -> XOR (IW, dst, src) : pairu pairv;
166 andl dst, src -> AND (IL, dst, src) : pairu pairv;
167 orl dst, src -> OR (IL, dst, src) : pairu pairv;
168 xorl dst, src -> XOR (IL, dst, src) : pairu pairv;
170 _shli pre, dst, $src -> SHL (pre, dst, src) : pairu;
171 _sali pre, dst, $src -> SAL (pre, dst, src) : pairu;
172 _shri pre, dst, $src -> SHR (pre, dst, src) : pairu;
173 _sari pre, dst, $src -> SAR (pre, dst, src) : pairu;
174 shl pre, dst, src -> SHL (pre, dst, src);
175 sal pre, dst, src -> SAL (pre, dst, src);
176 shr pre, dst, src -> SHR (pre, dst, src);
177 sar pre, dst, src -> SAR (pre, dst, src);
178 shld pre, dst, src1, src2 -> SHLD (pre, dst, src1, src2);
179 shrd pre, dst, src1, src2 -> SHRD (pre, dst, src1, src2);
180 shll dst, src -> SHL (IL, dst, src);
181 sall dst, src -> SAL (IL, dst, src);
182 shrl dst, src -> SHR (IL, dst, src);
183 sarl dst, src -> SAR (IL, dst, src);
184 shldl dst, src1, src2 -> SHLD (IL, dst, src1, src2);
185 shrdl dst, src1, src2 -> SHRD (IL, dst, src1, src2);
188 (* Comparisons and control-flow *)
190 cmp pre, src1, src2 -> CMP (pre, src1, src2) : pairu pairv;
191 test pre, src1, src2 -> TEST (pre, src1, src2) : pairu pairv;
192 cmpl src1, src2 -> CMP (IL, src1, src2) : pairu pairv;
193 testl src1, src2 -> TEST (IL, src1, src2) : pairu pairv;
195 instructions cond_any cond_any_equality:
196 je label -> JCC (EQ, label) : pairv boundary_inst;
197 jne label -> JCC (NEQ, label) : pairv boundary_inst;
198 sete dst -> SET (EQ, dst);
199 setne dst -> SET (NEQ, dst);
201 instructions cond_any:
202 jcc op, label -> JCC (op, label) : pairv boundary_inst;
203 set op, dst -> SET (op, dst);
205 instructions boundary_inst:
206 jmp label -> JMP label : pairv;
207 fjmp label -> FJMP label : pairv;
208 ijmp srcs, label -> IJMP (srcs, label) : pairv;
209 res l, s, m, p -> RES (l, s, m, p);
210 cow l, s, m, p, cp -> COW (l, s, m, p, cp);
211 resp l, s -> RESP (l, s);
215 _pshi pre, $op -> PUSH (pre, op) : pairu pairv;
216 _pshr pre, %op -> PUSH (pre, op) : pairu pairv;
217 _popr pre, %op -> POP (pre, op) : pairu pairv;
218 push pre, op -> PUSH (pre, op);
219 pop pre, op -> POP (pre, op);
220 pushl op -> PUSH (IL, op);
221 popl op -> POP (IL, op);
222 call label -> CALL label : pairv;
223 fcall label -> FCALL label : pairv;
226 (* Floating-point operations *)
228 fld pre, op -> FLD (pre, op) : pairv;
229 fldt op -> FLD (FT, op) : pairv;
230 fild op -> FILD op : pairv;
231 fild64 op -> FILD64 op : pairv;
232 fst pre, op -> FST (pre, op);
234 fstp pre, op -> FSTP (pre, op);
235 fstpt op -> FSTP (FT, op);
236 fistp op -> FISTP op;
237 fistp64 op -> FISTP64 op;
238 fmov dp, d, sp, s-> FMOV (dp, d, sp, s);
239 fmovp dp, d, sp, s-> FMOVP (dp, d, sp, s);
240 fxch op -> FXCH op : pairu pairv;
241 fstcw op -> FSTCW op;
242 fldcw op -> FLDCW op;
243 movd d, s -> MOVD (d, s) : pairu pariv;
244 movq d, s -> MOVQ (d, s) : pairu pairv;
246 instructions float1_op:
247 fchs -> FCHS : pairv;
248 fsqrt -> FSQRT : pairv;
249 fsin -> FSIN : pairv;
250 fcos -> FCOS : pairv;
252 instructions float2_op float2_pop_op:
253 faddp -> FADDP : pairv;
254 fsubp -> FSUBP : pairv;
255 fmulp -> FMULP : pairv;
256 fdivp -> FDIVP : pairv;
257 fsubrp -> FSUBRP : pairv;
258 fdivrp -> FDIVRP : pairv;
260 instructions float2_op float2_nopop_op:
261 fadd dst, src -> FADD (dst, src) : pairv;
262 fsub dst, src -> FSUB (dst, src) : pairv;
263 fmul dst, src -> FMUL (dst, src) : pairv;
264 fdiv dst, src -> FDIV (dst, src) : pairv;
265 fsubr dst, src -> FSUBR (dst, src) : pairv;
266 fdivr dst, src -> FDIVR (dst, src) : pairv;
269 finit -> FINIT : pairv;
270 fprem -> FPREM : pairv;
271 fpatan -> FPATAN : pairv;
272 fucompp -> FUCOMPP : pairv;
273 fucomp -> FUCOMP : pairv;
274 fucom -> FUCOM : pairv;
275 fstsw -> FSTSW : pairv;
279 instructions trivial_inst:
280 comm_inst s, inst -> CommentInst (s, inst);
281 comm_string s -> CommentString s;
282 comm_fir e -> CommentFIR e;
283 comm_mir e -> CommentMIR e;
286 (*** Identify the trivial instructions ***)
292 (*** Named Transformations ***)
296 Inverts the conditional of the named instruction. *)
297 transform cond_invert:
298 jcc EQ, label -> jcc NEQ, label;
299 jcc NEQ, label -> jcc EQ, label;
300 jcc LT, label -> jcc GE, label;
301 jcc LE, label -> jcc GT, label;
302 jcc GT, label -> jcc LE, label;
303 jcc GE, label -> jcc LT, label;
304 jcc ULT, label -> jcc UGE, label;
305 jcc ULE, label -> jcc UGT, label;
306 jcc UGT, label -> jcc ULE, label;
307 jcc UGE, label -> jcc ULT, label;
308 set EQ, dst -> set NEQ, dst;
309 set NEQ, dst -> set EQ, dst;
310 set LT, dst -> set GE, dst;
311 set LE, dst -> set GT, dst;
312 set GT, dst -> set LE, dst;
313 set GE, dst -> set LT, dst;
314 set ULT, dst -> set UGE, dst;
315 set ULE, dst -> set UGT, dst;
316 set UGT, dst -> set ULE, dst;
317 set UGE, dst -> set ULT, dst;
321 Reverses the direction of the conditional of the named instruction.
322 This is DIFFERENT from the above, which performs a logical NOT; this
323 instruction simply assumes the operands have been reversed. *)
324 transform cond_reverse:
325 jcc EQ, label -> jcc EQ, label;
326 jcc NEQ, label -> jcc NEQ, label;
327 jcc LT, label -> jcc GT, label;
328 jcc LE, label -> jcc GE, label;
329 jcc GT, label -> jcc LT, label;
330 jcc GE, label -> jcc LE, label;
331 jcc ULT, label -> jcc UGT, label;
332 jcc ULE, label -> jcc UGE, label;
333 jcc UGT, label -> jcc ULT, label;
334 jcc UGE, label -> jcc ULE, label;
335 set EQ, dst -> set EQ, dst;
336 set NEQ, dst -> set NEQ, dst;
337 set LT, dst -> set GT, dst;
338 set LE, dst -> set GE, dst;
339 set GT, dst -> set LT, dst;
340 set GE, dst -> set LE, dst;
341 set ULT, dst -> set UGT, dst;
342 set ULE, dst -> set UGE, dst;
343 set UGT, dst -> set ULT, dst;
344 set UGE, dst -> set ULE, dst;
347 (* float2_pop_reverse
348 Takes one of the above instructions and rewrites it as
349 an instruction which uses reversed arguments, and pops. *)
350 transform float2_pop_reverse:
359 (* float2_pop_reverse_nopop
360 Takes one of the above instructions and rewrites it as
361 an instruction which uses reversed arguments, and does
363 transform float2_pop_reverse_nopop:
364 faddp -> fadd @st(0), @st(1);
365 fsubp -> fsubr @st(0), @st(1);
366 fmulp -> fmul @st(0), @st(1);
367 fdivp -> fdivr @st(0), @st(1);
368 fsubrp -> fsub @st(0), @st(1);
369 fdivrp -> fdiv @st(0), @st(1);
372 (* float2_pop_reverse_nopop_src
373 Same as above, only instead of using @st(1), use the
374 register @st(stk) as the second argument. *)
375 transform float2_pop_reverse_nopop_src stk:
376 faddp -> fadd @st(0), @st(stk);
377 fsubp -> fsubr @st(0), @st(stk);
378 fmulp -> fmul @st(0), @st(stk);
379 fdivp -> fdivr @st(0), @st(stk);
380 fsubrp -> fsub @st(0), @st(stk);
381 fdivrp -> fdiv @st(0), @st(stk);
385 Takes one of the above instructions and rewrites it as
386 an instruction which does NOT pop. *)
387 transform float2_pop_nopop:
388 faddp -> fadd @st(0), @st(1);
389 fsubp -> fsub @st(0), @st(1);
390 fmulp -> fmul @st(0), @st(1);
391 fdivp -> fdiv @st(0), @st(1);
392 fsubrp -> fsubr @st(0), @st(1);
393 fdivrp -> fdivr @st(0), @st(1);
396 (* float2_pop_self_ref
397 Rewrites a float2 operation that is self-referential.
398 The result will NOT pop. *)
399 transform float2_pop_self_ref:
400 faddp -> fadd @st(0), @st(0);
401 fsubp -> fsub @st(0), @st(0);
402 fmulp -> fmul @st(0), @st(0);
403 fdivp -> fdiv @st(0), @st(0);
404 fsubrp -> fsubr @st(0), @st(0);
405 fdivrp -> fdivr @st(0), @st(0);
408 (* float2_pop_reverse_store_reg
409 Reverse the operation so the store reg is the original
410 source reg, not the usual %st(0). Only works for the
411 non-popping variety of instructions. *)
412 transform float2_nopop_reverse_store_reg:
413 fadd dst, src -> fadd src, dst;
414 fsub dst, src -> fsubr src, dst;
415 fmul dst, src -> fmul src, dst;
416 fdiv dst, src -> fdivr src, dst;
417 fsubr dst, src -> fsub src, dst;
418 fdivr dst, src -> fdiv src, dst;
421 (* float2_nopop_reverse
422 Reverses a floating-point operation which does not
423 currently pop the stack. *)
424 transform float2_nopop_reverse:
425 fadd dst, src -> fadd dst, src;
426 fsub dst, src -> fsubr dst, src;
427 fmul dst, src -> fmul dst, src;
428 fdiv dst, src -> fdivr dst, src;
429 fsubr dst, src -> fsub dst, src;
430 fdivr dst, src -> fdiv dst, src;