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

Diff of /sml/trunk/src/MLRISC/alpha/mltree/alpha.sml

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

revision 788, Wed Feb 28 04:09:48 2001 UTC revision 1335, Tue May 27 21:54:23 2003 UTC
# Line 5  Line 5 
5   *   *
6   * -- Allen   * -- Allen
7   *   *
8   * Notes: places with optimizations are marked ***OPT***   * Notes: places with optimizations are marked ***OPT**n*
9   *)   *)
10    
11    
12  functor Alpha  functor Alpha
13     (structure AlphaInstr : ALPHAINSTR     (structure AlphaInstr : ALPHAINSTR
14      structure PseudoInstrs : ALPHA_PSEUDO_INSTR      structure PseudoInstrs : ALPHA_PSEUDO_INSTR
15                            where I = AlphaInstr
16      structure ExtensionComp : MLTREE_EXTENSION_COMP      structure ExtensionComp : MLTREE_EXTENSION_COMP
17         where I = AlphaInstr         where I = AlphaInstr
18         sharing PseudoInstrs.I = AlphaInstr                            and T = AlphaInstr.T
19    
20        (* Cost of multiplication in cycles *)        (* Cost of multiplication in cycles *)
21      val multCost : int ref      val multCost : int ref
# Line 36  Line 38 
38    structure I   = AlphaInstr    structure I   = AlphaInstr
39    structure C   = I.C    structure C   = I.C
40    structure T   = I.T    structure T   = I.T
41    structure S   = T.Stream    structure TS  = ExtensionComp.TS
42    structure R   = T.Region    structure R   = T.Region
43    structure W32 = Word32    structure W32 = Word32
44    structure P   = PseudoInstrs    structure P   = PseudoInstrs
45    structure A   = MLRiscAnnotations    structure A   = MLRiscAnnotations
46      structure CB  = CellsBasis
47      structure CFG = ExtensionComp.CFG
48    
49   (*********************************************************   (*********************************************************
50    
# Line 137  Line 141 
141    "OpenVMS Alpha Software" (Part II of the Alpha Architecture    "OpenVMS Alpha Software" (Part II of the Alpha Architecture
142    Manual).  This stuff should apply to Unix (OSF1) as well as VMS.    Manual).  This stuff should apply to Unix (OSF1) as well as VMS.
143    
144    
145    
146    
147    
148    
149    
150                    -------------------o*o----------------------
151                               LIVE/KILL instructions
152                                     Nov 28, 2001
153                                      Lal George
154    
155      The mechanism described above is now obsolete. We no longer use
156      the DEFFREG instruction but the zero length LIVE instruction.
157      Therefore the code that gets generated is something like;
158    
159            f1 := f2 + f3
160            trap
161            LIVE f1, f2, f3
162    
163      The live ranges for f1, f2, and f3 are extended by the LIVE
164      instruction, and are live simultaneously and therefore cannot
165      be allocated to the same register.
166    
167      Multiple floating point instructions should be surrounded
168      by parallel copies. That is to say, if we have:
169    
170            f1 := f2 + f3
171            trapb
172            LIVE f1, f2, f3
173    
174            f4 := f1 * f2
175            trapb
176            LIVE f1, f2, f4
177    
178      Then the sequence above should be transformed to:
179    
180            [f2', f3'] := [f1, f2] ; parallel copy
181            f1' := f2' + f3'
182            f4' := f1' * f2'
183            trapb
184            LIVE f1', f2', f3', f4'
185            [f4] := [f4']  ; copy assuming f4 is the only value live.
186    
187      The parallel copies are to ensure that the primed variables will
188      not spill, and there should never be more than K reigsters in the LIVE
189      instruction (K is the number of registers on the machine).
190    ****************************************************************)    ****************************************************************)
191    
192    fun error msg = MLRiscErrorMsg.error("Alpha",msg)    fun error msg = MLRiscErrorMsg.error("Alpha",msg)
193    
194    type instrStream = (I.instruction,C.cellset) T.stream    type instrStream = (I.instruction, C.cellset, CFG.cfg) TS.stream
195    type mltreeStream = (T.stm,T.mlrisc list) T.stream    type mltreeStream = (T.stm, T.mlrisc list, CFG.cfg) TS.stream
196    
197    (*    (*
198     * This module is used to simulate operations of non-standard widths.     * This module is used to simulate operations of non-standard widths.
199     *)     *)
200    structure Gen = MLTreeGen(structure T = T    structure Gen = MLTreeGen(structure T = T
201                                structure Cells = C
202                              val intTy = 64                              val intTy = 64
203                              val naturalWidths = [32,64]                              val naturalWidths = [32,64]
204                              datatype rep = SE | ZE | NEITHER                              datatype rep = SE | ZE | NEITHER
# Line 160  Line 211 
211    fun toInt i = T.I.toInt(32, i)    fun toInt i = T.I.toInt(32, i)
212    val int_0   = T.I.int_0    val int_0   = T.I.int_0
213    val int_1   = T.I.int_1    val int_1   = T.I.int_1
214    fun EQ(x:IntInf.int,y) = x=y    val EQ      = IntInf.==
215    
216    (*    (*
217     * Specialize the modules for multiplication/division     * Specialize the modules for multiplication/division
# Line 169  Line 220 
220    functor Multiply32 = MLTreeMult    functor Multiply32 = MLTreeMult
221      (structure I = I      (structure I = I
222       structure T = T       structure T = T
223         structure CB = CellsBasis
224    
225       val intTy = 32       val intTy = 32
226    
227       type arg  = {r1:C.cell,r2:C.cell,d:C.cell}       type arg  = {r1:CB.cell,r2:CB.cell,d:CB.cell}
228       type argi = {r:C.cell,i:int,d:C.cell}       type argi = {r:CB.cell,i:int,d:CB.cell}
229    
230       fun mov{r,d}    = I.COPY{dst=[d],src=[r],tmp=NONE,impl=ref NONE}       fun mov{r,d}    = I.COPY{k=CB.GP, sz=intTy, dst=[d],src=[r],tmp=NONE}
231       fun add{r1,r2,d} = I.OPERATE{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}       fun add{r1,r2,d} = I.operate{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}
232       (*       (*
233        * How to left shift by a constant (32bits)        * How to left shift by a constant (32bits)
234        *)        *)
235       fun slli{r,i=1,d} = [I.OPERATE{oper=I.ADDL,ra=r,rb=I.REGop r,rc=d}]       fun slli{r,i=1,d} = [I.operate{oper=I.ADDL,ra=r,rb=I.REGop r,rc=d}]
236         | slli{r,i=2,d} = [I.OPERATE{oper=I.S4ADDL,ra=r,rb=zeroOpn,rc=d}]         | slli{r,i=2,d} = [I.operate{oper=I.S4ADDL,ra=r,rb=zeroOpn,rc=d}]
237         | slli{r,i=3,d} = [I.OPERATE{oper=I.S8ADDL,ra=r,rb=zeroOpn,rc=d}]         | slli{r,i=3,d} = [I.operate{oper=I.S8ADDL,ra=r,rb=zeroOpn,rc=d}]
238         | slli{r,i,d}   =         | slli{r,i,d}   =
239            let val tmp = C.newReg()            let val tmp = C.newReg()
240            in  [I.OPERATE{oper=I.SLL,ra=r,rb=I.IMMop i,rc=tmp},            in  [I.operate{oper=I.SLL,ra=r,rb=I.IMMop i,rc=tmp},
241                 I.OPERATE{oper=I.ADDL,ra=tmp,rb=zeroOpn,rc=d}]                 I.operate{oper=I.ADDL,ra=tmp,rb=zeroOpn,rc=d}]
242            end            end
243    
244       (*       (*
# Line 194  Line 246 
246        *)        *)
247       fun srli{r,i,d} =       fun srli{r,i,d} =
248           let val tmp = C.newReg()           let val tmp = C.newReg()
249           in  [I.OPERATE{oper=I.ZAP,ra=r,rb=I.IMMop 0xf0,rc=tmp},           in  [I.operate{oper=I.ZAP,ra=r,rb=I.IMMop 0xf0,rc=tmp},
250                I.OPERATE{oper=I.SRL,ra=tmp,rb=I.IMMop i,rc=d}]                I.operate{oper=I.SRL,ra=tmp,rb=I.IMMop i,rc=d}]
251           end           end
252    
253       (*       (*
# Line 203  Line 255 
255        *)        *)
256       fun srai{r,i,d} =       fun srai{r,i,d} =
257           let val tmp = C.newReg()           let val tmp = C.newReg()
258           in  [I.OPERATE{oper=I.ADDL,ra=r,rb=zeroOpn,rc=tmp},           in  [I.operate{oper=I.ADDL,ra=r,rb=zeroOpn,rc=tmp},
259                I.OPERATE{oper=I.SRA,ra=tmp,rb=I.IMMop i,rc=d}]                I.operate{oper=I.SRA,ra=tmp,rb=I.IMMop i,rc=d}]
260           end           end
261      )      )
262    
263    functor Multiply64 = MLTreeMult    functor Multiply64 = MLTreeMult
264      (structure I = I      (structure I = I
265       structure T = T       structure T = T
266         structure CB = CellsBasis
267    
268       val intTy = 64       val intTy = 64
269    
270       type arg  = {r1:C.cell,r2:C.cell,d:C.cell}       type arg  = {r1:CB.cell, r2:CB.cell, d:CB.cell}
271       type argi = {r:C.cell,i:int,d:C.cell}       type argi = {r:CB.cell, i:int, d:CB.cell}
272    
273       fun mov{r,d}    = I.COPY{dst=[d],src=[r],tmp=NONE,impl=ref NONE}       fun mov{r,d}    = I.COPY{k=CB.GP, sz=intTy, dst=[d],src=[r],tmp=NONE}
274       fun add{r1,r2,d}= I.OPERATE{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}       fun add{r1,r2,d}= I.operate{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}
275       fun slli{r,i,d} = [I.OPERATE{oper=I.SLL,ra=r,rb=I.IMMop i,rc=d}]       fun slli{r,i,d} = [I.operate{oper=I.SLL,ra=r,rb=I.IMMop i,rc=d}]
276       fun srli{r,i,d} = [I.OPERATE{oper=I.SRL,ra=r,rb=I.IMMop i,rc=d}]       fun srli{r,i,d} = [I.operate{oper=I.SRL,ra=r,rb=I.IMMop i,rc=d}]
277       fun srai{r,i,d} = [I.OPERATE{oper=I.SRA,ra=r,rb=I.IMMop i,rc=d}]       fun srai{r,i,d} = [I.operate{oper=I.SRA,ra=r,rb=I.IMMop i,rc=d}]
278      )      )
279    
280    (* signed, trapping version of multiply and divide *)    (* signed, trapping version of multiply and divide *)
281    structure Mult32 = Multiply32    structure Mult32 = Multiply32
282      (val trapping = true      (val trapping = true
283       val multCost = multCost       val multCost = multCost
284       fun addv{r1,r2,d} = [I.OPERATEV{oper=I.ADDLV,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.operatev{oper=I.ADDLV,ra=r1,rb=I.REGop r2,rc=d}]
285       fun subv{r1,r2,d} = [I.OPERATEV{oper=I.SUBLV,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.operatev{oper=I.SUBLV,ra=r1,rb=I.REGop r2,rc=d}]
286       val sh1addv = NONE       val sh1addv = NONE
287       val sh2addv = NONE       val sh2addv = NONE
288       val sh3addv = NONE       val sh3addv = NONE
# Line 240  Line 293 
293    functor Mul32 = Multiply32    functor Mul32 = Multiply32
294      (val trapping = false      (val trapping = false
295       val multCost = multCost       val multCost = multCost
296       fun addv{r1,r2,d} = [I.OPERATE{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.operate{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}]
297       fun subv{r1,r2,d} = [I.OPERATE{oper=I.SUBL,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.operate{oper=I.SUBL,ra=r1,rb=I.REGop r2,rc=d}]
298       val sh1addv = NONE       val sh1addv = NONE
299       val sh2addv = SOME(fn {r1,r2,d} =>       val sh2addv = SOME(fn {r1,r2,d} =>
300                      [I.OPERATE{oper=I.S4ADDL,ra=r1,rb=I.REGop r2,rc=d}])                      [I.operate{oper=I.S4ADDL,ra=r1,rb=I.REGop r2,rc=d}])
301       val sh3addv = SOME(fn {r1,r2,d} =>       val sh3addv = SOME(fn {r1,r2,d} =>
302                      [I.OPERATE{oper=I.S8ADDL,ra=r1,rb=I.REGop r2,rc=d}])                      [I.operate{oper=I.S8ADDL,ra=r1,rb=I.REGop r2,rc=d}])
303      )      )
304    structure Mulu32 = Mul32(val signed = false)    structure Mulu32 = Mul32(val signed = false)
305    structure Muls32 = Mul32(val signed = true)    structure Muls32 = Mul32(val signed = true)
# Line 255  Line 308 
308    structure Mult64 = Multiply64    structure Mult64 = Multiply64
309      (val trapping = true      (val trapping = true
310       val multCost = multCost       val multCost = multCost
311       fun addv{r1,r2,d} = [I.OPERATEV{oper=I.ADDQV,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.operatev{oper=I.ADDQV,ra=r1,rb=I.REGop r2,rc=d}]
312       fun subv{r1,r2,d} = [I.OPERATEV{oper=I.SUBQV,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.operatev{oper=I.SUBQV,ra=r1,rb=I.REGop r2,rc=d}]
313       val sh1addv = NONE       val sh1addv = NONE
314       val sh2addv = NONE       val sh2addv = NONE
315       val sh3addv = NONE       val sh3addv = NONE
# Line 267  Line 320 
320    functor Mul64 = Multiply64    functor Mul64 = Multiply64
321      (val trapping = false      (val trapping = false
322       val multCost = multCost       val multCost = multCost
323       fun addv{r1,r2,d} = [I.OPERATE{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.operate{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}]
324       fun subv{r1,r2,d} = [I.OPERATE{oper=I.SUBQ,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.operate{oper=I.SUBQ,ra=r1,rb=I.REGop r2,rc=d}]
325       val sh1addv = NONE       val sh1addv = NONE
326       val sh2addv = SOME(fn {r1,r2,d} =>       val sh2addv = SOME(fn {r1,r2,d} =>
327                      [I.OPERATE{oper=I.S4ADDQ,ra=r1,rb=I.REGop r2,rc=d}])                      [I.operate{oper=I.S4ADDQ,ra=r1,rb=I.REGop r2,rc=d}])
328       val sh3addv = SOME(fn {r1,r2,d} =>       val sh3addv = SOME(fn {r1,r2,d} =>
329                      [I.OPERATE{oper=I.S8ADDQ,ra=r1,rb=I.REGop r2,rc=d}])                      [I.operate{oper=I.S8ADDQ,ra=r1,rb=I.REGop r2,rc=d}])
330      )      )
331    structure Mulu64 = Mul64(val signed = false)    structure Mulu64 = Mul64(val signed = false)
332    structure Muls64 = Mul64(val signed = true)    structure Muls64 = Mul64(val signed = true)
# Line 289  Line 342 
342    val zeroFR = C.f31    val zeroFR = C.f31
343    val zeroEA = I.Direct zeroR    val zeroEA = I.Direct zeroR
344    val zeroT  = T.LI int_0    val zeroT  = T.LI int_0
345    val trapb = [I.TRAPB]    val trapb = [I.trapb]
346    val zeroImm = I.IMMop 0    val zeroImm = I.IMMop 0
347    
348    fun selectInstructions    fun selectInstructions
349          (instrStream as          (instrStream as
350           S.STREAM{emit,beginCluster,endCluster,           TS.S.STREAM{emit=emitInstruction,beginCluster,endCluster,getAnnotations,
351                    defineLabel,entryLabel,pseudoOp,annotation,                    defineLabel,entryLabel,pseudoOp,annotation,
352                    exitBlock,comment,...}) =                    exitBlock,comment,...}) =
353    let    let
354    
355        infix || && << >> ~>>        infix || && << >> ~>>
356    
357        val op ||  = W32.orb        val op ||  = W32.orb
# Line 309  Line 363 
363        val itow = Word.fromInt        val itow = Word.fromInt
364        val wtoi = Word.toIntX        val wtoi = Word.toIntX
365    
366          val emit = emitInstruction o I.INSTR
367    
368        val newReg = C.newReg        val newReg = C.newReg
369        val newFreg = C.newFreg        val newFreg = C.newFreg
370    
# Line 329  Line 385 
385        val (ADDSX,SUBSX,MULSX,DIVSX) =        val (ADDSX,SUBSX,MULSX,DIVSX) =
386              (I.ADDSSUD,I.SUBSSUD,I.MULSSUD,I.DIVSSUD)              (I.ADDSSUD,I.SUBSSUD,I.MULSSUD,I.DIVSSUD)
387    
388        fun mark'(i,[]) = i        fun annotate(i, an) = List.foldl (fn (a, i) => I.ANNOTATION{i=i,a=a}) i an
389          | mark'(i,a::an) = mark'(I.ANNOTATION{i=i,a=a},an)        fun mark'(i, an) = emitInstruction(annotate(i,an))
390        fun mark(i,an) = emit(mark'(i,an))        fun mark(i,an) = emitInstruction(annotate(I.INSTR i,an))
391    
392        (* Fit within 16 bits? *)        (* Fit within 16 bits? *)
393        fun literal16 n = ~32768 <= n andalso n < 32768        fun literal16 n = ~32768 <= n andalso n < 32768
# Line 402  Line 458 
458    
459        (* emit a copy *)        (* emit a copy *)
460        and copy(dst,src,an) =        and copy(dst,src,an) =
461            mark(I.COPY{dst=dst,src=src,impl=ref NONE,            mark'(I.COPY{k=CB.GP, sz=32, dst=dst,src=src,
462                        tmp=case dst of                        tmp=case dst of
463                             [_] => NONE | _ => SOME(I.Direct(newReg()))},an)                             [_] => NONE | _ => SOME(I.Direct(newReg()))},an)
464    
465        (* emit a floating point copy *)        (* emit a floating point copy *)
466        and fcopy(dst,src,an) =        and fcopy(dst,src,an) =
467            mark(I.FCOPY{dst=dst,src=src,impl=ref NONE,            mark'(I.COPY{k=CB.FP, sz=64, dst=dst,src=src,
468                        tmp=case dst of                        tmp=case dst of
469                             [_] => NONE | _ => SOME(I.FDirect(newFreg()))},an)                             [_] => NONE | _ => SOME(I.FDirect(newFreg()))},an)
470    
471        and move(s,d,an) =        and move(s,d,an) =
472            if C.sameCell(s,d) orelse C.sameCell(d,zeroR) then () else            if CB.sameCell(s,d) orelse CB.sameCell(d,zeroR) then () else
473            mark(I.COPY{dst=[d],src=[s],impl=ref NONE,tmp=NONE},an)            mark'(I.COPY{k=CB.GP, sz=32, dst=[d],src=[s],tmp=NONE},an)
474    
475        and fmove(s,d,an) =        and fmove(s,d,an) =
476            if C.sameCell(s,d) orelse C.sameCell(d,zeroFR) then () else            if CB.sameCell(s,d) orelse CB.sameCell(d,zeroFR) then () else
477            mark(I.FCOPY{dst=[d],src=[s],impl=ref NONE,tmp=NONE},an)            mark'(I.COPY{k=CB.FP, sz=64, dst=[d],src=[s],tmp=NONE},an)
478    
479         (* emit an sign extension op *)         (* emit an sign extension op *)
480        and signExt32(r,d) =        and signExt32(r,d) =
# Line 468  Line 524 
524                I.IMMop(toInt(n))                I.IMMop(toInt(n))
525              else let val tmpR = newReg()              else let val tmpR = newReg()
526                   in  loadImmed(n,zeroR,tmpR,[]); I.REGop tmpR end                   in  loadImmed(n,zeroR,tmpR,[]); I.REGop tmpR end
527          | opn(e as (T.CONST _ | T.LABEL _)) = I.LABop e          | opn(e as T.CONST _) = I.LABop e
528          | opn(T.LABEXP x) = I.LABop x          | opn(T.LABEXP x) = I.LABop x
529          | opn e = I.REGop(expr e)          | opn e = I.REGop(expr e)
530    
# Line 661  Line 717 
717            | SOME 0w3 => arith(I.S8ADDQ,a,zeroT,d,an)            | SOME 0w3 => arith(I.S8ADDQ,a,zeroT,d,an)
718            | _        => arith(I.SLL,a,b,d,an)            | _        => arith(I.SLL,a,b,d,an)
719    
720        and sra32(a,b,d,an) =         (* On the alpha, all 32 bit values are already sign extended.
721            let val ra = expr a          * So no sign extension is necessary.  We do the same for
722                val rb = opn b          * sra32 and sra64
               val t  = newReg()  
           in  (* On the alpha, all 32 bit values are already sign extended.  
                * So no sign extension is necessary.  
                * signExt32(ra,t);  
                * mark(I.OPERATE{oper=I.SRA,ra=t,rb=rb,rc=d},an)  
723                 *)                 *)
724                mark(I.OPERATE{oper=I.SRA,ra=ra,rb=rb,rc=d},an)        and sra(a,b,d,an) =
           end  
   
       and sra64(a,b,d,an) =  
725            mark(I.OPERATE{oper=I.SRA,ra=expr a,rb=opn b,rc=d},an)            mark(I.OPERATE{oper=I.SRA,ra=expr a,rb=opn b,rc=d},an)
726    
727        and srl32(a,b,d,an) =        and srl32(a,b,d,an) =
# Line 698  Line 746 
746                    (i,I.REGop r) => gen{ra=r,rb=i,rc=rd}                    (i,I.REGop r) => gen{ra=r,rb=i,rc=rd}
747                  | (I.REGop r,i) => gen{ra=r,rb=i,rc=rd}                  | (I.REGop r,i) => gen{ra=r,rb=i,rc=rd}
748                  | (r,i)         => gen{ra=reduceOpn r,rb=i,rc=rd}                  | (r,i)         => gen{ra=reduceOpn r,rb=i,rc=rd}
749                in mark'(instr,an)::trapb end                in annotate(instr,an)::trapb end
750                fun const(e,i) =                fun const(e,i) =
751                    let val r = expr e                    let val r = expr e
752                    in  if !useMultByConst andalso                    in  if !useMultByConst andalso
753                             IntInf.>=(i, T.I.int_0) andalso                             IntInf.>=(i, T.I.int_0) andalso
754                             IntInf.<(i, T.I.int_0x100) then                             IntInf.<(i, T.I.int_0x100) then
755                           mark'(gen{ra=r,rb=I.IMMop(toInt i),rc=rd},an)::trapb                           annotate(gen{ra=r,rb=I.IMMop(toInt i),rc=rd},an)::trapb
756                        else                        else
757                           (genConst{r=r,i=toInt i,d=rd}@trapb                           (genConst{r=r,i=toInt i,d=rd}@trapb
758                            handle _ => nonconst(T.REG(ty,r),T.LI i))                            handle _ => nonconst(T.REG(ty,r),T.LI i))
# Line 714  Line 762 
762                  of (_, T.LI i) => const(e1, i)                  of (_, T.LI i) => const(e1, i)
763                   | (T.LI i, _) => const(e2, i)                   | (T.LI i, _) => const(e2, i)
764                   | _ => nonconst(e1, e2)                   | _ => nonconst(e1, e2)
765            in  app emit instrs            in  app emitInstruction instrs
766            end            end
767    
768            (* Round r towards zero.            (* Round r towards zero.
# Line 750  Line 798 
798                    case e2 of                    case e2 of
799                       T.LI i   => const(e1,i)                       T.LI i   => const(e1,i)
800                     | _        => nonconst(e1,e2)                     | _        => nonconst(e1,e2)
801            in  app emit instrs            in  app emitInstruction instrs
802            end            end
803    
804    
# Line 802  Line 850 
850    
851        (* generate pseudo instruction *)        (* generate pseudo instruction *)
852        and pseudo(instr,e1,e2,rc) =        and pseudo(instr,e1,e2,rc) =
853             app emit (instr({ra=expr e1,rb=opn e2,rc=rc}, reduceOpn))             app emitInstruction (instr({ra=expr e1,rb=opn e2,rc=rc}, reduceOpn))
854    
855        (* generate a load *)        (* generate a load *)
856        and load(ldOp,ea,d,mem,an) =        and load(ldOp,ea,d,mem,an) =
# Line 891  Line 939 
939    
940        (* generate conversion from floating point to integer *)        (* generate conversion from floating point to integer *)
941        and cvtf2i(pseudo,rounding,e,rd,an) =        and cvtf2i(pseudo,rounding,e,rd,an) =
942            app emit (pseudo{mode=rounding, fs=fexpr e, rd=rd})            app emitInstruction (pseudo{mode=rounding, fs=fexpr e, rd=rd})
943    
944        (* generate an expression and return the register that holds the result *)        (* generate an expression and return the register that holds the result *)
945        and expr(e) = let        and expr(e) = let
# Line 948  Line 996 
996            | T.SUBT(32,a,b) => arithTrap(I.SUBLV,a,b,d,an)            | T.SUBT(32,a,b) => arithTrap(I.SUBLV,a,b,d,an)
997            | T.MULT(32,a,b) =>            | T.MULT(32,a,b) =>
998                 multiply(32,                 multiply(32,
999                   fn{ra,rb,rc} => I.OPERATEV{oper=I.MULLV,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.operatev{oper=I.MULLV,ra=ra,rb=rb,rc=rc},
1000                   Mult32.multiply,a,b,d,trapb,an)                   Mult32.multiply,a,b,d,trapb,an)
1001            | T.MULU(32,a,b) =>            | T.MULU(32,a,b) =>
1002                 multiply(32,                 multiply(32,
1003                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULL,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.operate{oper=I.MULL,ra=ra,rb=rb,rc=rc},
1004                   Mulu32.multiply,a,b,d,[],an)                   Mulu32.multiply,a,b,d,[],an)
1005            | T.MULS(32,a,b) =>            | T.MULS(32,a,b) =>
1006                 multiply(32,                 multiply(32,
1007                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULL,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.operate{oper=I.MULL,ra=ra,rb=rb,rc=rc},
1008                   Muls32.multiply,a,b,d,[],an)                   Muls32.multiply,a,b,d,[],an)
1009            | T.DIVT(32,a,b) => divide(32,P.divlv,Mult32.divide,a,b,d,an)            | T.DIVT(T.DIV_TO_ZERO,32,a,b) =>
1010                                  divide(32,P.divlv,Mult32.divide,a,b,d,an)
1011            | T.DIVU(32,a,b) => divide(32,P.divlu,Mulu32.divide,a,b,d,an)            | T.DIVU(32,a,b) => divide(32,P.divlu,Mulu32.divide,a,b,d,an)
1012            | T.DIVS(32,a,b) => divide(32,P.divl,Muls32.divide,a,b,d,an)            | T.DIVS(T.DIV_TO_ZERO,32,a,b) =>
1013            | T.REMT(32,a,b) => pseudo(P.remlv,a,b,d)                                divide(32,P.divl,Muls32.divide,a,b,d,an)
1014    (* FIXME: these two lines can go back in once the alphaMC can handle them:
1015            | T.REMU(32,a,b) => pseudo(P.remlu,a,b,d)            | T.REMU(32,a,b) => pseudo(P.remlu,a,b,d)
1016            | T.REMS(32,a,b) => pseudo(P.reml,a,b,d)            | T.REMS(T.DIV_TO_ZERO,32,a,b) => pseudo(P.reml,a,b,d)
1017    *)
1018    
1019            | T.SLL(32,a,b) => sll32(a,b,d,an)            | T.SLL(32,a,b) => sll32(a,b,d,an)
1020            | T.SRA(32,a,b) => sra32(a,b,d,an)            | T.SRA(32,a,b) => sra(a,b,d,an)
1021            | T.SRL(32,a,b) => srl32(a,b,d,an)            | T.SRL(32,a,b) => srl32(a,b,d,an)
1022    
1023              (* 64 bit support *)              (* 64 bit support *)
# Line 976  Line 1027 
1027            | T.SUBT(64,a,b) => arithTrap(I.SUBQV,a,b,d,an)            | T.SUBT(64,a,b) => arithTrap(I.SUBQV,a,b,d,an)
1028            | T.MULT(64,a,b) =>            | T.MULT(64,a,b) =>
1029                 multiply(64,                 multiply(64,
1030                   fn{ra,rb,rc} => I.OPERATEV{oper=I.MULQV,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.operatev{oper=I.MULQV,ra=ra,rb=rb,rc=rc},
1031                   Mult64.multiply,a,b,d,trapb,an)                   Mult64.multiply,a,b,d,trapb,an)
1032            | T.MULU(64,a,b) =>            | T.MULU(64,a,b) =>
1033                 multiply(64,                 multiply(64,
1034                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULQ,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.operate{oper=I.MULQ,ra=ra,rb=rb,rc=rc},
1035                   Mulu64.multiply,a,b,d,[],an)                   Mulu64.multiply,a,b,d,[],an)
1036            | T.MULS(64,a,b) =>            | T.MULS(64,a,b) =>
1037                 multiply(64,                 multiply(64,
1038                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULQ,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.operate{oper=I.MULQ,ra=ra,rb=rb,rc=rc},
1039                   Muls64.multiply,a,b,d,[],an)                   Muls64.multiply,a,b,d,[],an)
1040            | T.DIVT(64,a,b) => divide(64,P.divqv,Mult64.divide,a,b,d,an)            | T.DIVT(T.DIV_TO_ZERO,64,a,b) =>
1041                                  divide(64,P.divqv,Mult64.divide,a,b,d,an)
1042            | T.DIVU(64,a,b) => divide(64,P.divqu,Mulu64.divide,a,b,d,an)            | T.DIVU(64,a,b) => divide(64,P.divqu,Mulu64.divide,a,b,d,an)
1043            | T.DIVS(64,a,b) => divide(64,P.divq,Muls64.divide,a,b,d,an)            | T.DIVS(T.DIV_TO_ZERO,64,a,b) =>
1044            | T.REMT(64,a,b) => pseudo(P.remqv,a,b,d)                                divide(64,P.divq,Muls64.divide,a,b,d,an)
1045    (* FIXME: These two lines can go back in once the alphaMC can handle them:
1046            | T.REMU(64,a,b) => pseudo(P.remqu,a,b,d)            | T.REMU(64,a,b) => pseudo(P.remqu,a,b,d)
1047            | T.REMS(64,a,b) => pseudo(P.remq,a,b,d)            | T.REMS(T.DIV_TO_ZERO,64,a,b) => pseudo(P.remq,a,b,d)
1048    *)
1049    
1050            | T.SLL(64,a,b) => sll64(a,b,d,an)            | T.SLL(64,a,b) => sll64(a,b,d,an)
1051            | T.SRA(64,a,b) => sra64(a,b,d,an)            | T.SRA(64,a,b) => sra(a,b,d,an)
1052            | T.SRL(64,a,b) => srl64(a,b,d,an)            | T.SRL(64,a,b) => srl64(a,b,d,an)
1053    
1054              (* special bit operations with complement *)              (* special bit operations with complement *)
# Line 1070  Line 1124 
1124            let val fa = fexpr a            let val fa = fexpr a
1125                val fb = fexpr b                val fb = fexpr b
1126            in  if SMLNJfloatingPoint then            in  if SMLNJfloatingPoint then
1127                     (emit(I.DEFFREG d);                     ((* emit(I.DEFFREG d); *)
1128                      mark(I.FOPERATEV{oper=opcodeSMLNJ,fa=fa,fb=fb,fc=d},an);                      mark(I.FOPERATEV{oper=opcodeSMLNJ,fa=fa,fb=fb,fc=d},an);
1129                      emit(I.TRAPB)                      emit(I.TRAPB);
1130                        emitInstruction(I.LIVE{regs=List.foldl C.addFreg C.empty [fa,fb,d],
1131                                               spilled=[]})
1132    
1133                     )                     )
1134                else mark(I.FOPERATE{oper=opcode,fa=fa,fb=fb,fc=d},an)                else mark(I.FOPERATE{oper=opcode,fa=fa,fb=fb,fc=d},an)
1135            end            end
# Line 1092  Line 1149 
1149        (* generate an external floating point operation *)        (* generate an external floating point operation *)
1150        and fcvti2f(pseudo,e,fd,an) =        and fcvti2f(pseudo,e,fd,an) =
1151            let val opnd = opn e            let val opnd = opn e
1152            in  app emit (pseudo({opnd=opnd, fd=fd}, reduceOpn))            in  app emitInstruction (pseudo({opnd=opnd, fd=fd}, reduceOpn))
1153            end            end
1154    
1155        (* generate a floating point store *)        (* generate a floating point store *)
# Line 1194  Line 1251 
1251                  val f2 = fexpr e2                  val f2 = fexpr e2
1252                  fun bcc(cmp,br) =                  fun bcc(cmp,br) =
1253                  let val tmpR = C.newFreg()                  let val tmpR = C.newFreg()
1254                  in  emit(I.DEFFREG(tmpR));                  in  (*emit(I.DEFFREG(tmpR));*)
1255                      emit(I.FOPERATE{oper=cmp,fa=f1,fb=f2,fc=tmpR});                      emit(I.FOPERATE{oper=cmp,fa=f1,fb=f2,fc=tmpR});
1256                      emit(I.TRAPB);                      emit(I.TRAPB);
1257                        emitInstruction(I.LIVE{regs=List.foldl C.addFreg C.empty [f1,f2,tmpR],
1258                                    spilled=[]});
1259                      mark(I.FBRANCH{b=br,f=tmpR,lab=lab},an)                      mark(I.FBRANCH{b=br,f=tmpR,lab=lab},an)
1260                  end                  end
1261                  fun fall(cmp1, br1, cmp2, br2) =                  fun fall(cmp1, br1, cmp2, br2) =
1262                  let val tmpR1 = newFreg()                  let val tmpR1 = newFreg()
1263                      val tmpR2 = newFreg()                      val tmpR2 = newFreg()
1264                      val fallLab = Label.newLabel ""                      val fallLab = Label.anon()
1265                  in  emit(I.DEFFREG(tmpR1));                  in  (*emit(I.DEFFREG(tmpR1));*)
1266                      emit(I.FOPERATE{oper=cmp1, fa=f1, fb=f2, fc=tmpR1});                      emit(I.FOPERATE{oper=cmp1, fa=f1, fb=f2, fc=tmpR1});
1267                      emit(I.TRAPB);                      emit(I.TRAPB);
1268                        emitInstruction(I.LIVE{regs=List.foldl C.addFreg C.empty [f1,f2,tmpR1],
1269                                    spilled=[]});
1270                      mark(I.FBRANCH{b=br1, f=tmpR1, lab=fallLab},an);                      mark(I.FBRANCH{b=br1, f=tmpR1, lab=fallLab},an);
1271                      emit(I.DEFFREG(tmpR2));                      (* emit(I.DEFFREG(tmpR2)); *)
1272                      emit(I.FOPERATE{oper=cmp2, fa=f1, fb=f2, fc=tmpR2});                      emit(I.FOPERATE{oper=cmp2, fa=f1, fb=f2, fc=tmpR2});
1273                      emit(I.TRAPB);                      emit(I.TRAPB);
1274                        emitInstruction(I.LIVE{regs=List.foldl C.addFreg C.empty [f1,f2,tmpR2],
1275                                    spilled=[]});
1276                      mark(I.FBRANCH{b=br2, f=tmpR2, lab=lab},an);                      mark(I.FBRANCH{b=br2, f=tmpR2, lab=lab},an);
1277                      defineLabel fallLab                      defineLabel fallLab
1278                  end                  end
# Line 1416  Line 1479 
1479        and goto(lab,an) = mark(I.BRANCH{b=I.BR,r=zeroR,lab=lab},an)        and goto(lab,an) = mark(I.BRANCH{b=I.BR,r=zeroR,lab=lab},an)
1480    
1481           (* generate an call instruction *)           (* generate an call instruction *)
1482        and call(ea,flow,defs,uses,mem,an) =        and call(ea,flow,defs,uses,mem,cutTo,an,0) =
1483         let val defs=cellset defs         let val defs=cellset defs
1484             val uses=cellset uses             val uses=cellset uses
1485             val instr =             val instr =
1486                 case (ea, flow) of                 case (ea, flow) of
1487                   (T.LABEL lab, [_]) =>                   (T.LABEL lab, [_]) =>
1488                     I.BSR{lab=lab,r=C.returnAddr,defs=defs,uses=uses,mem=mem}                        I.BSR{lab=lab,r=C.returnAddr,defs=defs,uses=uses,
1489                                cutsTo=cutTo,mem=mem}
1490                 | _ => I.JSR{r=C.returnAddr,b=expr ea,                 | _ => I.JSR{r=C.returnAddr,b=expr ea,
1491                              d=0,defs=defs,uses=uses,mem=mem}                                   d=0,defs=defs,uses=uses,cutsTo=cutTo,mem=mem}
1492         in  mark(instr,an)         in  mark(instr,an)
1493         end         end
1494            | call _ = error "pops<>0 not implemented"
1495    
1496        and doCCexpr(T.CC(_,r),d,an) = move(r,d,an)        and doCCexpr(T.CC(_,r),d,an) = move(r,d,an)
1497          | doCCexpr(T.FCC(_,r),d,an) = fmove(r,d,an)          | doCCexpr(T.FCC(_,r),d,an) = fmove(r,d,an)
# Line 1454  Line 1519 
1519            | T.JMP(T.LABEL lab,_) => goto(lab,an)            | T.JMP(T.LABEL lab,_) => goto(lab,an)
1520            | T.JMP(e,labs) => mark(I.JMPL({r=zeroR,b=expr e,d=0},labs),an)            | T.JMP(e,labs) => mark(I.JMPL({r=zeroR,b=expr e,d=0},labs),an)
1521            | T.BCC(cc,lab) => branch(cc,lab,an)            | T.BCC(cc,lab) => branch(cc,lab,an)
1522            | T.CALL{funct,targets,defs,uses,region,...} =>            | T.CALL{funct,targets,defs,uses,region,pops,...} =>
1523                call(funct,targets,defs,uses,region,an)                call(funct,targets,defs,uses,region,[],an,pops)
1524              | T.FLOW_TO(T.CALL{funct,targets,defs,uses,region,pops,...},cutTo) =>
1525                  call(funct,targets,defs,uses,region,cutTo,an,pops)
1526            | T.RET _ => mark(I.RET{r=zeroR,b=C.returnAddr,d=0},an)            | T.RET _ => mark(I.RET{r=zeroR,b=C.returnAddr,d=0},an)
1527            | T.STORE(8,ea,data,mem) => store8(ea,data,mem,an)            | T.STORE(8,ea,data,mem) => store8(ea,data,mem,an)
1528            | T.STORE(16,ea,data,mem) => store16(ea,data,mem,an)            | T.STORE(16,ea,data,mem) => store16(ea,data,mem,an)
# Line 1466  Line 1533 
1533            | T.DEFINE l => defineLabel l            | T.DEFINE l => defineLabel l
1534            | T.ANNOTATION(s,a) => stmt(s,a::an)            | T.ANNOTATION(s,a) => stmt(s,a::an)
1535            | T.EXT s => ExtensionComp.compileSext (reducer()) {stm=s,an=an}            | T.EXT s => ExtensionComp.compileSext (reducer()) {stm=s,an=an}
1536              | T.LIVE rs => mark'(I.LIVE{regs=cellset rs, spilled=[]}, an)
1537              | T.KILL rs => mark'(I.KILL{regs=cellset rs, spilled=[]}, an)
1538            | s => doStmts (Gen.compileStm s)            | s => doStmts (Gen.compileStm s)
1539    
1540        and reducer() =        and reducer() =
1541            T.REDUCER{reduceRexp    = expr,            TS.REDUCER{reduceRexp    = expr,
1542                      reduceFexp    = fexpr,                      reduceFexp    = fexpr,
1543                      reduceCCexp   = ccExpr,                      reduceCCexp   = ccExpr,
1544                      reduceStm     = stmt,                      reduceStm     = stmt,
1545                      operand       = opn,                      operand       = opn,
1546                      reduceOperand = reduceOpn,                      reduceOperand = reduceOpn,
1547                      addressOf     = addr,                      addressOf     = addr,
1548                      emit          = mark,                       emit          = emitInstruction o annotate,
1549                      instrStream   = instrStream,                      instrStream   = instrStream,
1550                      mltreeStream  = self()                      mltreeStream  = self()
1551                     }                     }
# Line 1497  Line 1566 
1566            in  g(mlrisc, C.empty) end            in  g(mlrisc, C.empty) end
1567    
1568        and self() =        and self() =
1569            S.STREAM            TS.S.STREAM
1570           { beginCluster= beginCluster,           { beginCluster= beginCluster,
1571             endCluster  = endCluster,             endCluster  = endCluster,
1572             emit        = doStmt,             emit        = doStmt,
# Line 1506  Line 1575 
1575             entryLabel  = entryLabel,             entryLabel  = entryLabel,
1576             comment     = comment,             comment     = comment,
1577             annotation  = annotation,             annotation  = annotation,
1578               getAnnotations = getAnnotations,
1579             exitBlock   = fn regs => exitBlock(cellset regs)             exitBlock   = fn regs => exitBlock(cellset regs)
1580           }           }
1581     in  self()     in  self()

Legend:
Removed from v.788  
changed lines
  Added in v.1335

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