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

SCM Repository

[smlnj] Diff of /sml/trunk/src/MLRISC/x86/x86.md
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 409, Fri Sep 3 00:21:52 1999 UTC revision 579, Wed Mar 22 06:33:08 2000 UTC
# Line 27  Line 27 
27       *)       *)
28    
29     storage     storage
30        GP = 32 cells of 32 bits in cellset called "register"        GP "r" = 32 cells of 32 bits in cellset called "register"
31             assembly as             assembly as
32                      (fn 0 => "%eax"                      (fn (0,8)  => "%al"
33                        | 1 => "%ecx"                        | (0,16) => "%ax"
34                        | 2 => "%edx"                        | (0,32) => "%eax"
35                        | 3 => "%ebx"                        | (1,8)  => "%cl"
36                        | 4 => "%esp"                        | (1,16) => "%cx"
37                        | 5 => "%ebp"                        | (1,32) => "%ecx"
38                        | 6 => "%esi"                        | (2,8)  => "%dl"
39                        | 7 => "%edi"                        | (2,16) => "%dx"
40                        | r => "%"^Int.toString r                        | (2,32) => "%edx"
41                          | (3,8)  => "%bl"
42                          | (3,16) => "%bx"
43                          | (3,32) => "%ebx"
44                          | (4,16) => "%sp"
45                          | (4,32) => "%esp"
46                          | (5,16) => "%bp"
47                          | (5,32) => "%ebp"
48                          | (6,16) => "%si"
49                          | (6,32) => "%esi"
50                          | (7,16) => "%di"
51                          | (7,32) => "%edi"
52                          | (r,_) => "%"^Int.toString r
53                      )                      )
54     |  FP = 32 cells of 80 bits in cellset called "floating point register"     |  FP "f" = 32 cells of 80 bits in cellset called "floating point register"
55             assembly as (fn f => if f >= 0 andalso f < 8                 assembly as (fn (0,_) => "%st"
56                                  then "%st("^Int.toString f^")"                               | (f,_) =>
57                                  else "%f"^Int.toString f (* fake register *)                                  if f < 8 then "%st("^Int.toString f^")"
58                                    else "%f"^Int.toString f
59                                         (* pseudo register *)
60                         )                         )
61     |  CC = cells of 32 bits in cellset called "condition code register"     |  CC "cc" = cells of 32 bits in cellset called "condition code register"
62             assembly as "cc"             assembly as "cc"
63       |  MEM "m" = cells of 8 bits called "memory"
64                    assembly as (fn (r,_) => "m"^Int.toString r)
65       |  CTRL "ctrl" = cells of 8 bits called "control"
66                    assembly as (fn (r,_) => "ctrl"^Int.toString r)
67    
68     locations     locations
69         eax     = $GP[0]         eax     = $GP[0]
70     and ecx     = $GP[1]     and ecx     = $GP[1]
# Line 55  Line 74 
74     and ebp     = $GP[5]     and ebp     = $GP[5]
75     and esi     = $GP[6]     and esi     = $GP[6]
76     and edi     = $GP[7]     and edi     = $GP[7]
77     and stackptrR = esp     and stackptrR = $GP[4]
78       and ST(x)   = $FP[x]
79     and asmTmpR   = ~1 (* not used *)     and asmTmpR   = ~1 (* not used *)
80     and fasmTmp   = ~1 (* not used *)     and fasmTmp   = ~1 (* not used *)
81    
82     structure Cells =     structure RTL =
83     struct     struct
       fun zeroReg _ = NONE  
84     end     end
85    
   
    (*  
    semantics X86 =  
    struct  
       include "MD++/basis.md"  
       open Basis  
       structure Int32 = struct type int end  
       type 'a option  
    end *)  
   
86     structure Instruction = struct     structure Instruction = struct
87   (* An effective address can be any combination of   (* An effective address can be any combination of
88    *  base + index*scale + disp    *  base + index*scale + disp
# Line 96  Line 105 
105    (* Note: Relative is only generated after sdi resolution *)    (* Note: Relative is only generated after sdi resolution *)
106    datatype operand =    datatype operand =
107       Immed      of Int32.int       Immed      of Int32.int
    | Const      of Constant.const  
108     | ImmedLabel of LabelExp.labexp     | ImmedLabel of LabelExp.labexp
109     | Relative   of int     | Relative   of int
110     | LabelEA    of LabelExp.labexp     | LabelEA    of LabelExp.labexp
111     | Direct     of $GP     | Direct     of $GP
112     | FDirect    of $FP     | FDirect    of $FP
113       | ST         of $FP
114       | MemReg     of int (* pseudo memory register *)
115     | Displace   of {base: $GP, disp:operand, mem:Region.region}     | Displace   of {base: $GP, disp:operand, mem:Region.region}
116     | Indexed    of {base: $GP option, index: $GP, scale:int, disp:operand,     | Indexed    of {base: $GP option, index: $GP, scale:int, disp:operand,
117                      mem:Region.region}                      mem:Region.region}
118    
119    type ea = operand    type addressing_mode = operand
   
   datatype binaryOp! = ADD | SUB  | AND | OR | XOR | SHL | SAR | SHR  
   
   datatype multDivOp! = UMUL | IDIV | UDIV  
120    
121    datatype unaryOp! = DEC | INC | NEG | NOT    type ea = operand
   
   datatype move! = MOVL | MOVZX | MOVB  
122    
123    datatype cond! =    datatype cond! =
124        EQ | NE | LT | LE | GT | GE        EQ "e" | NE | LT "l" | LE | GT "g" | GE
125      | B  | BE (* below *)   | A  | AE (* above *)      | B  | BE (* below *)   | A  | AE (* above *)
126      | C  | NC (* if carry *)| P  | NP (* if parity *)      | C  | NC (* if carry *)| P  | NP (* if parity *)
127      | O  | NO (* overflow *)      | O  | NO (* overflow *)
128    
129      datatype binaryOp! =
130         ADDL | SUBL | ANDL | ORL | XORL | SHLL | SARL | SHRL | ADCL | SBBL
131       | ADDW | SUBW | ANDW | ORW | XORW | SHLW | SARW | SHRW
132       | ADDB | SUBB | ANDB | ORB | XORB | SHLB | SARB | SHRB
133    
134      datatype multDivOp! = UMUL | IDIV | UDIV
135    
136      datatype unaryOp! = DECL | INCL | NEGL | NOTL | NOTW | NOTB
137    
138      datatype move! = MOVL
139                     | MOVB
140                     | MOVW
141                     | MOVSWL | MOVZWL  (* word -> long *)
142                     | MOVSBL | MOVZBL  (* byte -> long *)
143    
144   (* The Intel manual is incorrect on the description of FDIV and FDIVR *)   (* The Intel manual is incorrect on the description of FDIV and FDIVR *)
145    datatype fbinOp! =    datatype fbinOp! =
146        FADDP  | FADD        FADDP   | FADDS
147      | FMULP  | FMUL      | FMULP   | FMULS
148      | FSUBP  | FSUB             (* ST(1) := ST-ST(1); [pop] *)                | FCOMS
149      | FSUBRP | FSUBR            (* ST(1) := ST(1)-ST; [pop] *)                | FCOMPS
150      | FDIVP  | FDIV             (* ST(1) := ST/ST(1); [pop] *)      | FSUBP   | FSUBS   (* ST(1) := ST-ST(1); [pop] *)
151      | FDIVRP | FDIVR            (* ST(1) := ST(1)/ST; [pop] *)      | FSUBRP  | FSUBRS  (* ST(1) := ST(1)-ST; [pop] *)
152        | FDIVP   | FDIVS   (* ST(1) := ST/ST(1); [pop] *)
153        | FDIVRP  | FDIVRS  (* ST(1) := ST(1)/ST; [pop] *)
154                  | FADDL
155                  | FMULL
156                  | FCOML
157                  | FCOMPL
158                  | FSUBL   (* ST(1) := ST-ST(1); [pop] *)
159                  | FSUBRL  (* ST(1) := ST(1)-ST; [pop] *)
160                  | FDIVL   (* ST(1) := ST/ST(1); [pop] *)
161                  | FDIVRL  (* ST(1) := ST(1)/ST; [pop] *)
162    
163      datatype fibinOp! =
164          FIADDS | FIMULS   | FICOMS | FICOMPS
165        | FISUBS | FISUBRS  | FIDIVS | FIDIVRS
166        | FIADDL | FIMULL   | FICOML | FICOMPL
167        | FISUBL | FISUBRL  | FIDIVL | FIDIVRL
168    
169    datatype funOp! = FABS | FCHS    datatype funOp! = FABS | FCHS
170                      | FSIN | FCOS | FTAN
171                      | FSCALE | FRNDINT | FSQRT
172                      | FTST | FXAM
173                      | FINCSTP | FDECSTP
174    
175      datatype fenvOp! = FLDENV | FNLDENV | FSTENV | FNSTENV
176    
177    end (* struct Instruction *)    end (* struct Instruction *)
178    
# Line 140  Line 181 
181       (structure MemRegs : MEMORY_REGISTERS where I = Instr) =       (structure MemRegs : MEMORY_REGISTERS where I = Instr) =
182    struct    struct
183       val memReg = MemRegs.memReg regmap       val memReg = MemRegs.memReg regmap
184       fun emitInt32 i = emit(if i < 0 then "-"^Int32.toString(~i)       fun emitInt32 i =
185                              else Int32.toString i)       let val s = Int32.toString i
186       fun emit_src2 NONE = ()           val s = if i >= 0 then s else "-"^String.substring(s,1,size s-1)
187         | emit_src2(SOME i) = (emit "$"; emitInt32 i; emit ", ")       in  emit s end
188    
189       fun emitScale 0 = emit "1"       fun emitScale 0 = emit "1"
190         | emitScale 1 = emit "2"         | emitScale 1 = emit "2"
# Line 152  Line 193 
193         | emitScale _ = error "emitScale"         | emitScale _ = error "emitScale"
194    
195       and eImmed(I.Immed (i)) = emitInt32 i       and eImmed(I.Immed (i)) = emitInt32 i
        | eImmed(I.Const c) = emit_const c  
196         | eImmed(I.ImmedLabel lexp) = emit_labexp lexp         | eImmed(I.ImmedLabel lexp) = emit_labexp lexp
197         | eImmed _ = error "eImmed"         | eImmed _ = error "eImmed"
198    
199       and emit_operand opn =       and emit_operand opn =
200           case opn of           case opn of
201           I.Immed i => (emit "$"; emitInt32 i)           I.Immed i => (emit "$"; emitInt32 i)
        | I.Const c => emit_const c  
202         | I.ImmedLabel lexp => (emit "$"; emit_labexp lexp)         | I.ImmedLabel lexp => (emit "$"; emit_labexp lexp)
203         | I.LabelEA le => emit_labexp le         | I.LabelEA le => emit_labexp le
204         | I.Relative _ => error "emit_operand"         | I.Relative _ => error "emit_operand"
205         | I.Direct r => emit_GP r         | I.Direct r => emit_GP r
206         | I.FDirect f =>         | I.MemReg r => emit_operand(memReg opn)
207              let val f' = regmap f         | I.ST f => emit_FP f
208              in  if f' < (32+8) then emit_FP f' else emit_operand(memReg opn) end         | I.FDirect f => emit_operand(memReg opn)
        | I.Displace{base,disp=I.Immed(0),mem,...} =>  
            (emit "("; emit_GP base; emit ")"; emit_region mem)  
209         | I.Displace{base,disp,mem,...} =>         | I.Displace{base,disp,mem,...} =>
210             (eImmed disp; emit "("; emit_GP base; emit ")";             (emit_disp disp; emit "("; emit_GP base; emit ")";
             emit_region mem)  
        | I.Indexed{base=NONE,index,scale,disp,mem,...} =>  
           (emit "("; emit_GP index; comma(); emitScale scale; emit ")";  
211             emit_region mem)             emit_region mem)
212         | I.Indexed{base=SOME base,index,scale,disp,mem,...} =>         | I.Indexed{base,index,scale,disp,mem,...} =>
213           (eOptionalDisp disp; emit "("; emit_GP base;            (emit_disp disp; emit "(";
214            comma(); emit_GP index; emitScale scale; emit ")";             case base of
215            emit_region mem)               NONE => ()
216        and eOptionalDisp(I.Immed 0) = ()             | SOME base => emit_GP base;
217          | eOptionalDisp(I.Const c) = emit(Constant.toString c)             comma();
218          | eOptionalDisp(I.Immed i) = emitInt32 i             emit_GP index; comma();
219          | eOptionalDisp _ = error "eOptionalDisp"             emitScale scale; emit ")"; emit_region mem)
220    
221          and emit_disp(I.Immed 0) = ()
222            | emit_disp(I.Immed i) = emitInt32 i
223            | emit_disp(I.ImmedLabel lexp) = emit_labexp lexp
224            | emit_disp _ = error "emit_disp"
225    
226       (* The gas assembler does not like the "$" prefix for immediate       (* The gas assembler does not like the "$" prefix for immediate
227        * labels in certain instructions.        * labels in certain instructions.
# Line 191  Line 230 
230          | stupidGas(I.LabelEA _) = error "stupidGas"          | stupidGas(I.LabelEA _) = error "stupidGas"
231          | stupidGas opnd = emit_operand opnd          | stupidGas opnd = emit_operand opnd
232    
233         (* Display the floating point binary opcode *)
234          fun isMemOpnd(I.MemReg _) = true
235            | isMemOpnd(I.FDirect f) = true
236            | isMemOpnd(I.LabelEA _) = true
237            | isMemOpnd(I.Displace _) = true
238            | isMemOpnd(I.Indexed _) = true
239            | isMemOpnd _ = false
240          fun chop fbinOp =
241              let val n = size fbinOp
242              in  case Char.toLower(String.sub(fbinOp,n-1)) of
243                    (#"s" | #"l") => String.substring(fbinOp,0,n-1)
244                  | _ => fbinOp
245              end
246    
247        val emit_dst = emit_operand        val emit_dst = emit_operand
248        val emit_src = emit_operand        val emit_src = emit_operand
249        val emit_opnd = emit_operand        val emit_opnd = emit_operand
       val emit_src1 = emit_operand  
250        val emit_rsrc = emit_operand        val emit_rsrc = emit_operand
251        val emit_lsrc = emit_operand        val emit_lsrc = emit_operand
252        val emit_addr = emit_operand        val emit_addr = emit_operand
253    end        val emit_src1 = emit_operand
254      end (* Instruction *)
255    
256   (* many of these instructions imply certain register usages *)   (* many of these instructions imply certain register usages *)
257    instruction    instruction
# Line 209  Line 262 
262          ``jmp\t<stupidGas operand>''          ``jmp\t<stupidGas operand>''
263    
264      | JCC of {cond:cond, opnd:operand}      | JCC of {cond:cond, opnd:operand}
265          ``j<cond>, <stupidGas opnd>''          ``j<cond>\t<stupidGas opnd>''
266    
267      | CALL of operand * C.cellset * C.cellset * Region.region      | CALL of operand * C.cellset * C.cellset * Region.region
268          ``call\t<stupidGas operand><region>''          ``call\t<stupidGas operand><region><
269              emit_defs(cellset1)><
270      | RET            emit_uses(cellset2)>''
271          ``ret''  
272        | LEAVE
273            ``leave''
274    
275        | RET of operand option
276            ``ret<case operand of NONE => ()
277                                | SOME e => (emit "\t"; emit_operand e)>''
278    
279     (* integer *)     (* integer *)
280      | MOVE of {mvOp:move, src:operand, dst:operand}      | MOVE of {mvOp:move, src:operand, dst:operand}
# Line 224  Line 283 
283      | LEA of {r32: $GP, addr: operand}      | LEA of {r32: $GP, addr: operand}
284          ``leal\t<addr>, <r32>''          ``leal\t<addr>, <r32>''
285    
286      | CMP of {lsrc: operand, rsrc: operand}      | CMPL of {lsrc: operand, rsrc: operand}
287          ``cmpl\t<rsrc>, <lsrc>''          ``cmpl\t<rsrc>, <lsrc>''
288    
289        | CMPW of {lsrc: operand, rsrc: operand}
290            ``cmpb\t<rsrc>, <lsrc>''
291    
292        | CMPB of {lsrc: operand, rsrc: operand}
293            ``cmpb\t<rsrc>, <lsrc>''
294    
295        | TESTL of {lsrc: operand, rsrc: operand}
296            ``testl\t<rsrc>, <lsrc>''
297    
298        | TESTW of {lsrc: operand, rsrc: operand}
299            ``testw\t<rsrc>, <lsrc>''
300    
301        | TESTB of {lsrc: operand, rsrc: operand}
302            ``testb\t<rsrc>, <lsrc>''
303    
304      | BINARY of {binOp:binaryOp, src:operand, dst:operand}      | BINARY of {binOp:binaryOp, src:operand, dst:operand}
305          ``<binOp>l\t<src>, <dst>''          asm: (case (src,binOp) of
306                   (I.Direct _,
307                   (I.SARL | I.SHRL | I.SHLL |
308                    I.SARW | I.SHRW | I.SHLW |
309                    I.SARB | I.SHRB | I.SHLB)) => ``<binOp>\t%cl, <dst>''
310                 | _ => ``<binOp>\t<src>, <dst>''
311                 )
312    
313      | MULTDIV of {multDivOp:multDivOp, src:operand}      | MULTDIV of {multDivOp:multDivOp, src:operand}
314          ``<multDivOp>l\t<src>''          ``<multDivOp>l\t<src>''
315    
316      | MUL3 of {dst:int, src1:operand, src2: Int32.int option}      | MUL3 of {dst: $GP, src2: Int32.int option, src1:operand}
317          ``imul\t<src1>, <emit_src2 src2><dst>''          (* Fermin: constant operand must go first *)
318            asm: (case src2 of
319                    NONE => ``imul\t<src1>, <dst>''
320                  | SOME i => ``imul\t$<emitInt32 i>, <src1>, <dst>''
321                 )
322    
323      | UNARY of {unOp:unaryOp, opnd:operand}      | UNARY of {unOp:unaryOp, opnd:operand}
324          ``<unOp>l\t<opnd>''          ``<unOp>\t<opnd>''
325    
326          (* set byte on condition code; note that
327           * this only sets the low order byte, so it also
328           * uses its operand.
329           *)
330        | SET of {cond:cond, opnd:operand}
331             ``set<cond>\t<opnd>''
332    
333            (* conditional move; Pentium Pro or higher only
334             * Destination must be a register.
335             *)
336        | CMOV of {cond:cond, src:operand, dst: $GP}
337            ``cmov<cond>\t<src>, <dst>''
338    
339      | PUSH of operand      | PUSHL of operand
340          ``pushl\t<operand>''          ``pushl\t<operand>''
341    
342        | PUSHW of operand
343            ``pushw\t<operand>''
344    
345        | PUSHB of operand
346            ``pushb\t<operand>''
347    
348      | POP of operand      | POP of operand
349          ``popl\t<operand>''          ``popl\t<operand>''
350    
# Line 253  Line 356 
356    
357     (* parallel copies *)     (* parallel copies *)
358      | COPY of {dst: $GP list, src: $GP list, tmp:operand option}      | COPY of {dst: $GP list, src: $GP list, tmp:operand option}
359          ``<emitInstrs (Shuffle.shuffle{regmap,tmp,dst,src})>''          asm: emitInstrs (Shuffle.shuffle{regmap,tmp,dst,src})
     | FCOPY of {dst: $FP list, src: $FP list, tmp:operand option}  
         ``<emitInstrs (Shuffle.shufflefp{regmap,tmp,dst,src})>''  
360    
361        | FCOPY of {dst: $FP list, src: $FP list, tmp:operand option}
362            asm: emitInstrs (Shuffle.shufflefp{regmap,tmp,dst,src})
363    
364     (* floating *)     (* floating *)
365      | FBINARY of {binOp:fbinOp, src:operand, dst:operand}      | FBINARY of {binOp:fbinOp, src:operand, dst:operand}
366          ``<binOp>\t<src>, <dst>''          asm: (if isMemOpnd src then ``<binOp>\t<src>''
367                  else ``<emit(chop(asm_fbinOp binOp))>\t<src>, <dst>''
368                 )
369    
370        | FIBINARY of {binOp:fibinOp, src:operand}
371            asm: ``<binOp>\t<src>'' (* the implied destination is %ST(0) *)
372    
373      | FUNARY of funOp      | FUNARY of funOp
374          ``<funOp>''          ``<funOp>''
# Line 268  Line 376 
376      | FUCOMPP      | FUCOMPP
377          ``fucompp''          ``fucompp''
378    
379      | FXCH      | FCOMPP
380          ``fxch''          ``fcompp''
381    
382        | FXCH of {opnd: $FP}
383            asm: (``fxch\t''; if opnd = C.ST(1) then () else ``<opnd>'')
384    
385        | FSTPL of operand
386            ``fstpl\t<operand>''
387    
388        | FSTPS of operand
389            ``fstps\t<operand>''
390    
391        | FSTPT of operand
392            ``fstps\t<operand>''
393    
394      | FSTP of operand      | FSTL of operand
395          ``fstp\t<operand>''          ``fstl\t<operand>''
396    
397      | FLD of operand      | FSTS of operand
398          ``fld\t<operand>''          ``fsts\t<operand>''
399    
400        | FLD1
401            ``fld1''
402    
403        | FLDL2E
404            ``fldl2e''
405    
406        | FLDL2T
407            ``fldl2t''
408    
409        | FLDLG2
410            ``fldlg2''
411    
412        | FLDLN2
413            ``fldln2''
414    
415        | FLDPI
416            ``fldpi''
417    
418        | FLDZ
419            ``fldz''
420    
421        | FLDL of operand
422            ``fldl\t<operand>''
423    
424        | FLDS of operand
425            ``flds\t<operand>''
426    
427        | FLDT of operand
428            ``fldt\t<operand>''
429    
430      | FILD of operand      | FILD of operand
431          ``fild\t<operand>''          ``fild\t<operand>''
432    
433        | FILDL of operand
434            ``fildl\t<operand>''
435    
436        | FILDLL of operand
437            ``fildll\t<operand>''
438    
439      | FNSTSW      | FNSTSW
440          ``fnstsw''          ``fnstsw''
441    
442        | FENV of {fenvOp:fenvOp, opnd:operand} (* load/store environment *)
443            ``<fenvOp>\t<opnd>''
444    
445     (* misc *)     (* misc *)
446      | SAHF      | SAHF
447          ``sahf''          ``sahf''
448    
449     (* annotations *)     (* annotations *)
450      | ANNOTATION of {i:instruction, a:Annotations.annotation}      | ANNOTATION of {i:instruction, a:Annotations.annotation}
451          ``<(emitInstr i; comment(Annotations.toString a))>''          asm: (emitInstr i; comment(Annotations.toString a))
   
     | GROUP of Annotations.annotation  
         ``<comment(Annotations.toString annotation)>''  
   
452  end  end
453    

Legend:
Removed from v.409  
changed lines
  Added in v.579

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