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
 [smlnj] / sml / trunk / src / MLRISC / alpha / mltree / alpha.sml

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

revision 651, Thu Jun 1 18:34:03 2000 UTC revision 788, Wed Feb 28 04:09:48 2001 UTC
# Line 10  Line 10
10
11  functor Alpha  functor Alpha
12     (structure AlphaInstr : ALPHAINSTR     (structure AlphaInstr : ALPHAINSTR
structure AlphaMLTree : MLTREE
13      structure PseudoInstrs : ALPHA_PSEUDO_INSTR      structure PseudoInstrs : ALPHA_PSEUDO_INSTR
14      structure ExtensionComp : MLTREE_EXTENSION_COMP      structure ExtensionComp : MLTREE_EXTENSION_COMP
15         where T = AlphaMLTree and I = AlphaInstr         where I = AlphaInstr
sharing AlphaMLTree.Region   = AlphaInstr.Region
sharing AlphaMLTree.LabelExp = AlphaInstr.LabelExp
16         sharing PseudoInstrs.I = AlphaInstr         sharing PseudoInstrs.I = AlphaInstr
sharing PseudoInstrs.T = AlphaMLTree
17
18        (* Cost of multiplication in cycles *)        (* Cost of multiplication in cycles *)
19      val multCost : int ref      val multCost : int ref
# Line 37  Line 33
33     ) : MLTREECOMP =     ) : MLTREECOMP =
34  struct  struct
35
structure T   = AlphaMLTree
structure S   = T.Stream
structure R   = AlphaMLTree.Region
36    structure I   = AlphaInstr    structure I   = AlphaInstr
37    structure C   = AlphaInstr.C    structure C   = I.C
38    structure LE  = I.LabelExp    structure T   = I.T
39      structure S   = T.Stream
40      structure R   = T.Region
41    structure W32 = Word32    structure W32 = Word32
42    structure P   = PseudoInstrs    structure P   = PseudoInstrs
43    structure A   = MLRiscAnnotations    structure A   = MLRiscAnnotations
# Line 146  Line 141
141
142    fun error msg = MLRiscErrorMsg.error("Alpha",msg)    fun error msg = MLRiscErrorMsg.error("Alpha",msg)
143
144    type instrStream = (I.instruction,C.regmap,C.cellset) T.stream    type instrStream = (I.instruction,C.cellset) T.stream
145    type mltreeStream = (T.stm,C.regmap,T.mlrisc list) T.stream    type mltreeStream = (T.stm,T.mlrisc list) T.stream
146
147    (*    (*
148     * This module is used to simulate operations of non-standard widths.     * This module is used to simulate operations of non-standard widths.
# Line 159  Line 154
154                              val rep = SE                              val rep = SE
155                             )                             )
156
157    val zeroR   = C.GPReg 31    val zeroR   = C.r31
158    val zeroOpn = I.REGop zeroR    val zeroOpn = I.REGop zeroR
159      fun LI i    = T.LI(T.I.fromInt(32, i))
160      fun toInt i = T.I.toInt(32, i)
161      val int_0   = T.I.int_0
162      val int_1   = T.I.int_1
163      fun EQ(x:IntInf.int,y) = x=y
164
165    (*    (*
166     * Specialize the modules for multiplication/division     * Specialize the modules for multiplication/division
# Line 283  Line 282
282     * The main stuff     * The main stuff
283     *)     *)
284
285    datatype times4or8 = TIMES1    datatype times4or8 = TIMES1 | TIMES4 | TIMES8
| TIMES4
| TIMES8
286    datatype zeroOne   = ZERO | ONE | OTHER    datatype zeroOne   = ZERO | ONE | OTHER
287    datatype commutative = COMMUTE | NOCOMMUTE    datatype commutative = COMMUTE | NOCOMMUTE
288
289    val zeroFR = C.FPReg 31    val zeroFR = C.f31
290    val zeroEA = I.Direct zeroR    val zeroEA = I.Direct zeroR
291    val zeroT  = T.LI 0    val zeroT  = T.LI int_0
292    val trapb = [I.TRAPB]    val trapb = [I.TRAPB]
293    val zeroImm = I.IMMop 0    val zeroImm = I.IMMop 0
294
# Line 299  Line 296
296          (instrStream as          (instrStream as
297           S.STREAM{emit,beginCluster,endCluster,           S.STREAM{emit,beginCluster,endCluster,
298                    defineLabel,entryLabel,pseudoOp,annotation,                    defineLabel,entryLabel,pseudoOp,annotation,
299                    exitBlock,phi,alias,comment,...}) =                    exitBlock,comment,...}) =
300    let    let
301        infix || && << >> ~>>        infix || && << >> ~>>
302
# Line 349  Line 346
346              in  emit(I.LDA{r=r, b=base, d=offset}); r end              in  emit(I.LDA{r=r, b=base, d=offset}); r end
347
349        fun loadImmed(n, base, rd, an) =        fun loadImmed(n, base, rd, an) = let
350        if n =0 then          val n = T.I.toInt32(32, n)
351           move(base, rd, an)        in
352            if n = 0 then move(base, rd, an)
353        else if ~32768 <= n andalso n < 32768 then        else if ~32768 <= n andalso n < 32768 then
354           mark(I.LDA{r=rd, b=base, d=I.IMMop n},an)            mark(I.LDA{r=rd, b=base, d=I.IMMop(Int32.toInt n)}, an)
355        else          else loadImmed32(n, base, rd, an)
let val w = itow n
val hi = Word.~>>(w, 0w16)
val lo = Word.andb(w, 0w65535)
val (hi', lo') =
if lo < 0w32768 then (hi, lo) else (hi+0w1, lo-0w65536)
val t = lda(base,I.IMMop(wtoi lo'))
in  mark(I.LDAH{r=rd, b=t, d=I.IMMop(wtoi hi')},an)
356        end        end
357
359         * In either case we sign extend the 32-bit value. This is compatible         * In either case we sign extend the 32-bit value. This is compatible
360         * with LDL which sign extends a 32-bit valued memory location.         * with LDL which sign extends a 32-bit valued memory location.
361         *)         *)
362        and loadImmed32(0w0, base, rd, an) =        (* TODO:
363             move(base, rd, an)         *  Should handle 64 bits if immediate is not in the 32 bit range.
364          | loadImmed32(n, base, rd, an) = let         *)
365              val low = W32.andb(n, 0w65535)  (* unsigned (0 .. 65535) *)        and loadImmed32(n, base, rd, an) = let
366              val high = W32.~>>(n, 0w16)     (* signed (~32768 .. 32768] *)          fun immed(0, high) =
367                   mark(I.LDAH{r=rd, b=base, d=I.IMMop(high)},an)                   mark(I.LDAH{r=rd, b=base, d=I.IMMop(high)},an)
368                | loadimmed(low, 0) =            | immed(low, 0) =
369                   mark(I.LDA{r=rd, b=base, d=I.IMMop(low)},an)                   mark(I.LDA{r=rd, b=base, d=I.IMMop(low)},an)
370                | loadimmed(low, high) =            | immed(low, high) =
371                   (emit(I.LDA{r=rd, b=base, d=I.IMMop(low)});                   (emit(I.LDA{r=rd, b=base, d=I.IMMop(low)});
372                    mark(I.LDAH{r=rd, b=rd, d=I.IMMop(high)},an))                 mark(I.LDAH{r=rd, b=rd, d=I.IMMop(high)}, an)
373                   )
374            val w = Word32.fromLargeInt(Int32.toLarge n)
375            val low = W32.andb(w, 0wxffff)
376            val high = W32.~>>(w, 0w16)
377            in            in
378              if W32.<(low, 0w32768) then          if W32.<(low, 0wx8000) then
379                 loadimmed(W32.toInt low, W32.toIntX high)            immed(W32.toInt low, W32.toIntX high)
380              else let (* low = (32768 .. 65535) *)          else let
381                 val lowsgn = W32.-(low, 0w65536) (* signed (~1 .. ~32768)  *)              val low = W32.toIntX(W32.-(low, 0wx10000))
382                 val highsgn = W32.+(high, 0w1)   (* (~32768 .. 32768) *)              val high = W32.toIntX(W32.+(high, 0w1))
val ilow = W32.toIntX lowsgn
val ihigh = W32.toIntX highsgn
383               in               in
384                 if ihigh <> 32768 then loadimmed(ilow, ihigh)              if high <> 0x8000 then immed(low, high)
385                 else              else let (* transition of high from pos to neg *)
386                 let val tmpR1 = newReg()                  val tmpR1 = newReg()
387                     val tmpR2 = newReg()                     val tmpR2 = newReg()
388                     val tmpR3 = newReg()                     val tmpR3 = newReg()
389                 in                 in
390                   (* you gotta do what you gotta do! *)                  (* you just gotta do, what you gotta do! *)
391                   emit(I.LDA{r=tmpR3, b=base, d=I.IMMop(ilow)});                  emit(I.LDA{r=tmpR3, b=base, d=I.IMMop(low)});
393                   emit(I.OPERATE{oper=I.SLL, ra=tmpR1, rb=I.IMMop 31, rc=tmpR2});                   emit(I.OPERATE{oper=I.SLL, ra=tmpR1, rb=I.IMMop 31, rc=tmpR2});
rc=rd},an)
395                 end                 end
396               end               end
397             end             end
398
399
400        (* emit load label *)        (* emit load label expression *)
402
403        (* emit a copy *)        (* emit a copy *)
404        and copy(dst,src,an) =        and copy(dst,src,an) =
# Line 424  Line 413
413                             [_] => NONE | _ => SOME(I.FDirect(newFreg()))},an)                             [_] => NONE | _ => SOME(I.FDirect(newFreg()))},an)
414
415        and move(s,d,an) =        and move(s,d,an) =
416            if s = d orelse d = zeroR then () else            if C.sameCell(s,d) orelse C.sameCell(d,zeroR) then () else
417            mark(I.COPY{dst=[d],src=[s],impl=ref NONE,tmp=NONE},an)            mark(I.COPY{dst=[d],src=[s],impl=ref NONE,tmp=NONE},an)
418
419        and fmove(s,d,an) =        and fmove(s,d,an) =
420            if s = d orelse d = zeroFR then () else            if C.sameCell(s,d) orelse C.sameCell(d,zeroFR) then () else
421            mark(I.FCOPY{dst=[d],src=[s],impl=ref NONE,tmp=NONE},an)            mark(I.FCOPY{dst=[d],src=[s],impl=ref NONE,tmp=NONE},an)
422
423         (* emit an sign extension op *)         (* emit an sign extension op *)
# Line 475  Line 464
464        (* convert an expression into an operand *)        (* convert an expression into an operand *)
465        and opn(T.REG(_,r)) = I.REGop r        and opn(T.REG(_,r)) = I.REGop r
466          | opn(e as T.LI n) =          | opn(e as T.LI n) =
467              if n <= 255 andalso n >= 0 then I.IMMop n              if IntInf.<=(n, T.I.int_0xff) andalso IntInf.>=(n, T.I.int_0) then
468                  I.IMMop(toInt(n))
469              else let val tmpR = newReg()              else let val tmpR = newReg()
471          | opn(e as T.LI32 w) =          | opn(e as (T.CONST _ | T.LABEL _)) = I.LABop e
472              if w <= 0w255 then I.IMMop(W32.toIntX w)          | opn(T.LABEXP x) = I.LABop x
else let val tmpR = newReg()
| opn(T.CONST c) = I.LABop(LE.CONST c)
473          | opn e = I.REGop(expr e)          | opn e = I.REGop(expr e)
474
475        (* compute base+displacement from an expression        (* compute base+displacement from an expression
476         *)         *)
478            let fun toLexp(I.IMMop i) = LE.INT i            let fun toLexp(I.IMMop i) = T.LI(IntInf.fromInt i)
479                  | toLexp(I.LABop le) = le                  | toLexp(I.LABop le) = le
480                  | toLexp _ = error "addr.toLexp"                  | toLexp _ = error "addr.toLexp"
481
486                fun addC(c,I.IMMop 0) = I.LABop(LE.CONST c)
487                  | addC(c,disp) = I.LABop(LE.PLUS(LE.CONST c,toLexp disp))                fun addLe(ty,le,I.IMMop 0) = I.LABop le
489                  | addL(l,disp) = I.LABop(LE.PLUS(l,toLexp disp))
490                fun sub(n,I.IMMop m) = I.IMMop(m-n)                fun sub(t,n,I.IMMop m) =
491                  | sub(n,I.LABop le) = I.LABop(LE.MINUS(le,LE.INT n))                    I.IMMop(toInt(T.I.SUB(t,IntInf.fromInt m,n)))
492                  | sub(n,_) = error "addr.sub"                  | sub(t,n,I.LABop le) = I.LABop(T.SUB(t,le,T.LI n))
493                fun sub32(n,disp) = sub(W32.toIntX n,disp)                  | sub(t,n,_) = error "addr.sub"
494                fun subC(c,disp) = I.LABop(LE.MINUS(toLexp disp, LE.CONST c))
495                fun subL(l,disp) = I.LABop(LE.MINUS(toLexp disp, l))                fun subLe(ty,le,I.IMMop 0) = I.LABop le
496                    | subLe(ty,le,disp) = I.LABop(T.SUB(ty,le,toLexp disp))
497
498                (* Should really take into account of the address width XXX *)                (* Should really take into account of the address width XXX *)
507                  | fold(T.SUB(_,e,T.LI n),disp) = fold(e, sub(n,disp))                  | fold(T.SUB(t,e,T.LI n),disp) = fold(e,sub(t,n,disp))
508                  | fold(T.SUB(_,e,T.LI32 n),disp) = fold(e, sub32(n,disp))                  | fold(T.SUB(t,e,x as T.CONST _),disp) = fold(e,subLe(t,x,disp))
509                  | fold(T.SUB(_,e,T.CONST n),disp) = fold(e, subC(n,disp))                  | fold(T.SUB(t,e,x as T.LABEL _),disp) = fold(e,subLe(t,x,disp))
510                  | fold(T.SUB(_,e,T.LABEL l),disp) = fold(e, subL(l,disp))                  | fold(T.SUB(t,e,T.LABEXP l),disp) = fold(e,subLe(t,l,disp))
511                  | fold(e,disp) = (expr e,disp)                  | fold(e,disp) = (expr e,disp)
512
513            in  makeEA(fold(exp, zeroImm))            in  makeEA(fold(exp, zeroImm))
# Line 536  Line 524
524                 end                 end
525             end             end
526          | offset(base,disp as I.LABop le,off) =          | offset(base,disp as I.LABop le,off) =
527             (base, I.LABop(LE.PLUS(le,LE.INT off)))             (base, I.LABop(T.ADD(64,le,T.LI(IntInf.fromInt off))))
528          | offset(base,disp,off) =          | offset(base,disp,off) =
529             let val tmp = newReg()             let val tmp = newReg()
# Line 562  Line 550
550
551        (* look for multiply by 4 and 8 of the given type *)        (* look for multiply by 4 and 8 of the given type *)
552        and times4or8(ty,e) =        and times4or8(ty,e) =
553            let fun f(t,a,n) = if t = ty then            let
554                                 if n = 4 then (TIMES4,a)                fun f(t,a,n) = if t = ty then
555                                 else if n = 8 then (TIMES8,a)                                 if EQ(n, T.I.int_4) then (TIMES4,a)
556                                 else (TIMES1,e)                                 else if EQ(n, T.I.int_8) then (TIMES8,a)
else (TIMES1,e)
fun g(t,a,n) = if t = ty then
if n = 0w4 then (TIMES4,a)
else if n = 0w8 then (TIMES8,a)
557                                 else (TIMES1,e)                                 else (TIMES1,e)
558                               else (TIMES1,e)                               else (TIMES1,e)
559
560                fun u(t,a,n) = if t = ty then                fun u(t,a,n) = if t = ty then
561                                 if n = 2 then (TIMES4,a)                                 if EQ(n, T.I.int_2) then (TIMES4,a)
562                                 else if n = 3 then (TIMES8,a)                                 else if EQ(n, T.I.int_3) then (TIMES8,a)
else (TIMES1,e)
else (TIMES1,e)
fun v(t,a,n) = if t = ty then
if n = 0w2 then (TIMES4,a)
else if n = 0w3 then (TIMES8,a)
563                                 else (TIMES1,e)                                 else (TIMES1,e)
564                               else (TIMES1,e)                               else (TIMES1,e)
565            in  case e of            in  case e of
566                  T.MULU(t,a,T.LI n)   => f(t,a,n)                  T.MULU(t,a,T.LI n)   => f(t,a,n)
| T.MULU(t,a,T.LI32 n) => g(t,a,n)
567                | T.MULS(t,T.LI n,a)   => f(t,a,n)                | T.MULS(t,T.LI n,a)   => f(t,a,n)
| T.MULS(t,T.LI32 n,a) => g(t,a,n)
568                | T.SLL(t,a,T.LI n)    => u(t,a,n)                | T.SLL(t,a,T.LI n)    => u(t,a,n)
| T.SLL(t,a,T.LI32 n)  => v(t,a,n)
569                | _                    => (TIMES1,e)                | _                    => (TIMES1,e)
570            end            end
571
# Line 620  Line 597
597                   (* use LDA to handle subtraction when possible                   (* use LDA to handle subtraction when possible
598                    * Note: this may have sign extension problems later.                    * Note: this may have sign extension problems later.
599                    *)                    *)
600                   T.LI i => (loadImmed(~i,expr a,d,an) handle Overflow =>                   T.LI i => (loadImmed(T.I.NEGT(32,i),expr a,d,an) handle _ =>
601                                arith(sub,a,b,d,an))                                arith(sub,a,b,d,an))
602                |  _ => arith(sub,a,b,d,an)                |  _ => arith(sub,a,b,d,an)
603                ) else arith(sub,a,b,d,an)                ) else arith(sub,a,b,d,an)
604            )            )
605
606        (* look for special constants *)        (* look for special constants *)
607        and wordOpn(T.LI n) = SOME(W32.fromInt n)        and wordOpn(T.LI n) = SOME(T.I.toWord32(32, n))
| wordOpn(T.LI32 w) = SOME w
608          | wordOpn e = NONE          | wordOpn e = NONE
609
610        (* look for special byte mask constants        (* look for special byte mask constants
# Line 659  Line 635
636              ~1 => (case byteMask(ty,wordOpn b) of              ~1 => (case byteMask(ty,wordOpn b) of
637                      ~1 => commArith(I.AND,a,b,d,an)                      ~1 => commArith(I.AND,a,b,d,an)
639                    )                    )
641
642        (* generate sll/sra/srl *)        (* generate sll/sra/srl *)
643        and sll32(a,b,d,an) =        and sll32(a,b,d,an) =
# Line 725  Line 701
701                in mark'(instr,an)::trapb end                in mark'(instr,an)::trapb end
702                fun const(e,i) =                fun const(e,i) =
703                    let val r = expr e                    let val r = expr e
704                    in  if !useMultByConst andalso i >= 0 andalso i < 256 then                    in  if !useMultByConst andalso
705                           mark'(gen{ra=r,rb=I.IMMop i,rc=rd},an)::trapb                             IntInf.>=(i, T.I.int_0) andalso
706                               IntInf.<(i, T.I.int_0x100) then
707                             mark'(gen{ra=r,rb=I.IMMop(toInt i),rc=rd},an)::trapb
708                        else                        else
709                           (genConst{r=r,i=i,d=rd}@trapb                           (genConst{r=r,i=toInt i,d=rd}@trapb
710                            handle _ => nonconst(T.REG(ty,r),T.LI i))                            handle _ => nonconst(T.REG(ty,r),T.LI i))
711                    end                    end
fun constw(e,i) = const(e,Word32.toInt i)
handle _ => nonconst(e,T.LI32 i)
712                val instrs =                val instrs =
713                    case (e1,e2) of                  case (e1, e2)
714                       (e1,T.LI i)   => const(e1,i)                  of (_, T.LI i) => const(e1, i)
715                     | (e1,T.LI32 i) => constw(e1,i)                   | (T.LI i, _) => const(e2, i)
| (T.LI i,e2)   => const(e2,i)
| (T.LI32 i,e2) => constw(e2,i)
716                     | _             => nonconst(e1,e2)                     | _             => nonconst(e1,e2)
717            in  app emit instrs            in  app emit instrs
718            end            end
# Line 769  Line 743
743                fun const(e,i) =                fun const(e,i) =
744                    let val r = expr e                    let val r = expr e
745                    in  genDiv{mode=T.TO_ZERO,stm=doStmt}                    in  genDiv{mode=T.TO_ZERO,stm=doStmt}
746                              {r=r,i=i,d=rd}                              {r=r,i=toInt i,d=rd}
747                        handle _ => nonconst(T.REG(ty,r),T.LI i)                        handle _ => nonconst(T.REG(ty,r),T.LI i)
748                    end                    end
fun constw(e,i) = const(e,Word32.toInt i)
handle _ => nonconst(e,T.LI32 i)
749                val instrs =                val instrs =
750                    case e2 of                    case e2 of
751                       T.LI i   => const(e1,i)                       T.LI i   => const(e1,i)
| T.LI32 i => constw(e1,i)
752                     | _        => nonconst(e1,e2)                     | _        => nonconst(e1,e2)
753            in  app emit instrs            in  app emit instrs
754            end            end
# Line 923  Line 894
894            app emit (pseudo{mode=rounding, fs=fexpr e, rd=rd})            app emit (pseudo{mode=rounding, fs=fexpr e, rd=rd})
895
896        (* generate an expression and return the register that holds the result *)        (* generate an expression and return the register that holds the result *)
897        and expr(T.REG(_,r)) = r        and expr(e) = let
898          | expr(T.LI 0) = zeroR          fun comp() = let
899          | expr(T.LI32 0w0) = zeroR            val r = newReg()
900            in doExpr(e, r, []); r
901            end
902          in
903            case e
904            of T.REG(_, r) => r
905             | T.LI z => if T.I.isZero(z) then zeroR else comp()
906              (* On the alpha: all 32 bit values are already sign extended.              (* On the alpha: all 32 bit values are already sign extended.
907               * So no sign extension is necessary               * So no sign extension is necessary
908               *)               *)
909          | expr(T.CVTI2I(64, T.SIGN_EXTEND, 32, e)) = expr e           | T.SX(64, 32, e) => expr e
910          | expr(T.CVTI2I(64, T.ZERO_EXTEND, 32, e)) = expr e           | T.ZX(64, 32, e) => expr e
911             | _ => comp()
912          | expr e = let val r = newReg()        end
in  doExpr(e,r,[]); r end
913
914        (* generate an expression that targets register d *)        (* generate an expression that targets register d *)
915        and doExpr(exp,d,an) =        and doExpr(exp,d,an) =
916            case exp of            case exp of
917              T.REG(_,r) => move(r,d,an)              T.REG(_,r) => move(r,d,an)
922
923              (* special optimizations for additions and subtraction              (* special optimizations for additions and subtraction
924               * Question: using LDA for all widths is not really correct               * Question: using LDA for all widths is not really correct
925               * since the result may not fit into the sign extension scheme.               * since the result may not fit into the sign extension scheme.
926               *)               *)
927            | T.ADD(64,e,T.LABEL le) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)            | T.ADD(64,e,T.LABEXP le) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)
928            | T.ADD(64,T.LABEL le,e) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)            | T.ADD(64,T.LABEXP le,e) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)
929            | T.ADD(64,e,T.CONST c)  =>            | T.ADD(64,e,x as (T.CONST _ | T.LABEL _))  =>
930                 mark(I.LDA{r=d,b=expr e,d=I.LABop(LE.CONST c)},an)                 mark(I.LDA{r=d,b=expr e,d=I.LABop x},an)
931            | T.ADD(64,T.CONST c,e)  =>            | T.ADD(64,x as (T.CONST _ | T.LABEL _),e)  =>
932                 mark(I.LDA{r=d,b=expr e,d=I.LABop(LE.CONST c)},an)                 mark(I.LDA{r=d,b=expr e,d=I.LABop x},an)
935            | T.ADD(64,e,T.LI32 i)   => loadImmed32(i, expr e, d, an)            | T.SUB(sz, a, b as T.LI z)    =>
936            | T.ADD(64,T.LI32 i,e)   => loadImmed32(i, expr e, d, an)                if T.I.isZero(z) then
937            | T.SUB(_,a,(T.LI 0 | T.LI32 0w0)) => doExpr(a,d,an)                  doExpr(a,d,an)
938                  else (case sz
939                    of 32 => minus(32,I.SUBL,I.S4SUBL,I.S8SUBL,a,b,d,an)
940                     | 64 => minus(64,I.SUBQ,I.S4SUBQ,I.S8SUBQ,a,b,d,an)
941                     | _ =>  doExpr(Gen.compileRexp exp,d,an)
942                    (*esac*))
943
944              (* 32-bit support *)              (* 32-bit support *)
# Line 1032  Line 1013
1013            | T.NOTB(_,e) => arith(I.ORNOT,zeroT,e,d,an)            | T.NOTB(_,e) => arith(I.ORNOT,zeroT,e,d,an)
1014
# Line 1057  Line 1035
1035              )              )
1036
1037             (* conversion to boolean *)             (* conversion to boolean *)
1038            | T.COND(_,T.CMP(ty,cond,e1,e2),T.LI 1,T.LI 0) =>            | T.COND(_, T.CMP(ty,cond,e1,e2), x, y)  =>
1039                 (case (x, y)
1040                  of (T.LI n, T.LI m) =>
1041                    if EQ(n, int_1) andalso EQ(m, int_0) then
1042                 compare(ty,cond,e1,e2,d,an)                 compare(ty,cond,e1,e2,d,an)
1043            | T.COND(_,T.CMP(ty,cond,e1,e2),T.LI 0,T.LI 1) =>                  else if EQ(n, int_0) andalso EQ(m, int_1) then
1044                 compare(ty,T.Basis.negateCond cond,e1,e2,d,an)                 compare(ty,T.Basis.negateCond cond,e1,e2,d,an)
1045            | T.COND(_,T.CMP(ty,cond,e1,e2),x,y) =>                  else
1046                 cmove(ty,cond,e1,e2,x,y,d,an)                 cmove(ty,cond,e1,e2,x,y,d,an)
1047                  | _ => cmove(ty,cond,e1,e2,x,y,d,an)
1048                 (*esac*))
1049
1050            | T.LET(s,e) => (doStmt s; doExpr(e, d, an))            | T.LET(s,e) => (doStmt s; doExpr(e, d, an))
1051            | T.MARK(e,A.MARKREG f) => (f d; doExpr(e,d,an))            | T.MARK(e,A.MARKREG f) => (f d; doExpr(e,d,an))
# Line 1070  Line 1053
1053              (* On the alpha: all 32 bit values are already sign extended.              (* On the alpha: all 32 bit values are already sign extended.
1054               * So no sign extension is necessary               * So no sign extension is necessary
1055               *)               *)
1056            | T.CVTI2I(64, T.SIGN_EXTEND, 32, e) => doExpr(e, d, an)            | T.SX(64, 32, e) => doExpr(e, d, an)
1057            | T.CVTI2I(64, T.ZERO_EXTEND, 32, e) => doExpr(e, d, an)            | T.ZX(64, 32, e) => doExpr(e, d, an)
1058
1059            | T.PRED(e, c) => doExpr(e, d, A.CTRLUSE c::an)            | T.PRED(e, c) => doExpr(e, d, A.CTRLUSE c::an)
1060            | T.REXT e => ExtensionComp.compileRext (reducer()) {e=e, an=an, rd=d}            | T.REXT e => ExtensionComp.compileRext (reducer()) {e=e, an=an, rd=d}
# Line 1182  Line 1165
1165            | _ => error "doFexpr"            | _ => error "doFexpr"
1166
1167            (* check whether an expression is andb(e,1) *)            (* check whether an expression is andb(e,1) *)
1168        and isAndb1(T.ANDB(_,e,T.LI 1))     = (true,e)        and isAndb1(e as T.ANDB(_, e1, e2)) = let
1169          | isAndb1(T.ANDB(_,e,T.LI32 0w1)) = (true,e)              fun isOne(n, ei) =
1170          | isAndb1(T.ANDB(_,T.LI 1,e))     = (true,e)                if EQ(n, int_1) then (true, ei) else (false, e)
1171          | isAndb1(T.ANDB(_,T.LI32 0w1,e)) = (true,e)            in
1172                case(e1, e2)
1173                of (T.LI n, _) => isOne(n, e2)
1174                 | (_, T.LI n) => isOne(n, e1)
1175                 | _ => (false, e)
1176              end
1177          | isAndb1 e                       = (false,e)          | isAndb1 e                       = (false,e)
1178
1179        and zeroOrOne(T.LI 0)     = ZERO        and zeroOrOne(T.LI n) =
1180          | zeroOrOne(T.LI32 0w0) = ZERO          if T.I.isZero n then ZERO
1181          | zeroOrOne(T.LI 1)     = ONE          else if EQ(n, int_1) then ONE
1182          | zeroOrOne(T.LI32 0w1) = ONE               else OTHER
1183          | zeroOrOne _           = OTHER          | zeroOrOne _           = OTHER
1184
1185        (* compile a branch *)        (* compile a branch *)
# Line 1199  Line 1187
1187            case e of            case e of
1188              T.CMP(ty,cc,e1 as T.LI _,e2) =>              T.CMP(ty,cc,e1 as T.LI _,e2) =>
1189                 branchBS(ty,T.Basis.swapCond cc,e2,e1,lab,an)                 branchBS(ty,T.Basis.swapCond cc,e2,e1,lab,an)
| T.CMP(ty,cc,e1 as T.LI32 _,e2) =>
branchBS(ty,T.Basis.swapCond cc,e2,e1,lab,an)
1190            | T.CMP(ty,cc,e1,e2) => branchBS(ty,cc,e1,e2,lab,an)            | T.CMP(ty,cc,e1,e2) => branchBS(ty,cc,e1,e2,lab,an)
1191              (* generate an floating point branch *)              (* generate an floating point branch *)
1192            | T.FCMP(fty,cc,e1,e2) =>            | T.FCMP(fty,cc,e1,e2) =>
# Line 1244  Line 1230
1230                  | T.?<=  => bcc2(I.CMPTLESU, I.FBNE, I.CMPTUNSU, I.FBNE)                  | T.?<=  => bcc2(I.CMPTLESU, I.FBNE, I.CMPTUNSU, I.FBNE)
1231                  | T.<> => fall(I.CMPTEQSU, I.FBNE, I.CMPTUNSU, I.FBEQ)                  | T.<> => fall(I.CMPTEQSU, I.FBNE, I.CMPTUNSU, I.FBEQ)
1232                  | T.?= => bcc2(I.CMPTEQSU, I.FBNE, I.CMPTUNSU, I.FBNE)                  | T.?= => bcc2(I.CMPTEQSU, I.FBNE, I.CMPTUNSU, I.FBNE)
1233                    | _     => error "branch"
1234              end              end
1235            | e => mark(I.BRANCH{b=I.BNE,r=ccExpr e,lab=lab},an)            | e => mark(I.BRANCH{b=I.BNE,r=ccExpr e,lab=lab},an)
1236
# Line 1262  Line 1249
1249            (* generate a branch instruction.            (* generate a branch instruction.
1250             * Check for branch on zero as a special case             * Check for branch on zero as a special case
1251             *)             *)
1252        and branchIt(ty,cc,e,T.LI 0,lab,an) = branchIt0(cc,e,lab,an)
1253          | branchIt(ty,cc,e,T.LI32 0w0,lab,an) = branchIt0(cc,e,lab,an)        and branchIt(ty,cc,e1,e2 as T.LI z,lab,an) =
1254               if T.I.isZero z then branchIt0(cc,e1,lab,an)
1255               else branchItOther(ty,cc,e1,e2,lab,an)
1256          | branchIt(ty,cc,e1,e2,lab,an) = branchItOther(ty,cc,e1,e2,lab,an)          | branchIt(ty,cc,e1,e2,lab,an) = branchItOther(ty,cc,e1,e2,lab,an)
1257
1258            (* generate a branch instruction.            (* generate a branch instruction.
# Line 1279  Line 1268
1268          | branchIt0(T.GEU,e,lab,an) = (* always true! *) goto(lab,an)          | branchIt0(T.GEU,e,lab,an) = (* always true! *) goto(lab,an)
1269          | branchIt0(T.LTU,e,lab,an) = (* always false! *) ()          | branchIt0(T.LTU,e,lab,an) = (* always false! *) ()
1270          | branchIt0(T.LEU,e,lab,an) = br(I.BEQ,e,lab,an)  (* never < 0! *)          | branchIt0(T.LEU,e,lab,an) = br(I.BEQ,e,lab,an)  (* never < 0! *)
1271            | branchIt0 _               = error "brnachIt0"
1272
1273          (* Generate the operands for unsigned comparisons          (* Generate the operands for unsigned comparisons
1274           * Mask out high order bits whenever necessary.           * Mask out high order bits whenever necessary.
# Line 1326  Line 1316
1316                | T.LEU => unsignedCmp(ty,I.CMPULE,I.BNE)                | T.LEU => unsignedCmp(ty,I.CMPULE,I.BNE)
1317                | T.GTU => unsignedCmp(ty,I.CMPULE,I.BEQ)                | T.GTU => unsignedCmp(ty,I.CMPULE,I.BEQ)
1318                | T.GEU => unsignedCmp(ty,I.CMPULT,I.BEQ)                | T.GEU => unsignedCmp(ty,I.CMPULT,I.BEQ)
1319                  | _     => error "branchItOther"
1320            end            end
1321
1322           (* This function generates a conditional move:           (* This function generates a conditional move:
# Line 1340  Line 1331
1331                val (cond,a,b) =                val (cond,a,b) =
1332                  (* move the immed operand to b *)                  (* move the immed operand to b *)
1333                  case a of                  case a of
1334                    (T.LI _ | T.LI32 _ | T.CONST _) => (T.Basis.swapCond cond,b,a)                    (T.LI _ | T.CONST _ | T.LABEL _ | T.LABEXP _) =>
1335                        (T.Basis.swapCond cond,b,a)
1336                  | _ => (cond,a,b)                  | _ => (cond,a,b)
1337
1338                fun sub(a,(T.LI 0 | T.LI32 0w0)) = expr a                fun sub(a, T.LI z) =
1339                       if T.I.isZero z then expr a else expr(T.SUB(ty,a,b))
1340                  | sub(a,b)                     = expr(T.SUB(ty,a,b))                  | sub(a,b)                     = expr(T.SUB(ty,a,b))
1341
1342                fun cmp(cond,e1,e2) =                fun cmp(cond,e1,e2) =
# Line 1359  Line 1352
1352                  | (T.NE,(true,e),ONE)  => (I.CMOVLBC,expr e,x,y)                  | (T.NE,(true,e),ONE)  => (I.CMOVLBC,expr e,x,y)
1353                       (* signed  *)                       (* signed  *)
1354                  | (T.EQ,_,_)           => (I.CMOVEQ,sub(a,b),x,y)                  | (T.EQ,_,_)           => (I.CMOVEQ,sub(a,b),x,y)
1355                  | (T.NE,_,_)           => (I.CMOVEQ,cmp(T.EQ,a,b),y,x)                  | (T.NE,_,_)           => (I.CMOVNE,sub(a,b),x,y)
1356                  | (T.GT,_,_)           => (I.CMOVGT,sub(a,b),x,y)                  | (T.GT,_,_)           => (I.CMOVGT,sub(a,b),x,y)
1357                  | (T.GE,_,_)           => (I.CMOVGE,sub(a,b),x,y)                  | (T.GE,_,_)           => (I.CMOVGE,sub(a,b),x,y)
1358                  | (T.LT,_,_)           => (I.CMOVLT,sub(a,b),x,y)                  | (T.LT,_,_)           => (I.CMOVLT,sub(a,b),x,y)
# Line 1370  Line 1363
1363                  | (T.LEU,_,_)          => (I.CMOVEQ,cmp(T.GTU,a,b),x,y)                  | (T.LEU,_,_)          => (I.CMOVEQ,cmp(T.GTU,a,b),x,y)
1364                  | (T.GTU,_,_)          => (I.CMOVEQ,cmp(T.LEU,a,b),x,y)                  | (T.GTU,_,_)          => (I.CMOVEQ,cmp(T.LEU,a,b),x,y)
1365                  | (T.GEU,_,_)          => (I.CMOVEQ,cmp(T.LTU,a,b),x,y)                  | (T.GEU,_,_)          => (I.CMOVEQ,cmp(T.LTU,a,b),x,y)
1366                    | _                    => error "cmove"
1367            in  mark(I.CMOVE{oper=oper,ra=ra,rb=opn x,rc=tmp},an); (* true case *)            in  mark(I.CMOVE{oper=oper,ra=ra,rb=opn x,rc=tmp},an); (* true case *)
1368                move(tmp, d, [])                move(tmp, d, [])
1369            end            end
# Line 1401  Line 1395
1395                    end                    end
1396                val (cond,e1,e2) =                val (cond,e1,e2) =
1397                    case e1 of                    case e1 of
1398                      (T.LI _ | T.LI32 _ | T.CONST _) =>                      (T.LI _ | T.CONST _ | T.LABEL _ | T.LABEXP _) =>
1399                         (T.Basis.swapCond cond,e2,e1)                         (T.Basis.swapCond cond,e2,e1)
1400                    | _ => (cond,e1,e2)                    | _ => (cond,e1,e2)
1401            in  case cond of            in  case cond of
# Line 1415  Line 1409
1409                | T.GEU => unsignedCmp(ty,I.CMPULE,e2,e1,d)                | T.GEU => unsignedCmp(ty,I.CMPULE,e2,e1,d)
1410                | T.LTU => unsignedCmp(ty,I.CMPULT,e1,e2,d)                | T.LTU => unsignedCmp(ty,I.CMPULT,e1,e2,d)
1411                | T.LEU => unsignedCmp(ty,I.CMPULE,e1,e2,d)                | T.LEU => unsignedCmp(ty,I.CMPULE,e1,e2,d)
1412                  | _     => error "compare"
1413            end            end
1414
1415           (* generate an unconditional branch *)           (* generate an unconditional branch *)
# Line 1426  Line 1421
1421             val uses=cellset uses             val uses=cellset uses
1422             val instr =             val instr =
1423                 case (ea, flow) of                 case (ea, flow) of
1424                   (T.LABEL(LE.LABEL lab), [_]) =>                   (T.LABEL lab, [_]) =>
1427                              d=0,defs=defs,uses=uses,mem=mem}                              d=0,defs=defs,uses=uses,mem=mem}
# Line 1456  Line 1451
1451            | T.CCMV(r,e) => doCCexpr(e,r,an)            | T.CCMV(r,e) => doCCexpr(e,r,an)
1452            | T.COPY(ty,dst,src) => copy(dst,src,an)            | T.COPY(ty,dst,src) => copy(dst,src,an)
1453            | T.FCOPY(ty,dst,src) => fcopy(dst,src,an)            | T.FCOPY(ty,dst,src) => fcopy(dst,src,an)
1454            | T.JMP(ctrl,T.LABEL(LE.LABEL lab),_) => goto(lab,an)            | T.JMP(T.LABEL lab,_) => goto(lab,an)
1455            | T.JMP(ctrl,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)
1456            | T.BCC(ctrl,cc,lab) => branch(cc,lab,an)            | T.BCC(cc,lab) => branch(cc,lab,an)
1457            | T.CALL{funct,targets,defs,uses,cdefs,cuses,region} =>            | T.CALL{funct,targets,defs,uses,region,...} =>
1458                call(funct,targets,defs,uses,region,an)                call(funct,targets,defs,uses,region,an)
1460            | T.STORE(8,ea,data,mem) => store8(ea,data,mem,an)            | T.STORE(8,ea,data,mem) => store8(ea,data,mem,an)
# Line 1511  Line 1506
1506             entryLabel  = entryLabel,             entryLabel  = entryLabel,
1507             comment     = comment,             comment     = comment,
1508             annotation  = annotation,             annotation  = annotation,
1509             exitBlock   = fn regs => exitBlock(cellset regs),             exitBlock   = fn regs => exitBlock(cellset regs)
alias       = alias,
phi         = phi
1510           }           }
1511     in  self()     in  self()
1512     end     end

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