Got rid of previous stuff and just imported mcc.
[shack.git] / mcc-0.5.4rta03 / arch / x86 / type / x86_arch.kupo
blob5fd8734c52c2b3f4d033249369d22ad1d2754617
1 (*
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.
18  *)
21 (***  Instruction type file  ***)
22 open X86_frame
23 open X86_inst_type
24 open X86_runtime
27 (***  Declare ML type names  ***)
30 instruction_type  inst
33 (***  Register set and context  ***)
36 declarations:
37    (* Integer registers *)
38    %eax;
39    %ebx;
40    %ecx;
41    %edx;
42    %esi;
43    %edi;
44    %esp;
45    %ebp;
47    (* Flags registers *)
48    %iflags;
49    @fflags;
51    (* Context variables *)
52    %pointer_base;
53    %pointer_next;
54    %pointer_free;
55    %mem_base;
56    %mem_next;
57    %minor_limit;
58    %gc_point;
59    %float_reg_1;
60    %float_reg_2;
62    (* Special program labels *)
63    lbl bin_fir_label;
64    lbl migrate_fun_label;
66    (* Instruction listbufs for use with kupo *)
67    callee_header;
69    (* Constant values *)
70    int31 sizeof_int32;
71    int31 sizeof_int64;
72    int31 sizeof_pointer;
73    int31 callee_header_stack;
74    $ptable_pointer_mask;
75    $aggr_header_size32;
76    $aggr_shift_mask32;
77    $block_header_size32;
78    $index_word32;
79    $index_shift32;
80    $index_mask32;
81    $index_pred_mask32;
82    $size_word32;
83    $size_shift32;
84    $size_aggr_mask32;
85    $size_block_mask32;
86    $size_pred_aggr_mask32;
87    $size_pred_block_mask32;
88    $tag_word32;
89    $tag_shift32;
90    $tag_mask32;
91    $tag_pred_mask32;
92    $arity_tag_word32;
93    $arity_tag_shift32;
94    $arity_tag_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);
121 instructions:
122    rmovs pre               -> RMOVS pre;
123    rmovsb                  -> RMOVS IB;
124    rmovsw                  -> RMOVS IW;
127 (* Arithmetic ops *)
128 instructions:
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;
147    cltd                    -> CLTD;
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 *)
189 instructions:
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);
212    ret                     -> RET;
214 instructions:
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 *)
227 instructions:
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);
233    fist  op          -> FIST 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;
268 instructions:
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;
278 (* Comments *)
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  ***)
289 trivial  trivial_inst
292 (***  Named Transformations  ***)
295 (* cond_invert
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;
320 (* cond_reverse
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:
351    faddp             -> faddp;
352    fsubp             -> fsubrp;
353    fmulp             -> fmulp;
354    fdivp             -> fdivrp;
355    fsubrp            -> fsubp;
356    fdivrp            -> fdivp;
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
362    NOT pop.  *)
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);
384 (* float2_pop_nopop
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;