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 760, Fri Dec 22 14:15:24 2000 UTC revision 761, Sat Dec 23 05:37:37 2000 UTC
# Line 161  Line 161 
161    
162    val zeroR   = C.r31    val zeroR   = C.r31
163    val zeroOpn = I.REGop zeroR    val zeroOpn = I.REGop zeroR
164      fun LI i    = T.LI(T.I.fromInt(32, i))
165      fun toInt i = T.I.toInt(32, i)
166      val int_0   = T.I.int_0
167      val int_1   = T.I.int_1
168      fun EQ(x,y) = T.I.EQ(32, x, y)
169      fun GE(x,y) = T.I.GE(32, x, y)
170      fun LE(x,y) = T.I.LE(32, x, y)
171      fun LT(x,y) = T.I.LT(32, x, y)
172    
173    (*    (*
174     * Specialize the modules for multiplication/division     * Specialize the modules for multiplication/division
# Line 282  Line 290 
290     * The main stuff     * The main stuff
291     *)     *)
292    
293    datatype times4or8 = TIMES1    datatype times4or8 = TIMES1 | TIMES4 | TIMES8
                      | TIMES4  
                      | TIMES8  
294    datatype zeroOne   = ZERO | ONE | OTHER    datatype zeroOne   = ZERO | ONE | OTHER
295    datatype commutative = COMMUTE | NOCOMMUTE    datatype commutative = COMMUTE | NOCOMMUTE
296    
297    val zeroFR = C.f31    val zeroFR = C.f31
298    val zeroEA = I.Direct zeroR    val zeroEA = I.Direct zeroR
299    val zeroT  = T.LI 0    val zeroT  = T.LI int_0
300    val trapb = [I.TRAPB]    val trapb = [I.TRAPB]
301    val zeroImm = I.IMMop 0    val zeroImm = I.IMMop 0
302    
# Line 348  Line 354 
354              in  emit(I.LDA{r=r, b=base, d=offset}); r end              in  emit(I.LDA{r=r, b=base, d=offset}); r end
355    
356        (* emit load immed *)        (* emit load immed *)
357        fun loadImmed(n, base, rd, an) =        fun loadImmed(n, base, rd, an) = let
358        if n = 0 then          val n = T.I.toInt32(32, n)
359           move(base, rd, an)        in
360            if n = 0 then move(base, rd, an)
361        else if ~32768 <= n andalso n < 32768 then        else if ~32768 <= n andalso n < 32768 then
362           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)
363        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)  
364        end        end
365    
366        (* loadImmed32 is used to load int32 and word32 constants.        (* loadImmed32 is used to load int32 and word32 constants.
367         * 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
368         * with LDL which sign extends a 32-bit valued memory location.         * with LDL which sign extends a 32-bit valued memory location.
369         *)         *)
370        and loadImmed32(0w0, base, rd, an) =        (* TODO:
371             move(base, rd, an)         *  Should handle 64 bits if immediate is not in the 32 bit range.
372          | loadImmed32(n, base, rd, an) = let         *)
373              val low = W32.andb(n, 0w65535)  (* unsigned (0 .. 65535) *)        and loadImmed32(n, base, rd, an) = let
374              val high = W32.~>>(n, 0w16)     (* signed (~32768 .. 32768] *)          fun immed(0, high) =
             fun loadimmed(0, high) =  
375                   mark(I.LDAH{r=rd, b=base, d=I.IMMop(high)},an)                   mark(I.LDAH{r=rd, b=base, d=I.IMMop(high)},an)
376                | loadimmed(low, 0) =            | immed(low, 0) =
377                   mark(I.LDA{r=rd, b=base, d=I.IMMop(low)},an)                   mark(I.LDA{r=rd, b=base, d=I.IMMop(low)},an)
378                | loadimmed(low, high) =            | immed(low, high) =
379                   (emit(I.LDA{r=rd, b=base, d=I.IMMop(low)});                   (emit(I.LDA{r=rd, b=base, d=I.IMMop(low)});
380                    mark(I.LDAH{r=rd, b=rd, d=I.IMMop(high)},an))                 mark(I.LDAH{r=rd, b=rd, d=I.IMMop(high)}, an)
381                   )
382            val w = Word32.fromLargeInt(Int32.toLarge n)
383            val low = W32.andb(w, 0wxffff)
384            val high = W32.~>>(w, 0w16)
385            in            in
386              if W32.<(low, 0w32768) then          if W32.<(low, 0wx8000) then
387                 loadimmed(W32.toInt low, W32.toIntX high)            immed(W32.toInt low, W32.toIntX high)
388              else let (* low = (32768 .. 65535) *)          else let
389                 val lowsgn = W32.-(low, 0w65536) (* signed (~1 .. ~32768)  *)              val low = W32.toIntX(W32.-(low, 0wx10000))
390                 val highsgn = W32.+(high, 0w1)   (* (~32768 .. 32768) *)              val high = W32.toIntX(W32.+(high, 0w1))
                val ilow = W32.toIntX lowsgn  
                val ihigh = W32.toIntX highsgn  
391               in               in
392                 if ihigh <> 32768 then loadimmed(ilow, ihigh)              if high <> 0x8000 then immed(low, high)
393                 else              else let (* transition of high from pos to neg *)
394                 let val tmpR1 = newReg()                  val tmpR1 = newReg()
395                     val tmpR2 = newReg()                     val tmpR2 = newReg()
396                     val tmpR3 = newReg()                     val tmpR3 = newReg()
397                 in                 in
398                   (* you gotta do what you gotta do! *)                  (* you just gotta do, what you gotta do! *)
399                   emit(I.LDA{r=tmpR3, b=base, d=I.IMMop(ilow)});                  emit(I.LDA{r=tmpR3, b=base, d=I.IMMop(low)});
400                   emit(I.OPERATE{oper=I.ADDQ, ra=zeroR, rb=I.IMMop 1, rc=tmpR1});                   emit(I.OPERATE{oper=I.ADDQ, ra=zeroR, rb=I.IMMop 1, rc=tmpR1});
401                   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});
402                   mark(I.OPERATE{oper=I.ADDQ, ra=tmpR2, rb=I.REGop tmpR3,                  mark(I.OPERATE{oper=I.ADDQ, ra=tmpR2, rb=I.REGop tmpR3, rc=rd},an)
                                 rc=rd},an)  
403                 end                 end
404               end               end
405             end             end
406    
407    
408        (* emit load immed *)        (* emit load immed *)
409        and loadConst(c,d,an) = mark(I.LDA{r=d,b=zeroR,d=I.LABop(LE.CONST c)},an)        and loadConst(c,d,an) = mark(I.LDA{r=d,b=zeroR,d=I.LABop(LE.CONST c)},an)
410    
# Line 474  Line 475 
475        (* convert an expression into an operand *)        (* convert an expression into an operand *)
476        and opn(T.REG(_,r)) = I.REGop r        and opn(T.REG(_,r)) = I.REGop r
477          | opn(e as T.LI n) =          | opn(e as T.LI n) =
478              if n <= 255 andalso n >= 0 then I.IMMop n              if LE(n, T.I.int_0xff) andalso GE(n, T.I.int_0) then
479                  I.IMMop(toInt(n))
480              else let val tmpR = newReg()              else let val tmpR = newReg()
481                   in  loadImmed(n,zeroR,tmpR,[]); I.REGop tmpR end                   in  loadImmed(n,zeroR,tmpR,[]); I.REGop tmpR end
         | opn(e as T.LI32 w) =  
             if w <= 0w255 then I.IMMop(W32.toIntX w)  
             else let val tmpR = newReg()  
                  in  loadImmed32(w,zeroR,tmpR,[]); I.REGop tmpR end  
482          | opn(T.CONST c) = I.LABop(LE.CONST c)          | opn(T.CONST c) = I.LABop(LE.CONST c)
483          | opn e = I.REGop(expr e)          | opn e = I.REGop(expr e)
484    
# Line 491  Line 489 
489                  | toLexp(I.LABop le) = le                  | toLexp(I.LABop le) = le
490                  | toLexp _ = error "addr.toLexp"                  | toLexp _ = error "addr.toLexp"
491    
492                fun add(n,I.IMMop m) = I.IMMop(n+m)                fun add(n,I.IMMop m)  = I.IMMop(toInt n + m)
493                  | add(n,I.LABop le) = I.LABop(LE.PLUS(LE.INT n,le))                  | add(n,I.LABop le) = I.LABop(LE.PLUS(LE.INT(toInt(n)),le))
494                  | add(n,_) = error "addr.add"                  | add(n,_) = error "addr.add"
               fun add32(n,disp) = add(W32.toIntX n,disp) (* overflow XXX *)  
495                fun addC(c,I.IMMop 0) = I.LABop(LE.CONST c)                fun addC(c,I.IMMop 0) = I.LABop(LE.CONST c)
496                  | addC(c,disp) = I.LABop(LE.PLUS(LE.CONST c,toLexp disp))                  | addC(c,disp) = I.LABop(LE.PLUS(LE.CONST c,toLexp disp))
497                fun addL(l,I.IMMop 0) = I.LABop l                fun addL(l,I.IMMop 0) = I.LABop l
498                  | addL(l,disp) = I.LABop(LE.PLUS(l,toLexp disp))                  | addL(l,disp) = I.LABop(LE.PLUS(l,toLexp disp))
499                fun sub(n,I.IMMop m) = I.IMMop(m-n)                fun sub(n,I.IMMop m) = I.IMMop(m - toInt n)
500                  | sub(n,I.LABop le) = I.LABop(LE.MINUS(le,LE.INT n))                  | sub(n,I.LABop le) = I.LABop(LE.MINUS(le,LE.INT(toInt n)))
501                  | sub(n,_) = error "addr.sub"                  | sub(n,_) = error "addr.sub"
               fun sub32(n,disp) = sub(W32.toIntX n,disp)  
502                fun subC(c,disp) = I.LABop(LE.MINUS(toLexp disp, LE.CONST c))                fun subC(c,disp) = I.LABop(LE.MINUS(toLexp disp, LE.CONST c))
503                fun subL(l,disp) = I.LABop(LE.MINUS(toLexp disp, l))                fun subL(l,disp) = I.LABop(LE.MINUS(toLexp disp, l))
504    
505                (* Should really take into account of the address width XXX *)                (* Should really take into account of the address width XXX *)
506                fun fold(T.ADD(_,e,T.LI n),disp) = fold(e, add(n,disp))                fun fold(T.ADD(_,e,T.LI n),disp) = fold(e, add(n,disp))
                 | fold(T.ADD(_,e,T.LI32 n),disp) = fold(e, add32(n,disp))  
507                  | fold(T.ADD(_,e,T.CONST c),disp) = fold(e, addC(c,disp))                  | fold(T.ADD(_,e,T.CONST c),disp) = fold(e, addC(c,disp))
508                  | fold(T.ADD(_,e,T.LABEL l),disp) = fold(e, addL(l,disp))                  | fold(T.ADD(_,e,T.LABEL l),disp) = fold(e, addL(l,disp))
509                  | fold(T.ADD(_,T.LI n,e),disp) = fold(e, add(n,disp))                  | fold(T.ADD(_,T.LI n,e),disp) = fold(e, add(n,disp))
                 | fold(T.ADD(_,T.LI32 n, e),disp) = fold(e, add32(n,disp))  
510                  | fold(T.ADD(_,T.CONST n, e),disp) = fold(e, addC(n,disp))                  | fold(T.ADD(_,T.CONST n, e),disp) = fold(e, addC(n,disp))
511                  | fold(T.ADD(_,T.LABEL l, e),disp) = fold(e, addL(l,disp))                  | fold(T.ADD(_,T.LABEL l, e),disp) = fold(e, addL(l,disp))
512                  | fold(T.SUB(_,e,T.LI n),disp) = fold(e, sub(n,disp))                  | fold(T.SUB(_,e,T.LI n),disp) = fold(e, sub(n,disp))
                 | fold(T.SUB(_,e,T.LI32 n),disp) = fold(e, sub32(n,disp))  
513                  | fold(T.SUB(_,e,T.CONST n),disp) = fold(e, subC(n,disp))                  | fold(T.SUB(_,e,T.CONST n),disp) = fold(e, subC(n,disp))
514                  | fold(T.SUB(_,e,T.LABEL l),disp) = fold(e, subL(l,disp))                  | fold(T.SUB(_,e,T.LABEL l),disp) = fold(e, subL(l,disp))
515                  | fold(e,disp) = (expr e,disp)                  | fold(e,disp) = (expr e,disp)
# Line 561  Line 554 
554    
555        (* look for multiply by 4 and 8 of the given type *)        (* look for multiply by 4 and 8 of the given type *)
556        and times4or8(ty,e) =        and times4or8(ty,e) =
557            let fun f(t,a,n) = if t = ty then            let
558                                 if n = 4 then (TIMES4,a)                fun f(t,a,n) = if t = ty then
559                                 else if n = 8 then (TIMES8,a)                                 if EQ(n, T.I.int_4) then (TIMES4,a)
560                                 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)  
561                                 else (TIMES1,e)                                 else (TIMES1,e)
562                               else (TIMES1,e)                               else (TIMES1,e)
563    
564                fun u(t,a,n) = if t = ty then                fun u(t,a,n) = if t = ty then
565                                 if n = 2 then (TIMES4,a)                                 if EQ(n, T.I.int_2) then (TIMES4,a)
566                                 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)  
567                                 else (TIMES1,e)                                 else (TIMES1,e)
568                               else (TIMES1,e)                               else (TIMES1,e)
569            in  case e of            in  case e of
570                  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)  
571                | 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)  
572                | 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)  
573                | _                    => (TIMES1,e)                | _                    => (TIMES1,e)
574            end            end
575    
# Line 619  Line 601 
601                   (* use LDA to handle subtraction when possible                   (* use LDA to handle subtraction when possible
602                    * Note: this may have sign extension problems later.                    * Note: this may have sign extension problems later.
603                    *)                    *)
604                   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 _ =>
605                                arith(sub,a,b,d,an))                                arith(sub,a,b,d,an))
606                |  _ => arith(sub,a,b,d,an)                |  _ => arith(sub,a,b,d,an)
607                ) else arith(sub,a,b,d,an)                ) else arith(sub,a,b,d,an)
608            )            )
609    
610        (* look for special constants *)        (* look for special constants *)
611        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  
612          | wordOpn e = NONE          | wordOpn e = NONE
613    
614        (* look for special byte mask constants        (* look for special byte mask constants
# Line 658  Line 639 
639            case byteMask(ty,wordOpn a) of            case byteMask(ty,wordOpn a) of
640              ~1 => (case byteMask(ty,wordOpn b) of              ~1 => (case byteMask(ty,wordOpn b) of
641                      ~1 => commArith(I.AND,a,b,d,an)                      ~1 => commArith(I.AND,a,b,d,an)
642                    | mask => arith(I.ZAP,a,T.LI mask,d,an)                    | mask => arith(I.ZAP,a,LI mask,d,an)
643                    )                    )
644            | mask => arith(I.ZAP,b,T.LI mask,d,an)            | mask => arith(I.ZAP,b,LI mask,d,an)
645    
646        (* generate sll/sra/srl *)        (* generate sll/sra/srl *)
647        and sll32(a,b,d,an) =        and sll32(a,b,d,an) =
# Line 724  Line 705 
705                in mark'(instr,an)::trapb end                in mark'(instr,an)::trapb end
706                fun const(e,i) =                fun const(e,i) =
707                    let val r = expr e                    let val r = expr e
708                    in  if !useMultByConst andalso i >= 0 andalso i < 256 then                    in  if !useMultByConst andalso
709                           mark'(gen{ra=r,rb=I.IMMop i,rc=rd},an)::trapb                             GE(i, T.I.int_0) andalso
710                               LT(i, T.I.int_0x100) then
711                             mark'(gen{ra=r,rb=I.IMMop(toInt i),rc=rd},an)::trapb
712                        else                        else
713                           (genConst{r=r,i=i,d=rd}@trapb                           (genConst{r=r,i=toInt i,d=rd}@trapb
714                            handle _ => nonconst(T.REG(ty,r),T.LI i))                            handle _ => nonconst(T.REG(ty,r),T.LI i))
715                    end                    end
               fun constw(e,i) = const(e,Word32.toInt i)  
                                   handle _ => nonconst(e,T.LI32 i)  
716                val instrs =                val instrs =
717                    case (e1,e2) of                  case (e1, e2)
718                       (e1,T.LI i)   => const(e1,i)                  of (_, T.LI i) => const(e1, i)
719                     | (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)  
720                     | _             => nonconst(e1,e2)                     | _             => nonconst(e1,e2)
721            in  app emit instrs            in  app emit instrs
722            end            end
# Line 768  Line 747 
747                fun const(e,i) =                fun const(e,i) =
748                    let val r = expr e                    let val r = expr e
749                    in  genDiv{mode=T.TO_ZERO,stm=doStmt}                    in  genDiv{mode=T.TO_ZERO,stm=doStmt}
750                              {r=r,i=i,d=rd}                              {r=r,i=toInt i,d=rd}
751                        handle _ => nonconst(T.REG(ty,r),T.LI i)                        handle _ => nonconst(T.REG(ty,r),T.LI i)
752                    end                    end
               fun constw(e,i) = const(e,Word32.toInt i)  
                                   handle _ => nonconst(e,T.LI32 i)  
753                val instrs =                val instrs =
754                    case e2 of                    case e2 of
755                       T.LI i   => const(e1,i)                       T.LI i   => const(e1,i)
                    | T.LI32 i => constw(e1,i)  
756                     | _        => nonconst(e1,e2)                     | _        => nonconst(e1,e2)
757            in  app emit instrs            in  app emit instrs
758            end            end
# Line 922  Line 898 
898            app emit (pseudo{mode=rounding, fs=fexpr e, rd=rd})            app emit (pseudo{mode=rounding, fs=fexpr e, rd=rd})
899    
900        (* generate an expression and return the register that holds the result *)        (* generate an expression and return the register that holds the result *)
901        and expr(T.REG(_,r)) = r        and expr(e) = let
902          | expr(T.LI 0) = zeroR          fun comp() = let
903          | expr(T.LI32 0w0) = zeroR            val r = newReg()
904            in doExpr(e, r, []); r
905            end
906          in
907            case e
908            of T.REG(_, r) => r
909             | T.LI z => if T.I.isZero(z) then zeroR else comp()
910              (* On the alpha: all 32 bit values are already sign extended.              (* On the alpha: all 32 bit values are already sign extended.
911               * So no sign extension is necessary               * So no sign extension is necessary
912               *)               *)
913          | expr(T.SX(64, 32, e)) = expr e           | T.SX(64, 32, e) => expr e
914          | expr(T.ZX(64, 32, e)) = expr e           | T.ZX(64, 32, e) => expr e
915             | _ => comp()
916          | expr e = let val r = newReg()        end
                    in  doExpr(e,r,[]); r end  
917    
918        (* generate an expression that targets register d *)        (* generate an expression that targets register d *)
919        and doExpr(exp,d,an) =        and doExpr(exp,d,an) =
920            case exp of            case exp of
921              T.REG(_,r) => move(r,d,an)              T.REG(_,r) => move(r,d,an)
922            | T.LI n     => loadImmed(n,zeroR,d,an)            | T.LI n     => loadImmed(n,zeroR,d,an)
           | T.LI32 w   => loadImmed32(w,zeroR,d,an)  
923            | T.LABEL l  => loadLabel(l,d,an)            | T.LABEL l  => loadLabel(l,d,an)
924            | T.CONST c  => loadConst(c,d,an)            | T.CONST c  => loadConst(c,d,an)
925    
# Line 955  Line 935 
935                 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(LE.CONST c)},an)
936            | T.ADD(64,e,T.LI i)     => loadImmed(i, expr e, d, an)            | T.ADD(64,e,T.LI i)     => loadImmed(i, expr e, d, an)
937            | T.ADD(64,T.LI i,e)     => loadImmed(i, expr e, d, an)            | T.ADD(64,T.LI i,e)     => loadImmed(i, expr e, d, an)
938            | T.ADD(64,e,T.LI32 i)   => loadImmed32(i, expr e, d, an)            | T.SUB(sz, a, b as T.LI z)    =>
939            | T.ADD(64,T.LI32 i,e)   => loadImmed32(i, expr e, d, an)                if T.I.isZero(z) then
940            | T.SUB(_,a,(T.LI 0 | T.LI32 0w0)) => doExpr(a,d,an)                  doExpr(a,d,an)
941                  else (case sz
942                    of 32 => minus(32,I.SUBL,I.S4SUBL,I.S8SUBL,a,b,d,an)
943                     | 64 => minus(64,I.SUBQ,I.S4SUBQ,I.S8SUBQ,a,b,d,an)
944                     | _ =>  doExpr(Gen.compileRexp exp,d,an)
945                    (*esac*))
946    
947              (* 32-bit support *)              (* 32-bit support *)
948            | T.ADD(32,a,b) => plus(32,I.ADDL,I.S4ADDL,I.S8ADDL,a,b,d,an)            | T.ADD(32,a,b) => plus(32,I.ADDL,I.S4ADDL,I.S8ADDL,a,b,d,an)
# Line 1053  Line 1038 
1038              )              )
1039    
1040             (* conversion to boolean *)             (* conversion to boolean *)
1041            | T.COND(_,T.CMP(ty,cond,e1,e2),T.LI 1,T.LI 0) =>            | T.COND(_, T.CMP(ty,cond,e1,e2), x, y)  =>
1042                 (case (x, y)
1043                  of (T.LI n, T.LI m) =>
1044                    if EQ(n, int_1) andalso EQ(m, int_0) then
1045                 compare(ty,cond,e1,e2,d,an)                 compare(ty,cond,e1,e2,d,an)
1046            | 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
1047                 compare(ty,T.Basis.negateCond cond,e1,e2,d,an)                 compare(ty,T.Basis.negateCond cond,e1,e2,d,an)
1048            | T.COND(_,T.CMP(ty,cond,e1,e2),x,y) =>                  else
1049                 cmove(ty,cond,e1,e2,x,y,d,an)                 cmove(ty,cond,e1,e2,x,y,d,an)
1050                  | _ => cmove(ty,cond,e1,e2,x,y,d,an)
1051                 (*esac*))
1052    
1053            | T.LET(s,e) => (doStmt s; doExpr(e, d, an))            | T.LET(s,e) => (doStmt s; doExpr(e, d, an))
1054            | 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 1178  Line 1168 
1168            | _ => error "doFexpr"            | _ => error "doFexpr"
1169    
1170            (* check whether an expression is andb(e,1) *)            (* check whether an expression is andb(e,1) *)
1171        and isAndb1(T.ANDB(_,e,T.LI 1))     = (true,e)        and isAndb1(e as T.ANDB(_, e1, e2)) = let
1172          | isAndb1(T.ANDB(_,e,T.LI32 0w1)) = (true,e)              fun isOne(n, ei) =
1173          | isAndb1(T.ANDB(_,T.LI 1,e))     = (true,e)                if EQ(n, int_1) then (true, ei) else (false, e)
1174          | isAndb1(T.ANDB(_,T.LI32 0w1,e)) = (true,e)            in
1175                case(e1, e2)
1176                of (T.LI n, _) => isOne(n, e2)
1177                 | (_, T.LI n) => isOne(n, e1)
1178                 | _ => (false, e)
1179              end
1180          | isAndb1 e                       = (false,e)          | isAndb1 e                       = (false,e)
1181    
1182        and zeroOrOne(T.LI 0)     = ZERO        and zeroOrOne(T.LI n) =
1183          | zeroOrOne(T.LI32 0w0) = ZERO          if T.I.isZero n then ZERO
1184          | zeroOrOne(T.LI 1)     = ONE          else if EQ(n, int_1) then ONE
1185          | zeroOrOne(T.LI32 0w1) = ONE               else OTHER
1186          | zeroOrOne _           = OTHER          | zeroOrOne _           = OTHER
1187    
1188        (* compile a branch *)        (* compile a branch *)
# Line 1195  Line 1190 
1190            case e of            case e of
1191              T.CMP(ty,cc,e1 as T.LI _,e2) =>              T.CMP(ty,cc,e1 as T.LI _,e2) =>
1192                 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)  
1193            | 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)
1194              (* generate an floating point branch *)              (* generate an floating point branch *)
1195            | T.FCMP(fty,cc,e1,e2) =>            | T.FCMP(fty,cc,e1,e2) =>
# Line 1259  Line 1252 
1252            (* generate a branch instruction.            (* generate a branch instruction.
1253             * Check for branch on zero as a special case             * Check for branch on zero as a special case
1254             *)             *)
1255        and branchIt(ty,cc,e,T.LI 0,lab,an) = branchIt0(cc,e,lab,an)  
1256          | 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) =
1257               if T.I.isZero z then branchIt0(cc,e1,lab,an)
1258               else branchItOther(ty,cc,e1,e2,lab,an)
1259          | 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)
1260    
1261            (* generate a branch instruction.            (* generate a branch instruction.
# Line 1339  Line 1334 
1334                val (cond,a,b) =                val (cond,a,b) =
1335                  (* move the immed operand to b *)                  (* move the immed operand to b *)
1336                  case a of                  case a of
1337                    (T.LI _ | T.LI32 _ | T.CONST _) => (T.Basis.swapCond cond,b,a)                    (T.LI _ | T.CONST _) => (T.Basis.swapCond cond,b,a)
1338                  | _ => (cond,a,b)                  | _ => (cond,a,b)
1339    
1340                fun sub(a,(T.LI 0 | T.LI32 0w0)) = expr a                fun sub(a, T.LI z) =
1341                       if T.I.isZero z then expr a else expr(T.SUB(ty,a,b))
1342                  | sub(a,b)                     = expr(T.SUB(ty,a,b))                  | sub(a,b)                     = expr(T.SUB(ty,a,b))
1343    
1344                fun cmp(cond,e1,e2) =                fun cmp(cond,e1,e2) =
# Line 1401  Line 1397 
1397                    end                    end
1398                val (cond,e1,e2) =                val (cond,e1,e2) =
1399                    case e1 of                    case e1 of
1400                      (T.LI _ | T.LI32 _ | T.CONST _) =>                      (T.LI _ | T.CONST _) =>
1401                         (T.Basis.swapCond cond,e2,e1)                         (T.Basis.swapCond cond,e2,e1)
1402                    | _ => (cond,e1,e2)                    | _ => (cond,e1,e2)
1403            in  case cond of            in  case cond of

Legend:
Removed from v.760  
changed lines
  Added in v.761

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