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/x86MC.sml
ViewVC logotype

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

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

revision 730, Fri Nov 10 14:04:49 2000 UTC revision 731, Fri Nov 10 22:57:45 2000 UTC
# Line 39  Line 39 
39    fun const c = Int32.fromInt(Const.valueOf c)    fun const c = Int32.fromInt(Const.valueOf c)
40    fun lexp le = Int32.fromInt(LE.valueOf le)    fun lexp le = Int32.fromInt(LE.valueOf le)
41    
42    val toWord8 =    val toWord8 = Word8.fromLargeWord o LargeWord.fromLargeInt o Int32.toLarge
     Word8.fromLargeWord o LargeWord.fromLargeInt o Int32.toLarge  
43    val eBytes = Word8Vector.fromList    val eBytes = Word8Vector.fromList
44    fun eByte i = eBytes [Word8.fromInt i]    fun eByte i = eBytes [W8.fromInt i]
45    fun eLong i32 = let    fun eLong i32 = let
46      val w = (W.fromLargeInt o Int32.toLarge) i32      val w = (W.fromLargeInt o Int32.toLarge) i32
47      fun shift cnt = Word8.fromLargeWord(W.>>(w, cnt))      fun shift cnt = W8.fromLargeWord(W.>>(w, cnt))
48    in [shift(0w0), shift(0w8), shift(0w16), shift(0w24)]    in [shift(0w0), shift(0w8), shift(0w16), shift(0w24)]
49    end    end
50    
# Line 58  Line 57 
57             let val AsmEmitter.S.STREAM{emit,...} = AsmEmitter.makeStream []             let val AsmEmitter.S.STREAM{emit,...} = AsmEmitter.makeStream []
58             in  emit regmap instr; error msg end             in  emit regmap instr; error msg end
59    
 (*    val rNum = Intmap.map regmap *)  
60      fun rNum r = let      fun rNum r = let
61        val r' = regmap r        val r' = regmap r
62      in if r' >=0 andalso r' <= 7 then r'      in if r' >=0 andalso r' <= 7 then r'
63         else error ("rNum: bad register " ^ Int.toString r ^ " --> " ^         else error ("rNum: bad register " ^ Int.toString r ^ " --> " ^
64                      Int.toString r')                      Int.toString r')
65      end      end
     fun fNum r = if r < 64 then r else regmap r  
66    
67      val memReg = MemRegs.memReg fNum      fun fNum f = regmap f - fpoffset
68    
69        val memReg = MemRegs.memReg regmap
70    
71      datatype size = Zero | Bits8 | Bits32      datatype size = Zero | Bits8 | Bits32
72      fun size i =      fun size i =
# Line 81  Line 80 
80        | immedOpnd _ = error "immedOpnd"        | immedOpnd _ = error "immedOpnd"
81    
82      nonfix mod      nonfix mod
83      fun modrm{mod, reg, rm} = Word8.fromInt(mod*64 + reg*8 + rm)  
84      fun sib{ss, index, base} = Word8.fromInt(ss*64 + index*8 + base)      fun scale(n, m) = Word.toIntX(Word.<<(Word.fromInt n, Word.fromInt m))
85        fun modrm{mod, reg, rm} = W8.fromInt(scale(mod,6) + scale(reg,3) + rm)
86        fun sib{ss, index, base} = W8.fromInt(scale(ss,6) + scale(index,3) + base)
87        fun reg{opc, reg} = W8.fromInt(scale(opc,3) + reg)
88    
89      fun eImmedExt(opc, I.Direct r) = [modrm{mod=3, reg=opc, rm=rNum r}]      fun eImmedExt(opc, I.Direct r) = [modrm{mod=3, reg=opc, rm=rNum r}]
90        | eImmedExt(opc, opn as I.MemReg _) = eImmedExt(opc, memReg opn)        | eImmedExt(opc, opn as I.MemReg _) = eImmedExt(opc, memReg opn)
# Line 91  Line 93 
93            val immed = immedOpnd disp            val immed = immedOpnd disp
94            fun displace(mod, eDisp) =            fun displace(mod, eDisp) =
95              if base=esp then              if base=esp then
96                modrm{mod=mod, reg=opc, rm=4}::sib{ss=0, index=4, base=esp}::eDisp immed                modrm{mod=mod, reg=opc, rm=4}::
97                  sib{ss=0, index=4, base=esp}::eDisp immed
98              else              else
99                modrm{mod=mod, reg=opc, rm=base} :: eDisp immed                modrm{mod=mod, reg=opc, rm=base} :: eDisp immed
100          in          in
# Line 136  Line 139 
139        | eImmedExt(_, I.ImmedLabel _) = error "eImmedExt: ImmedLabel"        | eImmedExt(_, I.ImmedLabel _) = error "eImmedExt: ImmedLabel"
140        | eImmedExt(_, I.Relative _) = error "eImmedExt: Relative"        | eImmedExt(_, I.Relative _) = error "eImmedExt: Relative"
141        | eImmedExt(_, I.LabelEA _) = error "eImmedExt: LabelEA"        | eImmedExt(_, I.LabelEA _) = error "eImmedExt: LabelEA"
142          | eImmedExt(_, I.FPR _) = error "eImmedExt: FPR"
143          | eImmedExt(_, I.ST _) = error "eImmedExt: ST"
144    
145           (* Short hands for various encodings *)
146        fun encode(byte1, opc, opnd) = eBytes(byte1 :: eImmedExt(opc, opnd))
147        fun encodeST(byte1, opc, STn) = eBytes[byte1, reg{opc=opc,reg=fNum STn}]
148        fun encode2(byte1, byte2, opc, opnd) =
149            eBytes(byte1 :: byte2 :: eImmedExt(opc, opnd))
150        fun encodeReg(byte1, reg, opnd) = encode(byte1, rNum reg, opnd)
151        fun encodeLongImm(byte1, opc, opnd, i) =
152             eBytes(byte1 :: (eImmedExt(opc, opnd) @ eLong i))
153        fun encodeByteImm(byte1, opc, opnd, b) =
154             eBytes(byte1 :: (eImmedExt(opc, opnd) @ [toWord8 b]))
155    
156      fun condCode cond =      fun condCode cond =
157          (case cond          (case cond
# Line 166  Line 182 
182              of Bits32 =>              of Bits32 =>
183                 (case dst                 (case dst
184                  of I.Direct r =>                  of I.Direct r =>
185                      if rNum r = 0 (* eax *) then                      if rNum r = eax then
186                        eBytes(W8.fromInt(8*opc2 + 5) :: eLong(i))                        eBytes(W8.fromInt(8*opc2 + 5) :: eLong(i))
187                      else                      else
188                        eBytes(0wx81 :: (eImmedExt(opc2, dst) @ eLong(i)))                        encodeLongImm(0wx81, opc2, dst, i)
189                   | _ =>                   | _ => encodeLongImm(0wx81, opc2, dst, i)
                       eBytes(0wx81 :: (eImmedExt(opc2, dst) @ eLong(i)))  
190                 (*esac*))                 (*esac*))
191               | _ =>               | _ => encodeByteImm(0wx83, opc2, dst, i) (* 83 /digit ib *)
                (* 83 /digit ib *)  
                eBytes(0wx83 :: (eImmedExt(opc2,dst) @ [toWord8 i]))  
192            (*esac*))            (*esac*))
193          | f(src, I.Direct r) =          | f(src, I.Direct r) = encodeReg(opc1+0w3, r, src)
194               eBytes((opc1+0w3)::eImmedExt(rNum r, src))          | f(I.Direct r, dst) = encodeReg(opc1+0w1, r, dst)
         | f(I.Direct r, dst) =  
              eBytes((opc1 + 0w1) :: eImmedExt(rNum r, dst))  
195          | f _ = error "arith.f"          | f _ = error "arith.f"
196      in f      in f
197      end      end
# Line 198  Line 209 
209      fun test(bits, I.ImmedLabel le, lsrc) = test(bits, I.Immed(lexp le), lsrc)      fun test(bits, I.ImmedLabel le, lsrc) = test(bits, I.Immed(lexp le), lsrc)
210        | test(bits, I.LabelEA le, lsrc) = test(bits, I.Immed(lexp le), lsrc)        | test(bits, I.LabelEA le, lsrc) = test(bits, I.Immed(lexp le), lsrc)
211        | test(bits, I.Immed(i), lsrc) =        | test(bits, I.Immed(i), lsrc) =
212          let val encoding =           (case (lsrc, i >= 0 andalso i < 255) of
                 case (lsrc, i >= 0 andalso i < 255) of  
213                    (I.Direct r, false) =>                    (I.Direct r, false) =>
214                        if rNum r = 0 (* eax *) then (0wxA9::eLong i)               if rNum r = eax then eBytes(0wxA9 :: eLong i)
215                        else 0wxF7::(eImmedExt(0, lsrc)@eLong i)               else encodeLongImm(0wxF7, 0, lsrc, i)
216                  | (_, false)  => 0wxF7::(eImmedExt(0, lsrc) @ eLong i)           | (_, false)  => encodeLongImm(0wxF7, 0, lsrc, i)
217                  | (I.Direct r, true) =>  (* 8 bit *)                  | (I.Direct r, true) =>  (* 8 bit *)
218                     let val r = rNum r                     let val r = rNum r
219                     in  if r = 0 (* eax *) then [0wxA8, toWord8 i]             in  if r = eax then eBytes[0wxA8, toWord8 i]
220                         else if r < 4 then                         else if r < 4 then
221                            (* unfortunately, only CL, DL, BL can be encoded *)                            (* unfortunately, only CL, DL, BL can be encoded *)
222                            0wxF6::(eImmedExt(0, lsrc) @ [toWord8 i])                    encodeByteImm(0wxF6, 0, lsrc, i)
223                         else if bits = 8 then error "test.8"                         else if bits = 8 then error "test.8"
224                         else 0wxF7::(eImmedExt(0, lsrc) @ eLong i)                 else encodeLongImm(0wxF7, 0, lsrc, i)
                    end  
                 | (_, true) => 0wxF6::(eImmedExt(0, lsrc) @ [toWord8 i])  
         in  eBytes encoding  
225          end          end
226             | (_, true) => encodeByteImm(0wxF6, 0, lsrc, i)
227             )
228        | test(8, rsrc as I.Direct r, lsrc) =        | test(8, rsrc as I.Direct r, lsrc) =
229           if rNum r < 4 then           if rNum r < 4 then encodeReg(0wx84, r, lsrc)
             eBytes(0wx84 :: eImmedExt(rNum r, lsrc))  
230           else error "test.8"           else error "test.8"
231        | test(32, I.Direct r, lsrc) =        | test(32, I.Direct r, lsrc) = encodeReg(0wx85, r, lsrc)
          eBytes(0wx85 :: eImmedExt(rNum r, lsrc))  
232        | test _ = error "test"        | test _ = error "test"
233    
234    in    in
235      case instr      case instr
236      of I.NOP => eByte 0x90      of I.NOP => eByte 0x90
      | I.JMP(r as I.Direct _, _) => eBytes(0wxff :: eImmedExt(4, r))  
      | I.JMP(d as I.Displace _, _) => eBytes(0wxff :: eImmedExt(4, d))  
      | I.JMP(m as I.MemReg _, _) => eBytes(0wxff :: eImmedExt(4, m))  
      | I.JMP(i as I.Indexed _, _) => eBytes(0wxff :: eImmedExt(4, i))  
237       | I.JMP(I.Relative i, _) => ((let       | I.JMP(I.Relative i, _) => ((let
238           fun shortJmp() = eBytes[0wxeb, Word8.fromInt(i-2)]           fun shortJmp() = eBytes[0wxeb, Word8.fromInt(i-2)]
239         in         in
# Line 240  Line 243 
243          (*esac*)          (*esac*)
244         end         end
245         ) handle e => (print "JMP\n"; raise e))         ) handle e => (print "JMP\n"; raise e))
246         | I.JMP(opnd, _) => encode(0wxff, 4, opnd)
247       | I.JCC{cond, opnd=I.Relative i} =>       | I.JCC{cond, opnd=I.Relative i} =>
248         let val code = condCode cond         let val code = condCode cond
249         in  case size (Int32.fromInt(i-2))         in  case size (Int32.fromInt(i-2))
# Line 249  Line 253 
253                  eBytes[Word8.+(0wx70,code), Word8.fromInt(i-2)]                  eBytes[Word8.+(0wx70,code), Word8.fromInt(i-2)]
254         end         end
255       | I.CALL(I.Relative _, _, _, _) => error "CALL: Not implemented"       | I.CALL(I.Relative _, _, _, _) => error "CALL: Not implemented"
256       | I.CALL(opnd, _, _, _) => eBytes(0wxff :: eImmedExt(2, opnd))       | I.CALL(opnd, _, _, _) => encode(0wxff, 2, opnd)
257       | I.RET NONE => eByte 0xc3       | I.RET NONE => eByte 0xc3
258       (* integer *)       (* integer *)
259       | I.MOVE{mvOp=I.MOVL, src, dst} =>       | I.MOVE{mvOp=I.MOVL, src, dst} =>
260         let fun mv(I.Immed(i), I.Direct r) =         let fun mv(I.Immed(i), I.Direct r) =
261                   eBytes(Word8.+(0wxb8, Word8.fromInt(rNum r))::eLong(i))                   eBytes(Word8.+(0wxb8, Word8.fromInt(rNum r))::eLong(i))
262               | mv(I.Immed(i), _) =               | mv(I.Immed(i), _) = encodeLongImm(0wxc7, 0, dst, i)
                  eBytes(0wxc7 :: (eImmedExt(0, dst) @ eLong(i)))  
263               | mv(I.ImmedLabel le,dst) = mv(I.Immed(lexp le),dst)               | mv(I.ImmedLabel le,dst) = mv(I.Immed(lexp le),dst)
264               | mv(I.LabelEA le,dst) = error "MOVL: LabelEA"               | mv(I.LabelEA le,dst) = error "MOVL: LabelEA"
265               | mv(src as I.MemReg _, dst) = mv(memReg src, dst)               | mv(src as I.MemReg _, dst) = mv(memReg src, dst)
# Line 266  Line 269 
269       | I.MOVE{mvOp=I.MOVB, dst, src=I.Immed(i)} =>       | I.MOVE{mvOp=I.MOVB, dst, src=I.Immed(i)} =>
270         (case size i         (case size i
271           of Bits32 => error "MOVE: MOVB: imm8"           of Bits32 => error "MOVE: MOVB: imm8"
272            | _ => eBytes(0wxc6 :: (eImmedExt(0, dst) @ [toWord8 i]))            | _ => encodeByteImm(0wxc6, 0, dst, i)
273         (*esac*))         (*esac*))
274       | I.MOVE{mvOp=I.MOVB, dst, src=I.Direct r} =>       | I.MOVE{mvOp=I.MOVB, dst, src=I.Direct r} => encodeReg(0wx88, r, dst)
275           eBytes(0wx88 :: eImmedExt(rNum r, dst))       | I.MOVE{mvOp=I.MOVB, dst=I.Direct r, src} => encodeReg(0wx8a, r, src)
      | I.MOVE{mvOp=I.MOVB, dst=I.Direct r, src} =>  
          eBytes(0wx8a :: eImmedExt(rNum r, src))  
276       | I.MOVE{mvOp=I.MOVB, ...} => error "MOVE: MOVB"       | I.MOVE{mvOp=I.MOVB, ...} => error "MOVE: MOVB"
277       | I.MOVE{mvOp=I.MOVZBL, src=I.Immed _, ...} => error "MOVE: MOVZBL"       | I.MOVE{mvOp=I.MOVZBL, src=I.Immed _, ...} => error "MOVE: MOVZBL"
278       | I.MOVE{mvOp=I.MOVZBL, src, dst=I.Direct r} =>       | I.MOVE{mvOp=I.MOVZBL, src, dst=I.Direct r} =>
279           eBytes(0wx0f :: 0wxb6 :: eImmedExt(rNum r, src))           eBytes(0wx0f :: 0wxb6 :: eImmedExt(rNum r, src))
280       | I.MOVE _ => error "MOVE"       | I.MOVE _ => error "MOVE"
281       | I.LEA{r32, addr} => eBytes(0wx8d :: eImmedExt(rNum r32, addr))       | I.LEA{r32, addr} => encodeReg(0wx8d, r32, addr)
282       | I.CMPL{lsrc, rsrc} => arith(0wx38, 7) (rsrc, lsrc)       | I.CMPL{lsrc, rsrc} => arith(0wx38, 7) (rsrc, lsrc)
283       | (I.CMPW _ | I.CMPB _) => error "CMP"       | (I.CMPW _ | I.CMPB _) => error "CMP"
284       | I.TESTL{lsrc, rsrc} => test(32, rsrc, lsrc)       | I.TESTL{lsrc, rsrc} => test(32, rsrc, lsrc)
# Line 286  Line 287 
287       | I.BINARY{binOp, src, dst} => let       | I.BINARY{binOp, src, dst} => let
288           fun shift(code, src) =           fun shift(code, src) =
289              (case src              (case src
290               of I.Immed (1) => eBytes(0wxd1 :: eImmedExt(code, dst))               of I.Immed (1) => encode(0wxd1, code, dst)
291                | I.Immed (n) =>                | I.Immed (n) => encodeByteImm(0wxc1, code, dst, n)
                  eBytes(0wxc1 :: (eImmedExt(code, dst)@ [toWord8 n]))  
292                | I.Direct r =>                | I.Direct r =>
293                   if rNum r <> ecx then  error "shift: Direct"                   if rNum r <> ecx then  error "shift: Direct"
294                   else eBytes(0wxd3 :: eImmedExt(code, dst))                   else encode(0wxd3, code, dst)
295                | I.MemReg _ => shift(code, memReg src)                | I.MemReg _ => shift(code, memReg src)
296                | _  => error "shift"                | _  => error "shift"
297               (*esac*))               (*esac*))
# Line 310  Line 310 
310       | I.MULTDIV{multDivOp, src} => let       | I.MULTDIV{multDivOp, src} => let
311           val mulOp =           val mulOp =
312               (case multDivOp of I.MULL => 4 | I.IDIVL => 7 | I.DIVL => 6)               (case multDivOp of I.MULL => 4 | I.IDIVL => 7 | I.DIVL => 6)
313         in eBytes(0wxf7 :: eImmedExt(mulOp, src))         in encode(0wxf7, mulOp, src)
314         end         end
315       | I.MUL3{dst, src1, src2} => let       | I.MUL3{dst, src1, src2} => let
316           val dst = rNum dst           val dst = rNum dst
# Line 320  Line 320 
320              (case src1              (case src1
321               of I.Immed(i) =>               of I.Immed(i) =>
322                   (case size i                   (case size i
323                    of Bits32 =>                    of Bits32 => encodeLongImm(0wx69, dst, I.Direct(dst), i)
324                        eBytes(0wx69::(eImmedExt(dst, I.Direct(dst)) @ eLong i))                     | _ => encodeByteImm(0wx6b, dst, I.Direct(dst), i)
                    | _ =>  
                       eBytes(0wx6b::(eImmedExt(dst, I.Direct(dst)) @ [toWord8 i]))  
325                    (*esac*))                    (*esac*))
326                | _ => eBytes(0wx0f::0wxaf::(eImmedExt(dst, src1)))                | _ => eBytes(0wx0f::0wxaf::(eImmedExt(dst, src1)))
327              (*esac*))              (*esac*))
# Line 333  Line 331 
331                | I.ImmedLabel _ => error "mul3: ImmedLabel"                | I.ImmedLabel _ => error "mul3: ImmedLabel"
332                | _ =>                | _ =>
333                  (case size i                  (case size i
334                   of Bits32 => eBytes(0wx69 :: (eImmedExt(dst, src1) @ eLong(i)))                   of Bits32 => encodeLongImm(0wx69, dst, src1, i)
335                    | _ => eBytes(0wx6b :: (eImmedExt(dst, src1) @ [toWord8 i]))                    | _ => encodeByteImm(0wx6b, dst, src1, i)
336                   (*esac*))                   (*esac*))
337              (*esac*))              (*esac*))
338          (*esac*)          (*esac*)
# Line 344  Line 342 
342          of I.DECL =>          of I.DECL =>
343              (case opnd              (case opnd
344               of I.Direct d => eByte(0x48 + rNum d)               of I.Direct d => eByte(0x48 + rNum d)
345                | _ => eBytes(0wxff :: eImmedExt(1, opnd))                | _ => encode(0wxff, 1, opnd)
346               (*esac*))               (*esac*))
347           | I.INCL =>           | I.INCL =>
348              (case opnd              (case opnd
349               of I.Direct d => eByte(0x40 + rNum d)               of I.Direct d => eByte(0x40 + rNum d)
350                | _ => eBytes(0wxff :: eImmedExt(0, opnd))                | _ => encode(0wxff, 0, opnd)
351               (*esac*))               (*esac*))
352           | I.NEGL => eBytes(0wxf7 :: eImmedExt(3, opnd))           | I.NEGL => encode(0wxf7, 3, opnd)
353           | I.NOTL => eBytes(0wxf7 :: eImmedExt(2, opnd))           | I.NOTL => encode(0wxf7, 2, opnd)
354          (*esac*))          (*esac*))
355       | I.SET{cond,opnd} =>       | I.SET{cond,opnd} =>
356           eBytes(0wx0f :: Word8.+(0wx90,condCode cond) :: eImmedExt(0, opnd))           eBytes(0wx0f :: Word8.+(0wx90,condCode cond) :: eImmedExt(0, opnd))
# Line 362  Line 360 
360           | _ => eBytes[0wx6a, toWord8 i]           | _ => eBytes[0wx6a, toWord8 i]
361          (*esac*))          (*esac*))
362       | I.PUSHL(I.Direct r) => eByte(0x50+rNum r)       | I.PUSHL(I.Direct r) => eByte(0x50+rNum r)
363       | I.PUSHL opnd => eBytes(0wxff :: eImmedExt(6, opnd))       | I.PUSHL opnd => encode(0wxff, 6, opnd)
364       | I.POP(I.Direct r) => eByte(0x58+rNum r)       | I.POP(I.Direct r) => eByte(0x58+rNum r)
365       | I.POP(opnd) => eBytes(0wx8f :: eImmedExt(0, opnd))       | I.POP(opnd) => encode(0wx8f, 0, opnd)
366       | I.CDQ => eByte(0x99)       | I.CDQ => eByte(0x99)
367       | I.INTO => eByte(0xce)       | I.INTO => eByte(0xce)
368    
# Line 383  Line 381 
381         end         end
382    
383       (* floating *)       (* floating *)
384       | I.FBINARY{binOp, src=I.ST 32, dst=I.ST 33} =>       | I.FBINARY{binOp, src=I.ST src, dst=I.ST dst} =>
385           let val src = W8.fromInt(fNum src)
386               val dst = W8.fromInt(fNum dst)
387               val (opc1, opc2) =
388                case (src, dst) of
389                  (_, 0w0) =>
390         (case binOp         (case binOp
391          of I.FADDP => eBytes[0wxde, 0wxc1]                   of I.FADDL  => (0wxd8, 0wxc0 + src)
392           | I.FMULP => eBytes[0wxde, 0wxc9]                    | I.FMULL  => (0wxd8, 0wxc8 + src)
393           | I.FDIVP => eBytes[0wxde, 0wxf1]                    | I.FSUBRL => (0wxd8, 0wxe8 + src)
394           | I.FDIVRP=> eBytes[0wxde, 0wxf9]                    | I.FSUBL  => (0wxd8, 0wxe0 + src) (* gas XXX *)
395           | I.FSUBP => eBytes[0wxde, 0wxe1]                    | I.FDIVRL => (0wxd8, 0wxf8 + src)
396           | I.FSUBRP=> eBytes[0wxde, 0wxe9]                    | I.FDIVL  => (0wxd8, 0wxf0 + src) (* gas XXX *)
397                      | _        => error "FBINARY:pop:src=%st(n),dst=%st"
398           | I.FADDL  => eBytes[0wxdc, 0wxc1]                  )
399           | I.FMULL  => eBytes[0wxdc, 0wxc9]              | (0w0, _) =>
400           | I.FDIVL  => eBytes[0wxdc, 0wxf1]                  (case binOp
401           | I.FDIVRL => eBytes[0wxdc, 0wxf9]                   of I.FADDP  => (0wxde, 0wxc0 + dst)
402           | I.FSUBL  => eBytes[0wxdc, 0wxe1]                    | I.FMULP  => (0wxde, 0wxc8 + dst)
403           | I.FSUBRL => eBytes[0wxdc, 0wxe9]                    | I.FSUBRP => (0wxde, 0wxe8 + dst) (* gas XXX *)
404         (*esac*))                    | I.FSUBP  => (0wxde, 0wxe0 + dst)
405                      | I.FDIVRP => (0wxde, 0wxf8 + dst) (* gas XXX *)
406                      | I.FDIVP  => (0wxde, 0wxf0 + dst)
407    
408                      | I.FADDL  => (0wxdc, 0wxc0 + dst)
409                      | I.FMULL  => (0wxdc, 0wxc8 + dst)
410                      | I.FSUBRL => (0wxdc, 0wxe8 + dst) (* gas XXX *)
411                      | I.FSUBL  => (0wxdc, 0wxe0 + dst)
412                      | I.FDIVRL => (0wxdc, 0wxf8 + dst) (* gas XXX *)
413                      | I.FDIVL  => (0wxdc, 0wxf0 + dst)
414                    )
415                | (_, _) => error "FBINARY (src, dst) non %st(0)"
416           in  eBytes[opc1, opc2]
417           end
418       | I.FBINARY{binOp, src, dst=I.ST 32} => let       | I.FBINARY{binOp, src, dst=I.ST 32} => let
419           val (opc, code) =           val (opc, code) =
420             (case binOp of             (case binOp of
# Line 420  Line 436 
436                | I.FDIVRS => (0wxd8, 7)                | I.FDIVRS => (0wxd8, 7)
437                | _ =>  error "FBINARY:pop:dst=%st"                | _ =>  error "FBINARY:pop:dst=%st"
438             (*esac*))             (*esac*))
439           val src' =         in encode(opc, code, src)
            (case src  
             of I.FDirect f => memReg src  
              | I.ST f => I.Direct(f-fpoffset)  
              | mem => mem  
             (*esac*))  
        in eBytes(opc :: eImmedExt(code, src'))  
440         end         end
441       | I.FIBINARY{binOp, src} =>       | I.FIBINARY{binOp, src} =>
442         let val (opc, code) =         let val (opc, code) =
# Line 447  Line 457 
457               | I.FISUBRS => (0wxde, 5)               | I.FISUBRS => (0wxde, 5)
458               | I.FIDIVS  => (0wxde, 6)               | I.FIDIVS  => (0wxde, 6)
459               | I.FIDIVRS => (0wxde, 7)               | I.FIDIVRS => (0wxde, 7)
460         in  eBytes(opc :: eImmedExt(code, src)) end         in  encode(opc, code, src) end
461       | I.FUNARY unOp =>       | I.FUNARY unOp =>
462          eBytes[0wxd9,          eBytes[0wxd9,
463                 case unOp                 case unOp
# Line 456  Line 466 
466                   | I.FSQRT => 0wxfa                   | I.FSQRT => 0wxfa
467                   | I.FSIN  => 0wxfe                   | I.FSIN  => 0wxfe
468                   | I.FCOS  => 0wxff                   | I.FCOS  => 0wxff
469                   | I.FTAN  => 0wxf2                  | I.FPTAN => 0wxf2
470                   | I.FINCSTP => 0wxf7]                  | I.FPATAN => 0wxf3
471       | I.FXCH{opnd=33} => eBytes[0wxd9, 0wxc9]                  | I.FDECSTP => 0wxf6
472                    | I.FINCSTP => 0wxf7
473                   ]
474         | I.FXCH{opnd} => encodeST(0wxd9, 25, opnd)
475    
476         | I.FUCOM(I.ST n) => encodeST(0wxdd, 28, n)
477         | I.FUCOMP(I.ST n) => encodeST(0wxdd, 29, n)
478       | I.FUCOMPP => eBytes[0wxda, 0wxe9]       | I.FUCOMPP => eBytes[0wxda, 0wxe9]
479       | I.FSTPL(f as I.FDirect _) => emitInstr(I.FSTPL(memReg f), regmap)  
480       | I.FSTPL opnd => eBytes(0wxdd :: eImmedExt(3, opnd))       | I.FSTS opnd  => encode(0wxd9, 2, opnd)
481         | I.FSTL(I.ST n) => encodeST(0wxdd, 26, n)
482         | I.FSTL opnd  => encode(0wxdd, 2, opnd)
483    
484         | I.FSTPS opnd => encode(0wxd9, 3, opnd)
485         | I.FSTPL(I.ST n) => encodeST(0wxdd, 27, n)
486         | I.FSTPL opnd => encode(0wxdd, 3, opnd)
487         | I.FSTPT opnd => encode(0wxdb, 7, opnd)
488    
489       | I.FLD1 => eBytes[0wxd9,0wxe8]       | I.FLD1 => eBytes[0wxd9,0wxe8]
490         | I.FLDL2T => eBytes[0wxd9,0wxe9]
491         | I.FLDL2E => eBytes[0wxd9,0wxea]
492         | I.FLDPI  => eBytes[0wxd9,0wxeb]
493         | I.FLDLG2 => eBytes[0wxd9,0wxec]
494         | I.FLDLN2 => eBytes[0wxd9,0wxed]
495       | I.FLDZ => eBytes[0wxd9,0wxee]       | I.FLDZ => eBytes[0wxd9,0wxee]
496       | I.FLDL(f as I.FDirect _) => emitInstr(I.FLDL(memReg f), regmap)  
497       | I.FLDL opnd => eBytes(0wxdd :: eImmedExt(0, opnd))       | I.FLDL(I.ST n) => encodeST(0wxd9, 24, n)
498       | I.FILD opnd => eBytes(0wxdf :: eImmedExt(0, opnd))       | I.FLDL opnd => encode(0wxdd, 0, opnd)
499       | I.FILDL opnd => eBytes(0wxdb :: eImmedExt(0, opnd))  
500       | I.FILDLL opnd => eBytes(0wxdf :: eImmedExt(5, opnd))       | I.FILD opnd => encode(0wxdf, 0, opnd)
501         | I.FILDL opnd => encode(0wxdb, 0, opnd)
502         | I.FILDLL opnd => encode(0wxdf, 5, opnd)
503    
504       | I.FNSTSW => eBytes[0wxdf, 0wxe0]       | I.FNSTSW => eBytes[0wxdf, 0wxe0]
505    
506       (* misc *)       (* misc *)

Legend:
Removed from v.730  
changed lines
  Added in v.731

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