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/branches/idlbasis-devel/src/MLRISC/ppc/emit/ppcMC.sml
ViewVC logotype

Diff of /sml/branches/idlbasis-devel/src/MLRISC/ppc/emit/ppcMC.sml

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

revision 410, Fri Sep 3 00:25:03 1999 UTC revision 411, Fri Sep 3 00:25:03 1999 UTC
# Line 1  Line 1 
1  (* ppcMC.sml  (*
2   *   * This file was automatically generated by MDGen
3   * COPYRIGHT (c) 1999 Lucent Technologies, Bell Labs.   * from the machine description file "ppc/ppc.md".
  *  
4   *)   *)
5    
 (** IBM PPC machine code generator **)  
6    
7  functor PPCMCEmitter  functor PPCMCEmitter(structure Instr : PPCINSTR
8    (structure Instr : PPCINSTR                       structure Stream : INSTRUCTION_STREAM
9     structure PseudoOps : PSEUDO_OPS                       structure CodeString : CODE_STRING
10     structure CodeString : CODE_STRING) : EMITTER_NEW =                      ) : INSTRUCTION_EMITTER =
11  struct  struct
12    structure I = Instr    structure I = Instr
13    structure P = PseudoOps     structure S = Stream
14    structure C = I.C    structure C = I.C
15       structure Constant = I.Constant
16    structure LE = LabelExp     structure P = S.P
17       structure W = Word32
18    val << = Word.<<  
19    val >> = Word.>>     (* PPC is a big endian architecture *)
20    val ~>> = Word.~>>  
21    val ++ = Word.orb     fun error msg = MLRiscErrorMsg.error("PPCMC",msg)
22    val & = Word.andb     fun makeStream() =
23    infix << >> ~>> ++ &     let infix && || << >> ~>>
24           val op << = W.<<
25    val itow  = Word.fromInt         val op >> = W.>>
26    fun error msg = MLRiscErrorMsg.impossible ("PPCMCEmitter." ^ msg)         val op ~>> = W.~>>
27           val op || = W.orb
28           val op && = W.andb
29           val itow = W.fromInt
30           fun emit_bool false = 0w0 : W.word
31             | emit_bool true = 0w1 : W.word
32           val emit_int = itow
33           fun emit_word w = w
34           fun emit_label l = itow(Label.addrOf l)
35           fun emit_labexp le = itow(LabelExp.valueOf le)
36           fun emit_const c = itow(Constant.valueOf c)
37    val loc = ref 0    val loc = ref 0
38    
39           (* emit a byte *)
40           fun eByte b =
41           let val i = !loc in loc := i + 1; CodeString.update(i,b) end
42    
43           (* emit the low order byte of a word *)
44           (* note: fromLargeWord strips the high order bits! *)
45           fun eByteW w =
46           let val i = !loc
47           in loc := i + 1; CodeString.update(i,Word8.fromLargeWord w) end
48    
49    fun eBytefromW8 w8  = let         fun doNothing _ = ()
     val i = !loc  
   in loc := i+1; CodeString.update(i,w8)  
   end  
   
   fun eBytefromW w = let  
     val i = !loc  
     val wtob  = Word8.fromLargeWord o Word.toLargeWord  
   in loc:= i+1; CodeString.update(i, wtob w)  
   end  
   
   fun emitHiLo(hi,lo) =  
     (eBytefromW ((hi >> 0w8) & 0w255);  
      eBytefromW (hi & 0w255);  
      eBytefromW ((lo >> 0w8) & 0w255);  
      eBytefromW (lo & 0w255))  
   
   fun defineLabel lab = ()  
   fun pseudoOp pOp = P.emitValue{pOp=pOp, loc= !loc, emit=eBytefromW8}  
   fun comment msg = ()  
   fun init n = (CodeString.init n; loc:=0)  
   
   fun emitInstr(instr, regmap) = let  
     val rMap = Intmap.map regmap  
     fun rNum r = itow(rMap r)  
     val fNum = rNum  
   
     val don'tCare = 0w0  
   
     fun bitToInt(I.LT) = 0      | bitToInt(I.GT) = 1  
       | bitToInt(I.EQ) = 2      | bitToInt(I.SO) = 3  
       | bitToInt(I.FL) = 0      | bitToInt(I.FG) = 1  
       | bitToInt(I.FE) = 2      | bitToInt(I.FU) = 3  
       | bitToInt(I.FX) = 0      | bitToInt(I.FEX)= 1  
       | bitToInt(I.VX) = 2      | bitToInt(I.OX) = 3  
   
     fun cvtRc true = 0w1  
       | cvtRc false = 0w0  
   
     fun cvtOE true = 0w1  
       | cvtOE false = 0w0  
   
     fun cvtLK true = 0w1  
       | cvtLK false = 0w0  
   
     fun cvtBO I.TRUE = 0w12             (* 011zy *)  
       | cvtBO I.FALSE = 0w4             (* 001zy *)  
       | cvtBO I.ALWAYS = 0w20           (* 1z1zz *)  
       | cvtBO(I.COUNTER{eqZero, cond=NONE}) =  
          if eqZero then 0w18            (* 1z01y *)  
          else 0w16                      (* 1z00y *)  
       | cvtBO(I.COUNTER{eqZero, cond=SOME cc}) =  
         (case (eqZero, cc)  
           of (false, false) => 0w0      (* 0000y *)  
            | (false, true) => 0w8       (* 0100y *)  
            | (true, false) => 0w2       (* 0001y *)  
            | (true, true) => 0w10       (* 0101y *)  
          (*esac*))  
   
     fun cr_bit(cr, bit) = itow(cr*4 + bitToInt bit)  
   
     local  
       fun split i = let  
             val w = Word.fromInt i  
             val hi = Word.~>>(w, 0w16)  
             val lo = Word.andb(w, 0w65535)  
       in if lo <  0w32768 then (hi, lo) else (hi+0w1, lo-0w65536)  
       end  
     in  
       fun high n = #1 (split n)  
       fun low n  = #2 (split n)  
     end  
   
   
     fun operand(I.RegOp r) = error "operand:RegOp"  
       | operand(I.ConstOp c) = error "operand:ConstOp"  
       | operand(I.ImmedOp i) = itow i  
       | operand(I.LabelOp lexp) = itow(LE.valueOf lexp)  
   
     fun relative (I.LabelOp lexp) = itow((LE.valueOf lexp - (!loc)) div 4)  
       | relative _ = error "relative"  
   
     fun d_form(opcd,rt,ra,si) = let  
       val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra  
       val lo = si  
     in emitHiLo(hi,lo)  
     end  
   
     fun b_form(opcd,bo,bi,bd,aa,lk) = let  
       val hi = (opcd << 0w10) ++ (bo << 0w5) ++ bi  
       val lo = (bd << 0w2) ++ (aa << 0w1) ++ lk  
     in emitHiLo(hi,lo)  
     end  
   
     fun x_form(opcd,rt,ra,rb,eo,rc) = let  
       val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra  
       val lo = (rb << 0w11) ++ (eo << 0w1) ++ rc  
     in emitHiLo(hi,lo)  
     end  
   
     fun xl_form(opcd,bt,ba,bb,eo,lk) = let  
       val hi = (opcd << 0w10) ++ (bt << 0w5) ++ ba  
       val lo = (bb << 0w11) ++ (eo << 0w1) ++ lk  
     in emitHiLo(hi,lo)  
     end  
50    
51      fun xo_form(opcd,rt,ra,rb,oe,eo',rc) = let         fun pseudoOp pOp = P.emitValue{pOp=pOp, loc= !loc,emit=eByte}
       val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra  
       val lo = (rb << 0w11) ++ (oe << 0w10) ++ (eo' << 0w1) ++ rc  
     in emitHiLo(hi,lo)  
     end  
52    
53      fun a_form(opcd,frt,fra,frb,frc,xo,rc) = let         fun init n = (CodeString.init n; loc := 0)
       val hi = (opcd << 0w10) ++ (frt << 0w5) ++ fra  
       val lo = (frb <<0w11) ++ (frc <<0w6) ++ (xo <<0w1) ++ rc  
     in emitHiLo(hi,lo)  
     end  
54    
     fun m_form(opcd,rs,ra,rb,mb,me,rc) = let  
       val hi = (opcd << 0w10) ++ (rs << 0w5) ++ ra  
       val lo = (rb << 0w11) ++ (itow mb << 0w6) ++ (itow me << 0w1) ++ rc  
     in emitHiLo(hi,lo)  
     end  
55    
56      fun ds_form(opcd, rt, ra, ds, xo) = let         fun emitter regmap =
57        val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra         let
       val lo = (ds << 0w2) ++ xo  
     in emitHiLo(hi, lo)  
     end  
58    
59      fun xfx_form(opcd, rs, spr, xo, LK) = let     fun eWord32 w = let
60        val hi = (opcd << 0w10) ++ (rs << 0w5) ++ (spr & 0wx1f)            val b8 = w
61        val lo = ((spr >> 0w5) << 0w11) ++ (xo << 0w1) ++ LK            val w = (w >> 0wx8)
62      in emitHiLo(hi, lo)            val b16 = w
63              val w = (w >> 0wx8)
64              val b24 = w
65              val w = (w >> 0wx8)
66              val b32 = w
67           in
68              ((eByteW b32);
69              (eByteW b24);
70              (eByteW b16);
71              (eByteW b8))
72           end
73    
74    
75       fun emit_SPR r = (itow ((regmap r) - 72))
76       and emit_CC r = (itow ((regmap r) - 64))
77       and emit_GP r = (itow (regmap r))
78       and emit_FP r = (itow ((regmap r) - 32))
79    
80       fun emit_bo (I.TRUE) = (0wxc : Word32.word)
81         | emit_bo (I.FALSE) = (0wx4 : Word32.word)
82         | emit_bo (I.ALWAYS) = (0wx14 : Word32.word)
83         | emit_bo (I.COUNTER{eqZero, cond}) =
84           (
85            case cond of
86            NONE => (if eqZero
87               then 0wx12
88               else 0wx10)
89          | SOME cc =>
90            (
91             case (eqZero, cc) of
92             (false, false) => 0wx0
93           | (false, true) => 0wx8
94           | (true, false) => 0wx2
95           | (true, true) => 0wxa
96            )
97           )
98       and emit_arithi (I.ADDI) = (0wxe : Word32.word)
99         | emit_arithi (I.ADDIS) = (0wxf : Word32.word)
100         | emit_arithi (I.SUBFIC) = (0wx8 : Word32.word)
101         | emit_arithi (I.MULLI) = (0wx7 : Word32.word)
102         | emit_arithi (I.ANDI_Rc) = (0wx1c : Word32.word)
103         | emit_arithi (I.ANDIS_Rc) = (0wx1d : Word32.word)
104         | emit_arithi (I.ORI) = (0wx18 : Word32.word)
105         | emit_arithi (I.ORIS) = (0wx19 : Word32.word)
106         | emit_arithi (I.XORI) = (0wx1a : Word32.word)
107         | emit_arithi (I.XORIS) = (0wx1b : Word32.word)
108         | emit_arithi (I.SRAWI) = (error "SRAWI")
109         | emit_arithi (I.SRADI) = (error "SRADI")
110       and emit_farith3 (I.FMADD) = (0wx3f, 0wx1d)
111         | emit_farith3 (I.FMADDS) = (0wx3b, 0wx1d)
112         | emit_farith3 (I.FMSUB) = (0wx3f, 0wx1c)
113         | emit_farith3 (I.FMSUBS) = (0wx3b, 0wx1c)
114         | emit_farith3 (I.FNMADD) = (0wx3f, 0wx1f)
115         | emit_farith3 (I.FNMADDS) = (0wx3b, 0wx1f)
116         | emit_farith3 (I.FNMSUB) = (0wx3f, 0wx1e)
117         | emit_farith3 (I.FNMSUBS) = (0wx3b, 0wx1e)
118         | emit_farith3 (I.FSEL) = (0wx3f, 0wx17)
119       and emit_farith (I.FADD) = (0wx3f, 0wx15)
120         | emit_farith (I.FSUB) = (0wx3f, 0wx14)
121         | emit_farith (I.FMUL) = (0wx3f, 0wx19)
122         | emit_farith (I.FDIV) = (0wx3f, 0wx12)
123         | emit_farith (I.FADDS) = (0wx3b, 0wx15)
124         | emit_farith (I.FSUBS) = (0wx3b, 0wx14)
125         | emit_farith (I.FMULS) = (0wx3b, 0wx19)
126         | emit_farith (I.FDIVS) = (0wx3b, 0wx12)
127       and emit_arith (I.ADD) = (0wx10a : Word32.word)
128         | emit_arith (I.SUBF) = (0wx28 : Word32.word)
129         | emit_arith (I.MULLW) = (0wxeb : Word32.word)
130         | emit_arith (I.MULLD) = (0wxe9 : Word32.word)
131         | emit_arith (I.MULHW) = (0wx4b : Word32.word)
132         | emit_arith (I.MULHWU) = (0wxb : Word32.word)
133         | emit_arith (I.DIVW) = (0wx1eb : Word32.word)
134         | emit_arith (I.DIVD) = (0wx1e9 : Word32.word)
135         | emit_arith (I.DIVWU) = (0wx1cb : Word32.word)
136         | emit_arith (I.DIVDU) = (0wx1c9 : Word32.word)
137         | emit_arith (I.AND) = (0wx1c : Word32.word)
138         | emit_arith (I.OR) = (0wx1bc : Word32.word)
139         | emit_arith (I.XOR) = (0wx13c : Word32.word)
140         | emit_arith (I.NAND) = (0wx1dc : Word32.word)
141         | emit_arith (I.NOR) = (0wx7c : Word32.word)
142         | emit_arith (I.EQV) = (0wx11c : Word32.word)
143         | emit_arith (I.ANDC) = (0wx3c : Word32.word)
144         | emit_arith (I.ORC) = (0wx19c : Word32.word)
145         | emit_arith (I.SLW) = (0wx18 : Word32.word)
146         | emit_arith (I.SLD) = (0wx1b : Word32.word)
147         | emit_arith (I.SRW) = (0wx218 : Word32.word)
148         | emit_arith (I.SRD) = (0wx21b : Word32.word)
149         | emit_arith (I.SRAW) = (0wx318 : Word32.word)
150         | emit_arith (I.SRAD) = (0wx31a : Word32.word)
151       and emit_fcmp (I.FCMPO) = (0wx20 : Word32.word)
152         | emit_fcmp (I.FCMPU) = (0wx0 : Word32.word)
153       and emit_ccarith (I.CRAND) = (0wx101 : Word32.word)
154         | emit_ccarith (I.CROR) = (0wx1c1 : Word32.word)
155         | emit_ccarith (I.CRXOR) = (0wxc1 : Word32.word)
156         | emit_ccarith (I.CRNAND) = (0wxe1 : Word32.word)
157         | emit_ccarith (I.CRNOR) = (0wx21 : Word32.word)
158         | emit_ccarith (I.CREQV) = (0wx121 : Word32.word)
159         | emit_ccarith (I.CRANDC) = (0wx81 : Word32.word)
160         | emit_ccarith (I.CRORC) = (0wx1a1 : Word32.word)
161       and emit_funary (I.FMR) = (0wx3f, 0wx48)
162         | emit_funary (I.FNEG) = (0wx3f, 0wx28)
163         | emit_funary (I.FABS) = (0wx3f, 0wx108)
164         | emit_funary (I.FNABS) = (0wx3f, 0wx88)
165         | emit_funary (I.FSQRT) = (0wx3f, 0wx16)
166         | emit_funary (I.FSQRTS) = (0wx3b, 0wx16)
167         | emit_funary (I.FRSP) = (0wx3f, 0wxc)
168         | emit_funary (I.FCTIW) = (0wx3f, 0wxe)
169         | emit_funary (I.FCTIWZ) = (0wx3f, 0wxf)
170         | emit_funary (I.FCTID) = (0wx3f, 0wx32e)
171         | emit_funary (I.FCTIDZ) = (0wx3f, 0wx32f)
172         | emit_funary (I.FCFID) = (0wx3f, 0wx34e)
173       and emit_operand (I.RegOp GP) = (emit_GP GP)
174         | emit_operand (I.ImmedOp int) = (itow int)
175         | emit_operand (I.LabelOp labexp) = (itow (LabelExp.valueOf labexp))
176         | emit_operand (I.ConstOp const) = (itow (Constant.valueOf const))
177       and emit_unary (I.NEG) = (0wx68 : Word32.word)
178         | emit_unary (I.EXTSB) = (0wx3ba : Word32.word)
179         | emit_unary (I.EXTSH) = (0wx39a : Word32.word)
180         | emit_unary (I.EXTSW) = (0wx3da : Word32.word)
181         | emit_unary (I.CNTLZW) = (0wx1a : Word32.word)
182         | emit_unary (I.CNTLZD) = (0wx3a : Word32.word)
183    
184       fun arithi' {oper, rt, ra, im} = let
185              val oper = (emit_arithi oper)
186              val rt = (emit_GP rt)
187              val ra = (emit_GP ra)
188              val im = (emit_operand im)
189           in (eWord32 ((im && 0wxffff) + ((ra << 0wx10) + ((rt << 0wx15) + (oper << 0wx1a)))))
190           end
191    
192       and loadde {opcd, rt, ra, de, xop} = let
193              val rt = (emit_GP rt)
194              val ra = (emit_GP ra)
195              val de = (emit_operand de)
196           in (eWord32 (xop + (((de && 0wxfff) << 0wx4) + ((ra << 0wx10) + ((rt << 0wx15) + (opcd << 0wx1a))))))
197           end
198    
199       and tdi {to, ra, si} = let
200              val to = (emit_int to)
201              val ra = (emit_GP ra)
202              val si = (emit_operand si)
203           in (eWord32 ((si && 0wxffff) + ((ra << 0wx10) + ((to << 0wx15) + 0wx8000000))))
204           end
205    
206       and stored {opcd, rs, ra, d} = let
207              val rs = (emit_GP rs)
208              val ra = (emit_GP ra)
209              val d = (emit_operand d)
210           in (eWord32 ((d && 0wxffff) + ((ra << 0wx10) + ((rs << 0wx15) + (opcd << 0wx1a)))))
211           end
212    
213       and twi {to, ra, si} = let
214              val to = (emit_int to)
215              val ra = (emit_GP ra)
216              val si = (emit_operand si)
217           in (eWord32 ((si && 0wxffff) + ((ra << 0wx10) + ((to << 0wx15) + 0wxc000000))))
218           end
219    
220       and floadd {opcd, ft, ra, d} = let
221              val ft = (emit_FP ft)
222              val ra = (emit_GP ra)
223              val d = (emit_operand d)
224           in (eWord32 ((d && 0wxffff) + ((ra << 0wx10) + ((ft << 0wx15) + (opcd << 0wx1a)))))
225           end
226    
227       and tdr {to, ra, rb} = let
228              val to = (emit_int to)
229              val ra = (emit_GP ra)
230              val rb = (emit_GP rb)
231           in (eWord32 ((rb << 0wxb) + ((ra << 0wx10) + ((to << 0wx15) + 0wx7c000088))))
232           end
233    
234       and loadd {opcd, rt, ra, d} = let
235              val rt = (emit_GP rt)
236              val ra = (emit_GP ra)
237              val d = (emit_operand d)
238           in (eWord32 ((d && 0wxffff) + ((ra << 0wx10) + ((rt << 0wx15) + (opcd << 0wx1a)))))
239           end
240    
241       and twr {to, ra, rb} = let
242              val to = (emit_int to)
243              val ra = (emit_GP ra)
244              val rb = (emit_GP rb)
245           in (eWord32 ((rb << 0wxb) + ((ra << 0wx10) + ((to << 0wx15) + 0wx7c000008))))
246           end
247    
248       and Cmpli {bf, l, ra, ui} = let
249              val bf = (emit_CC bf)
250              val l = (emit_bool l)
251              val ra = (emit_GP ra)
252              val ui = (emit_operand ui)
253           in (eWord32 ((ui && 0wxffff) + ((ra << 0wx10) + ((l << 0wx15) + ((bf << 0wx17) + 0wx28000000)))))
254           end
255    
256       and td {to, ra, si} =
257           (
258            case si of
259            I.RegOp rb => (tdr {to=to, ra=ra, rb=rb})
260          | _ => (tdi {to=to, ra=ra, si=si})
261           )
262       and rldcl {rs, ra, sh, mb} = let
263              val rs = (emit_GP rs)
264              val ra = (emit_GP ra)
265              val sh = (emit_GP sh)
266              val mb = (emit_int mb)
267           in (eWord32 ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx78000010)))))
268           end
269    
270       and farith3 {oper, ft, fa, fc, fb, Rc} = let
271              val oper = (emit_farith3 oper)
272              val ft = (emit_FP ft)
273              val fa = (emit_FP fa)
274              val fc = (emit_FP fc)
275              val fb = (emit_FP fb)
276           in let
277    
278    (*#line 448.1 "ppc/ppc.md"*)
279                 val(opcd, xo) = oper
280              in (a_form {opcd=opcd, frt=ft, fra=fa, frb=fb, frc=fc, xo=xo, rc=Rc})
281              end
282    
283           end
284    
285       and bce {bo, bi, bd, aa, lk} = let
286              val bo = (emit_bo bo)
287              val aa = (emit_bool aa)
288              val lk = (emit_bool lk)
289           in (eWord32 (lk + ((aa << 0wx1) + (((bd && 0wx3fff) << 0wx2) + ((bi << 0wx10) + ((bo << 0wx15) + 0wx40000000))))))
290           end
291    
292       and rlwimi {rs, ra, sh, mb, me} = let
293              val rs = (emit_GP rs)
294              val ra = (emit_GP ra)
295              val mb = (emit_int mb)
296              val me = (emit_int me)
297           in (eWord32 ((me << 0wx1) + ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx50000000))))))
298           end
299    
300       and storex {rs, ra, rb, xop} = let
301              val rs = (emit_GP rs)
302              val ra = (emit_GP ra)
303              val rb = (emit_GP rb)
304           in (eWord32 ((xop << 0wx1) + ((rb << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx7c000000)))))
305           end
306    
307       and ccarith {oper, bt, ba, bb} = let
308              val oper = (emit_ccarith oper)
309           in (xl_form {opcd=0wx13, bt=(cr_bit {cc=bt}), ba=(cr_bit {cc=ba}), bb=(cr_bit {cc=bb}), xo=oper, lk=false})
310           end
311    
312       and rldcr {rs, ra, sh, mb} = let
313              val rs = (emit_GP rs)
314              val ra = (emit_GP ra)
315              val sh = (emit_GP sh)
316              val mb = (emit_int mb)
317           in (eWord32 ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx78000012)))))
318           end
319    
320       and rotate {oper, ra, rs, sh, mb, me} =
321           (
322            case (oper, me) of
323            (I.RLWNM, SOME me) => (rlwnm {ra=ra, rs=rs, sh=sh, mb=mb, me=me})
324          | (I.RLDCL, _) => (rldcl {ra=ra, rs=rs, sh=sh, mb=mb})
325          | (I.RLDCR, _) => (rldcr {ra=ra, rs=rs, sh=sh, mb=mb})
326           )
327       and sradi' {rs, ra, sh, sh2} = let
328              val rs = (emit_GP rs)
329              val ra = (emit_GP ra)
330           in (eWord32 ((sh2 << 0wx1) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx7c000674)))))
331           end
332    
333       and floadx {ft, ra, rb, xop} = let
334              val ft = (emit_FP ft)
335              val ra = (emit_GP ra)
336              val rb = (emit_GP rb)
337           in (eWord32 ((xop << 0wx1) + ((rb << 0wxb) + ((ra << 0wx10) + ((ft << 0wx15) + 0wx7c000000)))))
338           end
339    
340       and unary' {ra, rt, OE, oper, Rc} = let
341              val ra = (emit_GP ra)
342              val rt = (emit_GP rt)
343              val OE = (emit_bool OE)
344              val oper = (emit_unary oper)
345              val Rc = (emit_bool Rc)
346           in (eWord32 (Rc + ((oper << 0wx1) + ((OE << 0wxa) + ((rt << 0wx10) + ((ra << 0wx15) + 0wx7c000000))))))
347           end
348    
349       and loadx {rt, ra, rb, xop} = let
350              val rt = (emit_GP rt)
351              val ra = (emit_GP ra)
352              val rb = (emit_GP rb)
353           in (eWord32 ((xop << 0wx1) + ((rb << 0wxb) + ((ra << 0wx10) + ((rt << 0wx15) + 0wx7c000000)))))
354           end
355    
356       and bclre {bo, bi, lk} = let
357              val bo = (emit_bo bo)
358              val lk = (emit_bool lk)
359           in (eWord32 (lk + ((bi << 0wx10) + ((bo << 0wx15) + 0wx4c000022))))
360           end
361    
362       and arithi {oper, rt, ra, im} =
363           (
364            case oper of
365            (I.ADDI|I.ADDIS|I.SUBFIC|I.MULLI) => (arithi' {oper=oper, rt=rt, ra=ra, im=im})
366          | I.SRAWI => (srawi {rs=ra, ra=rt, sh=im})
367          | I.SRADI => (sradi {rs=ra, ra=rt, sh=im})
368          | _ => (arithi' {oper=oper, rt=ra, ra=rt, im=im})
369           )
370       and x_form {opcd, rt, ra, rb, xo, rc} = let
371              val rc = (emit_bool rc)
372           in (eWord32 (rc + ((xo << 0wx1) + ((rb << 0wxb) + ((ra << 0wx10) + ((rt << 0wx15) + (opcd << 0wx1a)))))))
373           end
374    
375       and tw {to, ra, si} =
376           (
377            case si of
378            I.RegOp rb => (twr {to=to, ra=ra, rb=rb})
379          | _ => (twi {to=to, ra=ra, si=si})
380           )
381       and mtspr {rs, spr} = let
382              val spr = (emit_SPR spr)
383           in (mtspr' {rs=rs, spr=(((spr && 0wx1f) << 0wx5) + ((spr >> 0wx5)&& 0wx1f))})
384           end
385    
386       and sradi {rs, ra, sh} = let
387              val sh = (emit_operand sh)
388           in (sradi' {rs=rs, ra=ra, sh=(sh && 0wx1f), sh2=((sh >> 0wx5)&& 0wx1)})
389           end
390    
391       and bc {bo, bi, bd, aa, lk} = let
392              val bo = (emit_bo bo)
393              val aa = (emit_bool aa)
394              val lk = (emit_bool lk)
395           in (eWord32 (lk + ((aa << 0wx1) + (((bd && 0wx3fff) << 0wx2) + ((bi << 0wx10) + ((bo << 0wx15) + 0wx40000000))))))
396           end
397    
398       and fcmp {bf, fa, fb, cmp} = let
399              val bf = (emit_CC bf)
400              val fa = (emit_FP fa)
401              val fb = (emit_FP fb)
402              val cmp = (emit_fcmp cmp)
403           in (eWord32 ((cmp << 0wx1) + ((fb << 0wxb) + ((fa << 0wx10) + ((bf << 0wx17) + 0wxfc000000)))))
404           end
405    
406       and srawi {rs, ra, sh} = let
407              val rs = (emit_GP rs)
408              val ra = (emit_GP ra)
409              val sh = (emit_operand sh)
410           in (eWord32 (((sh && 0wx1f) << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx7c000670))))
411           end
412    
413       and xl_form {opcd, bt, ba, bb, xo, lk} = let
414              val lk = (emit_bool lk)
415           in (eWord32 (lk + ((xo << 0wx1) + ((bb << 0wxb) + ((ba << 0wx10) + ((bt << 0wx15) + (opcd << 0wx1a)))))))
416           end
417    
418       and be {li, aa, lk} = let
419              val aa = (emit_bool aa)
420              val lk = (emit_bool lk)
421           in (eWord32 (lk + ((aa << 0wx1) + (((li && 0wxffffff) << 0wx2) + 0wx58000000))))
422           end
423    
424       and mfspr' {rt, spr} = let
425              val rt = (emit_GP rt)
426           in (eWord32 ((spr << 0wxb) + ((rt << 0wx15) + 0wx7c0002a6)))
427           end
428    
429       and load {ld, rt, ra, d} =
430           (
431            case (d, ld) of
432            (I.RegOp rb, I.LBZ) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx57})
433          | (I.RegOp rb, I.LBZE) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx5f})
434          | (I.RegOp rb, I.LHZ) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx117})
435          | (I.RegOp rb, I.LHZE) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx11f})
436          | (I.RegOp rb, I.LHA) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx157})
437          | (I.RegOp rb, I.LHAE) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx15f})
438          | (I.RegOp rb, I.LWZ) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx17})
439          | (I.RegOp rb, I.LWZE) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx1f})
440          | (I.RegOp rb, I.LDE) => (loadx {rt=rt, ra=ra, rb=rb, xop=0wx31f})
441          | (d, I.LBZ) => (loadd {opcd=0wx22, rt=rt, ra=ra, d=d})
442          | (de, I.LBZE) => (loadde {opcd=0wx3a, rt=rt, ra=ra, de=de, xop=0wx0})
443          | (d, I.LHZ) => (loadd {opcd=0wx28, rt=rt, ra=ra, d=d})
444          | (de, I.LHZE) => (loadde {opcd=0wx3a, rt=rt, ra=ra, de=de, xop=0wx2})
445          | (d, I.LHA) => (loadd {opcd=0wx2a, rt=rt, ra=ra, d=d})
446          | (de, I.LHAE) => (loadde {opcd=0wx3a, rt=rt, ra=ra, de=de, xop=0wx4})
447          | (d, I.LWZ) => (loadd {opcd=0wx20, rt=rt, ra=ra, d=d})
448          | (de, I.LWZE) => (loadde {opcd=0wx3a, rt=rt, ra=ra, de=de, xop=0wx6})
449          | (de, I.LDE) => (loadde {opcd=0wx3e, rt=rt, ra=ra, de=de, xop=0wx0})
450           )
451       and cr_bit {cc} = let
452    
453    (*#line 453.1 "ppc/ppc.md"*)
454              val(cr, bit) = cc
455           in (((emit_CC cr) << 0wx2) + (itow
456              (
457               case bit of
458               I.LT => 0
459             | I.GT => 1
460             | I.EQ => 2
461             | I.SO => 3
462             | I.FL => 0
463             | I.FG => 1
464             | I.FE => 2
465             | I.FU => 3
466             | I.FX => 0
467             | I.FEX => 1
468             | I.VX => 2
469             | I.OX => 3
470              )))
471           end
472    
473       and fstore {st, fs, ra, d} =
474           (
475            case (d, st) of
476            (I.RegOp rb, I.STFS) => (fstorex {fs=fs, ra=ra, rb=rb, xop=0wx297})
477          | (I.RegOp rb, I.STFSE) => (fstorex {fs=fs, ra=ra, rb=rb, xop=0wx29f})
478          | (I.RegOp rb, I.STFD) => (fstorex {fs=fs, ra=ra, rb=rb, xop=0wx2d7})
479          | (I.RegOp rb, I.STFDE) => (fstorex {fs=fs, ra=ra, rb=rb, xop=0wx2f7})
480          | (d, I.STFS) => (fstored {fs=fs, ra=ra, d=d, opcd=0wx34})
481          | (de, I.STFSE) => (fstorede {fs=fs, ra=ra, de=de, opcd=0wx3e, xop=0wxc})
482          | (d, I.STFD) => (fstored {fs=fs, ra=ra, d=d, opcd=0wx36})
483          | (de, I.STFDE) => (fstorede {fs=fs, ra=ra, de=de, opcd=0wx3e, xop=0wxe})
484           )
485       and store {st, rs, ra, d} =
486           (
487            case (d, st) of
488            (I.RegOp rb, I.STB) => (storex {rs=rs, ra=ra, rb=rb, xop=0wxd7})
489          | (I.RegOp rb, I.STBE) => (storex {rs=rs, ra=ra, rb=rb, xop=0wxdf})
490          | (I.RegOp rb, I.STH) => (storex {rs=rs, ra=ra, rb=rb, xop=0wx197})
491          | (I.RegOp rb, I.STHE) => (storex {rs=rs, ra=ra, rb=rb, xop=0wx19f})
492          | (I.RegOp rb, I.STW) => (storex {rs=rs, ra=ra, rb=rb, xop=0wx97})
493          | (I.RegOp rb, I.STWE) => (storex {rs=rs, ra=ra, rb=rb, xop=0wx9f})
494          | (I.RegOp rb, I.STDE) => (storex {rs=rs, ra=ra, rb=rb, xop=0wx39f})
495          | (d, I.STB) => (stored {rs=rs, ra=ra, d=d, opcd=0wx26})
496          | (de, I.STBE) => (storede {rs=rs, ra=ra, de=de, opcd=0wx3a, xop=0wx8})
497          | (d, I.STH) => (stored {rs=rs, ra=ra, d=d, opcd=0wx2c})
498          | (de, I.STHE) => (storede {rs=rs, ra=ra, de=de, opcd=0wx3a, xop=0wxa})
499          | (d, I.STW) => (stored {rs=rs, ra=ra, d=d, opcd=0wx24})
500          | (de, I.STWE) => (storede {rs=rs, ra=ra, de=de, opcd=0wx3a, xop=0wxe})
501          | (de, I.STDE) => (storede {rs=rs, ra=ra, de=de, opcd=0wx3e, xop=0wx8})
502           )
503       and storede {opcd, rs, ra, de, xop} = let
504              val rs = (emit_GP rs)
505              val ra = (emit_GP ra)
506              val de = (emit_operand de)
507           in (eWord32 (xop + (((de && 0wxfff) << 0wx4) + ((ra << 0wx10) + ((rs << 0wx15) + (opcd << 0wx1a))))))
508           end
509    
510       and rlwinm {rs, ra, sh, mb, me} = let
511              val rs = (emit_GP rs)
512              val ra = (emit_GP ra)
513              val mb = (emit_int mb)
514              val me = (emit_int me)
515           in (eWord32 ((me << 0wx1) + ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx54000000))))))
516           end
517    
518       and fload {ld, ft, ra, d} =
519           (
520            case (d, ld) of
521            (I.RegOp rb, I.LFS) => (floadx {ft=ft, ra=ra, rb=rb, xop=0wx217})
522          | (I.RegOp rb, I.LFSE) => (floadx {ft=ft, ra=ra, rb=rb, xop=0wx21f})
523          | (I.RegOp rb, I.LFD) => (floadx {ft=ft, ra=ra, rb=rb, xop=0wx257})
524          | (I.RegOp rb, I.LFDE) => (floadx {ft=ft, ra=ra, rb=rb, xop=0wx25f})
525          | (d, I.LFS) => (floadd {ft=ft, ra=ra, d=d, opcd=0wx30})
526          | (de, I.LFSE) => (floadde {ft=ft, ra=ra, de=de, opcd=0wx3e, xop=0wx4})
527          | (d, I.LFD) => (floadd {ft=ft, ra=ra, d=d, opcd=0wx32})
528          | (de, I.LFDE) => (floadde {ft=ft, ra=ra, de=de, opcd=0wx3e, xop=0wx6})
529           )
530       and floadde {opcd, ft, ra, de, xop} = let
531              val ft = (emit_FP ft)
532              val ra = (emit_GP ra)
533              val de = (emit_operand de)
534           in (eWord32 (xop + (((de && 0wxfff) << 0wx4) + ((ra << 0wx10) + ((ft << 0wx15) + (opcd << 0wx1a))))))
535           end
536    
537       and fstored {opcd, fs, ra, d} = let
538              val fs = (emit_FP fs)
539              val ra = (emit_GP ra)
540              val d = (emit_operand d)
541           in (eWord32 ((d && 0wxffff) + ((ra << 0wx10) + ((fs << 0wx15) + (opcd << 0wx1a)))))
542           end
543    
544       and rlwnm {rs, ra, sh, mb, me} = let
545              val rs = (emit_GP rs)
546              val ra = (emit_GP ra)
547              val sh = (emit_GP sh)
548              val mb = (emit_int mb)
549              val me = (emit_int me)
550           in (eWord32 ((me << 0wx1) + ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx5c000000))))))
551           end
552    
553       and rldicl {rs, ra, sh, mb, sh2} = let
554              val rs = (emit_GP rs)
555              val ra = (emit_GP ra)
556              val mb = (emit_int mb)
557           in (eWord32 ((sh2 << 0wx1) + ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx78000000))))))
558           end
559    
560       and fstorede {opcd, fs, ra, de, xop} = let
561              val fs = (emit_FP fs)
562              val ra = (emit_GP ra)
563              val de = (emit_operand de)
564           in (eWord32 (xop + (((de && 0wxfff) << 0wx4) + ((ra << 0wx10) + ((fs << 0wx15) + (opcd << 0wx1a))))))
565           end
566    
567       and mtspr' {rs, spr} = let
568              val rs = (emit_GP rs)
569           in (eWord32 ((spr << 0wxb) + ((rs << 0wx15) + 0wx7c0003a6)))
570           end
571    
572       and farith {oper, ft, fa, fb, Rc} = let
573              val ft = (emit_FP ft)
574              val fa = (emit_FP fa)
575              val fb = (emit_FP fb)
576           in let
577    
578    (*#line 439.1 "ppc/ppc.md"*)
579                 val(opcd, xo) = (emit_farith oper)
580              in
581                 (
582                  case oper of
583                  (I.FMUL|I.FMULS) => (a_form {opcd=opcd, frt=ft, fra=fa, frb=0wx0, frc=fb, xo=xo, rc=Rc})
584                | _ => (a_form {opcd=opcd, frt=ft, fra=fa, frb=fb, frc=0wx0, xo=xo, rc=Rc})
585                 )
586              end
587    
588           end
589    
590       and arith' {rt, ra, rb, OE, oper, Rc} = let
591              val rt = (emit_GP rt)
592              val ra = (emit_GP ra)
593              val rb = (emit_GP rb)
594              val OE = (emit_bool OE)
595              val oper = (emit_arith oper)
596              val Rc = (emit_bool Rc)
597           in (eWord32 (Rc + ((oper << 0wx1) + ((OE << 0wxa) + ((rb << 0wxb) + ((ra << 0wx10) + ((rt << 0wx15) + 0wx7c000000)))))))
598           end
599    
600       and rldicr {rs, ra, sh, mb, sh2} = let
601              val rs = (emit_GP rs)
602              val ra = (emit_GP ra)
603              val mb = (emit_int mb)
604           in (eWord32 ((sh2 << 0wx1) + ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx78000004))))))
605           end
606    
607       and mfspr {rt, spr} = let
608              val spr = (emit_SPR spr)
609           in (mfspr' {rt=rt, spr=(((spr && 0wx1f) << 0wx5) + ((spr >> 0wx5)&& 0wx1f))})
610           end
611    
612       and arith {oper, rt, ra, rb, OE, Rc} =
613           (
614            case oper of
615            (I.ADD|I.SUBF|I.MULLW|I.MULLD|I.MULHW|I.MULHWU|I.DIVW|I.DIVD|I.DIVWU|I.DIVDU) => (arith' {oper=oper, rt=rt, ra=ra, rb=rb, OE=OE, Rc=Rc})
616          | _ => (arith' {oper=oper, rt=ra, ra=rt, rb=rb, OE=OE, Rc=Rc})
617           )
618       and bcctre {bo, bi, lk} = let
619              val bo = (emit_bo bo)
620              val lk = (emit_bool lk)
621           in (eWord32 (lk + ((bi << 0wx10) + ((bo << 0wx15) + 0wx4c000422))))
622           end
623    
624       and mcrf {bf, bfa} = let
625              val bf = (emit_CC bf)
626              val bfa = (emit_CC bfa)
627           in (eWord32 ((bfa << 0wx12) + ((bf << 0wx17) + 0wx4c000000)))
628           end
629    
630       and rotatei {oper, ra, rs, sh, mb, me} = let
631              val sh = (emit_operand sh)
632           in
633              (
634               case (oper, me) of
635               (I.RLWINM, SOME me) => (rlwinm {ra=ra, rs=rs, sh=sh, mb=mb, me=me})
636             | (I.RLWIMI, SOME me) => (rlwimi {ra=ra, rs=rs, sh=sh, mb=mb, me=me})
637             | (I.RLDICL, _) => (rldicl {ra=ra, rs=rs, sh=(sh && 0wx1f), sh2=((sh >> 0wx5)&& 0wx1), mb=mb})
638             | (I.RLDICR, _) => (rldicr {ra=ra, rs=rs, sh=(sh && 0wx1f), sh2=((sh >> 0wx5)&& 0wx1), mb=mb})
639             | (I.RLDIC, _) => (rldic {ra=ra, rs=rs, sh=(sh && 0wx1f), sh2=((sh >> 0wx5)&& 0wx1), mb=mb})
640             | (I.RLDIMI, _) => (rldimi {ra=ra, rs=rs, sh=(sh && 0wx1f), sh2=((sh >> 0wx5)&& 0wx1), mb=mb})
641              )
642           end
643    
644       and rldimi {rs, ra, sh, mb, sh2} = let
645              val rs = (emit_GP rs)
646              val ra = (emit_GP ra)
647              val mb = (emit_int mb)
648           in (eWord32 ((sh2 << 0wx1) + ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx7800000c))))))
649           end
650    
651       and fstorex {fs, ra, rb, xop} = let
652              val fs = (emit_FP fs)
653              val ra = (emit_GP ra)
654              val rb = (emit_GP rb)
655           in (eWord32 ((xop << 0wx1) + ((rb << 0wxb) + ((ra << 0wx10) + ((fs << 0wx15) + 0wx7c000000)))))
656           end
657    
658       and bcctr {bo, bi, lk} = let
659              val bo = (emit_bo bo)
660              val lk = (emit_bool lk)
661           in (eWord32 (lk + ((bi << 0wx10) + ((bo << 0wx15) + 0wx4c000420))))
662           end
663    
664       and Cmp {bf, l, ra, rb} = let
665              val bf = (emit_CC bf)
666              val l = (emit_bool l)
667              val ra = (emit_GP ra)
668              val rb = (emit_GP rb)
669           in (eWord32 ((rb << 0wxb) + ((ra << 0wx10) + ((l << 0wx15) + ((bf << 0wx17) + 0wx7c000000)))))
670           end
671    
672       and Cmpi {bf, l, ra, si} = let
673              val bf = (emit_CC bf)
674              val l = (emit_bool l)
675              val ra = (emit_GP ra)
676              val si = (emit_operand si)
677           in (eWord32 ((si && 0wxffff) + ((ra << 0wx10) + ((l << 0wx15) + ((bf << 0wx17) + 0wx2c000000)))))
678           end
679    
680       and b {li, aa, lk} = let
681              val aa = (emit_bool aa)
682              val lk = (emit_bool lk)
683           in (eWord32 (lk + ((aa << 0wx1) + (((li && 0wxffffff) << 0wx2) + 0wx48000000))))
684           end
685    
686       and a_form {opcd, frt, fra, frb, frc, xo, rc} = let
687              val rc = (emit_bool rc)
688           in (eWord32 (rc + ((xo << 0wx1) + ((frc << 0wx6) + ((frb << 0wxb) + ((fra << 0wx10) + ((frt << 0wx15) + (opcd << 0wx1a))))))))
689           end
690    
691       and Cmpl {bf, l, ra, rb} = let
692              val bf = (emit_CC bf)
693              val l = (emit_bool l)
694              val ra = (emit_GP ra)
695              val rb = (emit_GP rb)
696           in (eWord32 ((rb << 0wxb) + ((ra << 0wx10) + ((l << 0wx15) + ((bf << 0wx17) + 0wx7c000040)))))
697           end
698    
699       and m_form {opcd, rs, ra, rb, mb, me, rc} = let
700              val rc = (emit_bool rc)
701           in (eWord32 (rc + ((me << 0wx1) + ((mb << 0wx6) + ((rb << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + (opcd << 0wx1a))))))))
702           end
703    
704       and bclr {bo, bi, lk} = let
705              val bo = (emit_bo bo)
706              val lk = (emit_bool lk)
707           in (eWord32 (lk + ((bi << 0wx10) + ((bo << 0wx15) + 0wx4c000020))))
708           end
709    
710       and funary {oper, ft, fb, Rc} = let
711              val oper = (emit_funary oper)
712              val ft = (emit_FP ft)
713              val fb = (emit_FP fb)
714           in let
715    
716    (*#line 433.1 "ppc/ppc.md"*)
717                 val(opcd, xo) = oper
718              in (x_form {opcd=opcd, rt=ft, ra=0wx0, rb=fb, xo=xo, rc=Rc})
719              end
720    
721           end
722    
723       and rldic {rs, ra, sh, mb, sh2} = let
724              val rs = (emit_GP rs)
725              val ra = (emit_GP ra)
726              val mb = (emit_int mb)
727           in (eWord32 ((sh2 << 0wx1) + ((mb << 0wx6) + ((sh << 0wxb) + ((ra << 0wx10) + ((rs << 0wx15) + 0wx78000008))))))
728           end
729    
730       and unary {ra, rt, oper, OE, Rc} =
731           (
732            case oper of
733            I.NEG => (unary' {ra=rt, rt=ra, oper=oper, OE=OE, Rc=Rc})
734          | _ => (unary' {ra=ra, rt=rt, oper=oper, OE=OE, Rc=Rc})
735           )
736       and compare {cmp, bf, l, ra, rb} =
737           (
738            case (cmp, rb) of
739            (I.CMP, I.RegOp rb) => (Cmp {bf=bf, l=l, ra=ra, rb=rb})
740          | (I.CMPL, I.RegOp rb) => (Cmpl {bf=bf, l=l, ra=ra, rb=rb})
741          | (I.CMP, si) => (Cmpi {bf=bf, l=l, ra=ra, si=si})
742          | (I.CMPL, ui) => (Cmpli {bf=bf, l=l, ra=ra, ui=ui})
743           )
744    
745       fun relative (I.LabelOp lexp) = ((itow ((LabelExp.valueOf lexp) - (! loc))) ~>> 0wx2)
746         | relative _ = (error "relative")
747    
748       fun emitInstr (I.L{ld, rt, ra, d, mem}) = (load {ld=ld, rt=rt, ra=ra, d=d})
749         | emitInstr (I.LF{ld, ft, ra, d, mem}) = (fload {ld=ld, ft=ft, ra=ra, d=d})
750         | emitInstr (I.ST{st, rs, ra, d, mem}) = (store {st=st, rs=rs, ra=ra, d=d})
751         | emitInstr (I.STF{st, fs, ra, d, mem}) = (fstore {st=st, fs=fs, ra=ra, d=d})
752         | emitInstr (I.UNARY{oper, rt, ra, Rc, OE}) = (unary {oper=oper, rt=rt, ra=ra, OE=OE, Rc=Rc})
753         | emitInstr (I.ARITH{oper, rt, ra, rb, Rc, OE}) = (arith {oper=oper, rt=rt, ra=ra, rb=rb, OE=OE, Rc=Rc})
754         | emitInstr (I.ARITHI{oper, rt, ra, im}) = (arithi {oper=oper, rt=rt, ra=ra, im=im})
755         | emitInstr (I.ROTATE{oper, ra, rs, sh, mb, me}) = (rotate {oper=oper, ra=ra, rs=rs, sh=sh, mb=mb, me=me})
756         | emitInstr (I.ROTATEI{oper, ra, rs, sh, mb, me}) = (rotatei {oper=oper, ra=ra, rs=rs, sh=sh, mb=mb, me=me})
757         | emitInstr (I.COMPARE{cmp, l, bf, ra, rb}) = (compare {cmp=cmp, bf=bf, l=l, ra=ra, rb=rb})
758         | emitInstr (I.FCOMPARE{cmp, bf, fa, fb}) = (fcmp {cmp=cmp, bf=bf, fa=fa, fb=fb})
759         | emitInstr (I.FUNARY{oper, ft, fb, Rc}) = (funary {oper=oper, ft=ft, fb=fb, Rc=Rc})
760         | emitInstr (I.FARITH{oper, ft, fa, fb, Rc}) = (farith {oper=oper, ft=ft, fa=fa, fb=fb, Rc=Rc})
761         | emitInstr (I.FARITH3{oper, ft, fa, fb, fc, Rc}) = (farith3 {oper=oper, ft=ft, fa=fa, fb=fb, fc=fc, Rc=Rc})
762         | emitInstr (I.CCARITH{oper, bt, ba, bb}) = (ccarith {oper=oper, bt=bt, ba=ba, bb=bb})
763         | emitInstr (I.MCRF{bf, bfa}) = (mcrf {bf=bf, bfa=bfa})
764         | emitInstr (I.MTSPR{rs, spr}) = (mtspr {rs=rs, spr=spr})
765         | emitInstr (I.MFSPR{rt, spr}) = (mfspr {rt=rt, spr=spr})
766         | emitInstr (I.TW{to, ra, si}) = (tw {to=to, ra=ra, si=si})
767         | emitInstr (I.TD{to, ra, si}) = (td {to=to, ra=ra, si=si})
768         | emitInstr (I.BC{bo, bf, bit, addr, LK, fall}) = (bc {bo=bo, bi=(cr_bit {cc=(bf, bit)}), bd=(relative addr), aa=false, lk=LK})
769         | emitInstr (I.BCLR{bo, bf, bit, LK, labels}) = (bclr {bo=bo, bi=(cr_bit {cc=(bf, bit)}), lk=LK})
770         | emitInstr (I.B{addr, LK}) = (b {li=(relative addr), aa=false, lk=LK})
771         | emitInstr (I.CALL{def, use, mem}) = (bclr {bo=I.ALWAYS, bi=0wx0, lk=true})
772         | emitInstr (I.COPY{dst, src, impl, tmp}) = (error "COPY")
773         | emitInstr (I.FCOPY{dst, src, impl, tmp}) = (error "FCOPY")
774         | emitInstr (I.ANNOTATION{i, a}) = (emitInstr i)
775         | emitInstr (I.GROUP annotation) = (error "GROUP")
776           in
777               emitInstr
778           end
779    
780       in  S.STREAM{init=init,
781                    pseudoOp=pseudoOp,
782                    emit=emitter,
783                    finish=doNothing,
784                    defineLabel=doNothing,
785                    entryLabel=doNothing,
786                    comment=doNothing,
787                    exitBlock=doNothing,
788                    blockName=doNothing,
789                    annotation=doNothing
790                   }
791      end      end
   
     fun i_form(opcd,li,lk) = let  
       val liLo = li & 0wx3fff  
       val liHi = (li ~>> 0w14) & 0wx3ff  
       val hi = (opcd << 0w10) ++ liHi  
       val lo = (liLo << 0w2) ++ lk  
     in emitHiLo(hi,lo)  
792      end      end
793    
   in  
     case instr  
     of I.L{sz, rt, ra, d=I.RegOp rb, mem} => let  
          val ra = rNum ra  
          val rb = rNum rb  
        in  
          case sz  
          of I.Byte => x_form(0w31, rNum rt, ra, rb, 0w87, don'tCare)  
           | I.Half => x_form(0w31, rNum rt, ra, rb, 0w279, don'tCare)  
           | I.Word => x_form(0w31, rNum rt, ra, rb, 0w23, don'tCare)  
           | I.Long => x_form(0w31, rNum rt, ra, rb, 0w21, don'tCare)  
           | I.Single => x_form(0w31, fNum rt, ra, rb, 0w535, don'tCare)  
           | I.Double => x_form(0w31, fNum rt, ra, rb, 0w599, don'tCare)  
          (*esac*)  
        end  
      | I.L{sz, rt, ra, d, mem} => let  
          val ra = rNum ra  
          val d = operand d  
        in  
          case sz  
          of I.Byte => d_form(0w34, rNum rt, ra, d)  
           | I.Half => d_form(0w40, rNum rt, ra, d)  
           | I.Word => d_form(0w32, rNum rt, ra, d)  
           | I.Long => ds_form(0w58, rNum rt, ra, d, 0w0)  
           | I.Single => d_form(0w48, fNum rt, ra, d)  
           | I.Double => d_form(0w50, fNum rt, ra, d)  
          (*esac*)  
        end  
      | I.ST{sz, rs, ra, d=I.RegOp rb, mem} => let  
          val ra=rNum ra  
          val rb=rNum rb  
        in  
          case sz  
          of I.Byte => x_form(0w31, rNum rs, ra, rb, 0w215, don'tCare)  
           | I.Half => x_form(0w31, rNum rs, ra, rb, 0w407, don'tCare)  
           | I.Word => x_form(0w31, rNum rs, ra, rb, 0w151, don'tCare)  
           | I.Long => x_form(0w31, rNum rs, ra, rb, 0w149, don'tCare)  
           | I.Single => x_form(0w31, fNum rs, ra, rb, 0w663, don'tCare)  
           | I.Double => x_form(0w31, fNum rs, ra, rb, 0w727, don'tCare)  
          (*esac*)  
        end  
      | I.ST{sz, rs, ra, d, mem} => let  
          val ra = rNum ra  
          val d = operand d  
        in  
          case sz  
          of I.Byte => d_form(0w38, rNum rs, ra, d)  
           | I.Half => d_form(0w44, rNum rs, ra, d)  
           | I.Word => d_form(0w36, rNum rs, ra, d)  
           | I.Long => ds_form(0w62, rNum rs, ra, d, 0w0)  
           | I.Single => d_form(0w52, fNum rs, ra, d)  
           | I.Double => d_form(0w54, fNum rs, ra, d)  
          (*esac*)  
        end  
      | I.UNARY{oper,rt,ra,Rc,OE} =>  
         (case oper  
           of I.NEG =>  
               xo_form(0w31, rNum rt, rNum ra, don'tCare, cvtOE OE, 0w104, cvtRc Rc)  
         (*esac*))  
      | I.ARITH{oper,rt,ra,rb,Rc,OE} => let  
          val rt=rNum rt  
          val ra=rNum ra  
          val rb=rNum rb  
          val Rc=cvtRc Rc  
          val OE=cvtOE OE  
        in  
          case oper  
           of I.ADD  => xo_form(0w31, rt, ra, rb, OE, 0w266, Rc)  
            | I.ADDS => error "emitInstr:ARITH:ADDS"  
            | I.SUBF => xo_form(0w31, rt, ra, rb, OE, 0w40, Rc)  
            | I.MULL => xo_form(0w31, rt, ra, rb, OE, 0w235, Rc)  
            | I.DIVW => xo_form(0w31, rt, ra, rb, OE, 0w491, Rc)  
            | I.DIVWU=> xo_form(0w31, rt, ra, rb, OE, 0w459, Rc)  
            | I.AND  => x_form(0w31, ra, rt, rb, 0w28, Rc)  
            | I.OR   => x_form(0w31, ra, rt, rb, 0w444, Rc)  
            | I.XOR  => x_form(0w31, ra, rt, rb, 0w316, Rc)  
            | I.XORS => error "emitInstr:ARITH:XORS"  
            | I.SLW  => x_form(0w31, ra, rt, rb, 0w24, Rc)  
            | I.SRW  => x_form(0w31, ra, rt, rb, 0w536, Rc)  
            | I.SRAW => x_form(0w31, ra, rt, rb, 0w792, Rc)  
         (*esac*)  
        end  
      | I.ARITHI{oper, rt=rt', ra=ra', im=im'} => let  
          val rt=rNum rt'  
          val ra=rNum ra'  
          val im=operand im'  
        in  
          case oper  
           of I.ADD  => d_form(0w14, rt, ra, im)  
            | I.ADDS => d_form(0w15, rt, ra, im)  
            | I.SUBF => d_form(0w8, rt, ra, im)  
            | I.MULL => d_form(0w7, rt, ra, im)  
            | I.DIVW => error "emitInstr:ARITHI:DIVW"  
            | I.DIVWU => error "emitInstr:ARITHI:DIVWU"  
            | I.AND => d_form(0w28, ra, rt, im)  
            | I.OR => d_form(0w24, ra, rt, im)  
            | I.XOR => d_form(0w26, ra, rt, im)  
            | I.XORS => d_form(0w27, ra, rt, im)  
            | I.SLW =>  
              (case im'  
               of I.ImmedOp n =>  
                   emitInstr(  
                     I.ROTATE{oper=I.RLWNM, ra=rt', rs=ra', sh=I.ImmedOp n,  
                              mb=0, me=31-n},  
                     regmap)  
                | _ => error "emitInstr:ARITHI:SLW"  
              (*esac*))  
            | I.SRW =>  
              (case im'  
               of I.ImmedOp n =>  
                   emitInstr(  
                     I.ROTATE{oper=I.RLWNM, ra=rt', rs=ra', sh=I.ImmedOp(32-n),  
                              mb=n, me=31},  
                     regmap)  
                | _ => error "emitInstr:ARITHI:SLW"  
               (*esac*))  
            | I.SRAW => x_form(0w31, ra, rt, im, 0w824, 0w0)  
         (*esac*)  
        end  
      | I.ROTATE{oper, ra, rs, sh=I.RegOp rb, mb, me} =>  
          m_form(0w23, rNum rs, rNum ra, rNum rb, mb, me, don'tCare)  
      | I.ROTATE{oper, ra, rs, sh, mb, me} =>  
          m_form(0w21, rNum rs, rNum ra, operand sh, mb, me, don'tCare)  
      | I.COMPARE{cmp, bf, ra, rb=I.RegOp rb} => let  
          val ra=rNum ra  
          val rb=rNum rb  
          val bf=itow(bf*4)  
        in  
          case cmp  
          of I.CMP => x_form(0w31, bf, ra, rb, 0w0, don'tCare)  
           | I.CMPL => x_form(0w31,bf, ra, rb, 0w32, don'tCare)  
          (*esac*)  
        end  
      | I.COMPARE{cmp, bf, ra, rb} => let  
         val ra=rNum ra  
         val rb=operand rb  
         val bf=itow(bf * 4)  
        in  
          case cmp  
          of I.CMP => d_form(0w11, bf, ra, rb)  
           | I.CMPL => d_form(0w10, bf, ra, rb)  
          (*esac*)  
        end  
      | I.FCOMPARE{cmp, bf, fa, fb} => let  
         val fa=fNum fa  
         val fb=fNum fb  
         val bf=itow(bf*4)  
        in  
         case cmp  
          of I.FCMPO => x_form(0w63, bf, fa, fb, 0w32, don'tCare)  
           | I.FCMPU => x_form(0w63, bf, fa, fb, 0w0, don'tCare)  
         (*esac*)  
        end  
      | I.FUNARY{oper, ft, fb, Rc} => let  
          val ft=fNum ft  
          val fb=fNum fb  
          val Rc=cvtRc Rc  
        in  
          case oper  
          of I.FMR => x_form(0w63, ft, don'tCare, fb, 0w72, Rc)  
           | I.FABS => x_form(0w63, ft, don'tCare, fb, 0w264, Rc)  
           | I.FNEG => x_form(0w63, ft, don'tCare, fb, 0w40, Rc)  
         (*esac*)  
        end  
      | I.FARITH{oper, ft, fa, fb, Rc} => let  
          val fa=fNum fa  
          val fb=fNum fb  
          val ft=fNum ft  
          val Rc=cvtRc Rc  
        in  
          case oper  
          of I.FADD => a_form(0w63, ft, fa, fb, don'tCare, 0w21, Rc)  
           | I.FSUB => a_form(0w63, ft, fa, fb, don'tCare, 0w20, Rc)  
           | I.FMUL => a_form(0w63, ft, fa, don'tCare, fb, 0w25, Rc)  
           | I.FDIV => a_form(0w63, ft, fa, fb, don'tCare, 0w18, Rc)  
          (*esac*)  
        end  
      | I.CCARITH{oper, bt, ba, bb} => let  
         val bt=cr_bit bt  
         val ba=cr_bit ba  
         val bb=cr_bit bb  
        in  
          case oper  
          of I.CRAND => xl_form(0w19, bt, ba, bb, 0w257, don'tCare)  
           | I.CROR => xl_form(0w19, bt, ba, bb, 0w449, don'tCare)  
           | I.CRXOR => xl_form(0w19, bt, ba, bb, 0w193, don'tCare)  
           | I.CRNAND => xl_form(0w19, bt, ba, bb, 0w225, don'tCare)  
           | I.CRNOR => xl_form(0w19, bt, ba, bb, 0w33, don'tCare)  
          (*esac*)  
        end  
      | I.MCRF {bf:int, bfa:int} =>  
          xl_form(0w19, itow(bf*4), itow(bfa*4), don'tCare, 0w0, don'tCare)  
      | I.MTSPR{rs:int, spr:int} =>  
          xfx_form(0w31, rNum rs, itow spr, 0w467, don'tCare)  
      | I.MFSPR{rt:int, spr:int} =>  
          xfx_form(0w31, rNum rt, itow spr, 0w339, don'tCare)  
      | I.TWI{to, ra, si} =>  
          d_form(0w3, itow to, rNum ra, operand si)  
   
     (* Control Instructions -  AA is always assumed to be 0 *)  
      | I.BC{bo, bf, bit, addr, LK, ...} =>  
          b_form(0w16, cvtBO bo, cr_bit(bf, bit), relative addr, 0w0, cvtLK LK)  
      | I.BCLR{bo, bf, bit, LK, labels} =>  
          xl_form(0w19, cvtBO bo, cr_bit(bf, bit), don'tCare, 0w16, cvtLK LK)  
      | I.B{addr, LK} => i_form(0w18, relative addr, cvtLK LK)  
   
     (* CALL = BCLR {bo=ALWAYS, bf=0, bit=0, LK=true, labels=[] *)  
      | I.CALL{def, use} =>  
          emitInstr(  
            I.BCLR{bo=I.ALWAYS, bf=0, bit=I.LT, LK=true, labels=[]},  
            regmap)  
   
      | I.COPY{dst, src, impl, tmp} => error "emitInstr:COPY"  
      | I.FCOPY{dst, src, impl, tmp}=> error "emitInstr:FCOPY"  
   end(*emitInstr*)  
 end (*functor*)  

Legend:
Removed from v.410  
changed lines
  Added in v.411

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