Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /sml/trunk/src/MLRISC/x86/mltree/x86.sml
ViewVC logotype

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

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

revision 804, Thu Mar 22 19:37:34 2001 UTC revision 815, Fri May 4 05:09:10 2001 UTC
# Line 46  Line 46 
46      datatype arch = Pentium | PentiumPro | PentiumII | PentiumIII      datatype arch = Pentium | PentiumPro | PentiumII | PentiumIII
47      val arch : arch ref      val arch : arch ref
48      val cvti2f :      val cvti2f :
49             {ty: X86Instr.T.ty,
50              src: X86Instr.operand,
51           (* source operand, guaranteed to be non-memory! *)           (* source operand, guaranteed to be non-memory! *)
52           {ty: X86Instr.T.ty, src: X86Instr.operand} ->            an: Annotations.annotations ref (* cluster annotations *)
53             } ->
54           {instrs : X86Instr.instruction list,(* the instructions *)           {instrs : X86Instr.instruction list,(* the instructions *)
55            tempMem: X86Instr.operand,         (* temporary for CVTI2F *)            tempMem: X86Instr.operand,         (* temporary for CVTI2F *)
56            cleanup: X86Instr.instruction list (* cleanup code *)            cleanup: X86Instr.instruction list (* cleanup code *)
# Line 125  Line 128 
128     *)     *)
129    fun selectInstructions    fun selectInstructions
130         (instrStream as         (instrStream as
131          S.STREAM{emit,defineLabel,entryLabel,pseudoOp,annotation,          S.STREAM{emit,defineLabel,entryLabel,pseudoOp,annotation,getAnnotations,
132                   beginCluster,endCluster,exitBlock,comment,...}) =                   beginCluster,endCluster,exitBlock,comment,...}) =
133    let exception EA    let exception EA
134    
# Line 281  Line 284 
284          | cond T.GE = I.GE | cond T.GEU = I.AE          | cond T.GE = I.GE | cond T.GEU = I.AE
285          | cond T.GT = I.GT | cond T.GTU = I.A          | cond T.GT = I.GT | cond T.GTU = I.A
286    
287          fun zero dst = emit(I.BINARY{binOp=I.XORL, src=dst, dst=dst})
288    
289        (* Move and annotate *)        (* Move and annotate *)
290        fun move'(src as I.Direct s, dst as I.Direct d, an) =        fun move'(src as I.Direct s, dst as I.Direct d, an) =
291            if C.sameColor(s,d) then ()            if C.sameColor(s,d) then ()
292            else mark(I.COPY{dst=[d], src=[s], tmp=NONE}, an)            else mark(I.COPY{dst=[d], src=[s], tmp=NONE}, an)
293            | move'(I.Immed 0, dst as I.Direct d, an) =
294                mark(I.BINARY{binOp=I.XORL, src=dst, dst=dst}, an)
295          | move'(src, dst, an) = mark(I.MOVE{mvOp=I.MOVL, src=src, dst=dst}, an)          | move'(src, dst, an) = mark(I.MOVE{mvOp=I.MOVL, src=src, dst=dst}, an)
296    
297        (* Move only! *)        (* Move only! *)
298        fun move(src, dst) = move'(src, dst, [])        fun move(src, dst) = move'(src, dst, [])
299    
       fun zero dst = emit(I.BINARY{binOp=I.XORL, src=dst, dst=dst})  
   
300        val readonly = I.Region.readonly        val readonly = I.Region.readonly
301    
302        (*        (*
# Line 528  Line 533 
533                fun divrem(signed, overflow, e1, e2, resultReg) =                fun divrem(signed, overflow, e1, e2, resultReg) =
534                let val (opnd1, opnd2) = (operand e1, operand e2)                let val (opnd1, opnd2) = (operand e1, operand e2)
535                    val _ = move(opnd1, eax)                    val _ = move(opnd1, eax)
536                    val oper = if signed then (emit(I.CDQ); I.IDIVL)                    val oper = if signed then (emit(I.CDQ); I.IDIVL1)
537                               else (zero edx; I.DIVL)                               else (zero edx; I.DIVL1)
538                in  mark(I.MULTDIV{multDivOp=oper, src=regOrMem opnd2},an);                in  mark(I.MULTDIV{multDivOp=oper, src=regOrMem opnd2},an);
539                    move(resultReg, rdOpnd);                    move(resultReg, rdOpnd);
540                    if overflow then trap() else ()                    if overflow then trap() else ()
# Line 579  Line 584 
584                fun rem(signed, overflow, e1, e2) =                fun rem(signed, overflow, e1, e2) =
585                      divrem(signed, overflow, e1, e2, edx)                      divrem(signed, overflow, e1, e2, edx)
586    
587                      (* Makes sure the destination must be a register *)
588                  fun dstMustBeReg f =
589                      if isMemReg rd then
590                      let val tmpR = newReg()
591                          val tmp  = I.Direct(tmpR)
592                      in  f(tmpR, tmp); move(tmp, rdOpnd) end
593                      else f(rd, rdOpnd)
594    
595                    (* unsigned integer multiplication *)                    (* unsigned integer multiplication *)
596                fun uMultiply(e1, e2) =                fun uMultiply(e1, e2) =
597                    (* note e2 can never be (I.Direct edx) *)                    (* note e2 can never be (I.Direct edx) *)
598                    (move(operand e1, eax);                    (move(operand e1, eax);
599                     mark(I.MULTDIV{multDivOp=I.MULL,                     mark(I.MULTDIV{multDivOp=I.MULL1,
600                                    src=regOrMem(operand e2)},an);                                    src=regOrMem(operand e2)},an);
601                     move(eax, rdOpnd)                     move(eax, rdOpnd)
602                    )                    )
# Line 592  Line 605 
605                     * The only forms that are allowed that also sets the                     * The only forms that are allowed that also sets the
606                     * OF and CF flags are:                     * OF and CF flags are:
607                     *                     *
608                       *          (dst)  (src1)  (src2)
609                     *      imul r32, r32/m32, imm8                     *      imul r32, r32/m32, imm8
610                       *          (dst)  (src)
611                     *      imul r32, imm8                     *      imul r32, imm8
612                     *      imul r32, imm32                     *      imul r32, imm32
613                       *      imul r32, r32/m32
614                       * Note: destination must be a register!
615                     *)                     *)
616                fun multiply(e1, e2) =                fun multiply(e1, e2) =
617                let fun doit(i1 as I.Immed _, i2 as I.Immed _, dstR, dst) =                dstMustBeReg(fn (rd, rdOpnd) =>
618                        (move(i1, dst);                let fun doit(i1 as I.Immed _, i2 as I.Immed _) =
619                         mark(I.MUL3{dst=dstR, src1=i2, src2=NONE},an))                        (move(i1, rdOpnd);
620                      | doit(rm, i2 as I.Immed _, dstR, dst) =                         mark(I.BINARY{binOp=I.IMULL, dst=rdOpnd, src=i2},an))
621                          doit(i2, rm, dstR, dst)                      | doit(rm, i2 as I.Immed _) = doit(i2, rm)
622                      | doit(imm as I.Immed(i), rm, dstR, dst) =                      | doit(imm as I.Immed(i), rm) =
623                         mark(I.MUL3{dst=dstR, src1=rm, src2=SOME i},an)                             mark(I.MUL3{dst=rd, src1=rm, src2=i},an)
624                      | doit(r1 as I.Direct _, r2 as I.Direct _, dstR, dst) =                      | doit(r1 as I.Direct _, r2 as I.Direct _) =
625                        (move(r1, dst);                        (move(r1, rdOpnd);
626                         mark(I.MUL3{dst=dstR, src1=r2, src2=NONE},an))                         mark(I.BINARY{binOp=I.IMULL, dst=rdOpnd, src=r2},an))
627                      | doit(r1 as I.Direct _, rm, dstR, dst) =                      | doit(r1 as I.Direct _, rm) =
628                        (move(r1, dst);                        (move(r1, rdOpnd);
629                         mark(I.MUL3{dst=dstR, src1=rm, src2=NONE},an))                         mark(I.BINARY{binOp=I.IMULL, dst=rdOpnd, src=rm},an))
630                      | doit(rm, r as I.Direct _, dstR, dst) =                      | doit(rm, r as I.Direct _) = doit(r, rm)
631                         doit(r, rm, dstR, dst)                      | doit(rm1, rm2) =
                     | doit(rm1, rm2, dstR, dst) =  
632                         if equalRd rm2 then                         if equalRd rm2 then
633                         let val tmpR = newReg()                         let val tmpR = newReg()
634                             val tmp  = I.Direct tmpR                             val tmp  = I.Direct tmpR
635                         in move(rm1, tmp);                         in move(rm1, tmp);
636                            mark(I.MUL3{dst=tmpR, src1=rm2, src2=NONE},an);                            mark(I.BINARY{binOp=I.IMULL, dst=tmp, src=rm2},an);
637                            move(tmp, dst)                            move(tmp, rdOpnd)
638                         end                         end
639                         else                         else
640                           (move(rm1, dst);                           (move(rm1, rdOpnd);
641                            mark(I.MUL3{dst=dstR, src1=rm2, src2=NONE},an)                            mark(I.BINARY{binOp=I.IMULL, dst=rdOpnd, src=rm2},an)
642                           )                           )
643                    val (opnd1, opnd2) = (operand e1, operand e2)                    val (opnd1, opnd2) = (operand e1, operand e2)
644                in  if isMemReg rd then (* destination must be a real reg *)                in  doit(opnd1, opnd2)
                   let val tmpR = newReg()  
                       val tmp  = I.Direct tmpR  
                   in  doit(opnd1, opnd2, tmpR, tmp);  
                       move(tmp, rdOpnd)  
645                    end                    end
646                    else                )
                       doit(opnd1, opnd2, rd, rdOpnd)  
               end  
   
                  (* Makes sure the destination must be a register *)  
               fun dstMustBeReg f =  
                   if isMemReg rd then  
                   let val tmpR = newReg()  
                       val tmp  = I.Direct(tmpR)  
                   in  f(tmpR, tmp); move(tmp, rdOpnd) end  
                   else f(rd, rdOpnd)  
647    
648                   (* Emit a load instruction; makes sure that the destination                   (* Emit a load instruction; makes sure that the destination
649                    * is a register                    * is a register
# Line 960  Line 962 
962            in  mark(testopcode{lsrc=opnd1, rsrc=opnd2}, an)            in  mark(testopcode{lsrc=opnd1, rsrc=opnd2}, an)
963            end            end
964    
965              (* %eflags <- src *)
966          and moveToEflags src =
967              if C.sameColor(src, C.eflags) then ()
968              else (move(I.Direct src, eax); emit(I.LAHF))
969    
970              (* dst <- %eflags *)
971          and moveFromEflags dst =
972              if C.sameColor(dst, C.eflags) then ()
973              else (emit(I.SAHF); move(eax, I.Direct dst))
974    
975           (* generate a condition code expression           (* generate a condition code expression
976            * The zero is for setting the condition code!            * The zero is for setting the condition code!
977            * I have no idea why this is used.            * I have no idea why this is used.
978            *)            *)
979        and doCCexpr(T.CMP(ty, cc, t1, t2), rd, an) =        and doCCexpr(T.CMP(ty, cc, t1, t2), rd, an) =
980            if C.sameColor(rd, C.eflags) then            (cmp(false, ty, cc, t1, t2, an);
981               (cmp(false, ty, cc, t1, t2, an); ())             moveFromEflags rd
982              )
983            | doCCexpr(T.CC(cond,rs), rd, an) =
984              if C.sameColor(rs,C.eflags) orelse C.sameColor(rd,C.eflags) then
985                 (moveToEflags rs; moveFromEflags rd)
986            else            else
987               error "doCCexpr: cmp"               move'(I.Direct rs, I.Direct rd, an)
988          | doCCexpr(T.CCMARK(e,A.MARKREG f),rd,an) = (f rd; doCCexpr(e,rd,an))          | doCCexpr(T.CCMARK(e,A.MARKREG f),rd,an) = (f rd; doCCexpr(e,rd,an))
989          | doCCexpr(T.CCMARK(e,a), rd, an) = doCCexpr(e,rd,a::an)          | doCCexpr(T.CCMARK(e,a), rd, an) = doCCexpr(e,rd,a::an)
990          | doCCexpr(T.CCEXT e, cd, an) =          | doCCexpr(T.CCEXT e, cd, an) =
# Line 1047  Line 1063 
1063    
1064            (* generate code for calls *)            (* generate code for calls *)
1065        and call(ea, flow, def, use, mem, cutsTo, an) =        and call(ea, flow, def, use, mem, cutsTo, an) =
1066            mark(I.CALL{opnd=operand ea,defs=cellset(def),uses=cellset(use),        let fun return(set, []) = set
1067                        cutsTo=cutsTo,mem=mem},an)              | return(set, a::an) =
1068                  case #peek A.RETURN_ARG a of
1069                    SOME r => return(C.CellSet.add(r, set), an)
1070                  | NONE => return(set, an)
1071          in  mark(I.CALL{opnd=operand ea,defs=cellset(def),uses=cellset(use),
1072                          return=return(C.empty,an),cutsTo=cutsTo,mem=mem},an)
1073          end
1074    
1075            (* generate code for integer stores *)            (* generate code for integer stores; first move data to %eax
1076        and store8(ea, d, mem, an) =             * This is mainly because we can't allocate to registers like
1077            let val src = (* movb has to use %eax as source. Stupid x86! *)             * ah, dl, dx etc.
1078               *)
1079          and genStore(mvOp, ea, d, mem, an) =
1080              let val src =
1081                   case immedOrReg(operand d) of                   case immedOrReg(operand d) of
1082                       src as I.Direct r =>                       src as I.Direct r =>
1083                         if C.sameColor(r,C.eax)                         if C.sameColor(r,C.eax)
1084                         then src else (move(src, eax); eax)                         then src else (move(src, eax); eax)
1085                     | src => src                     | src => src
1086            in  mark(I.MOVE{mvOp=I.MOVB, src=src, dst=address(ea,mem)},an)            in  mark(I.MOVE{mvOp=mvOp, src=src, dst=address(ea,mem)},an)
1087            end            end
       and store16(ea, d, mem, an) =  
         mark(I.MOVE{mvOp=I.MOVW, src=immedOrReg(operand d), dst=address(ea, mem)}, an)  
1088    
1089              (* generate code for 8-bit integer stores *)
1090              (* movb has to use %eax as source. Stupid x86! *)
1091          and store8(ea, d, mem, an) = genStore(I.MOVB, ea, d, mem, an)
1092          and store16(ea, d, mem, an) = genStore(I.MOVW, ea, d, mem, an)
1093        and store32(ea, d, mem, an) =        and store32(ea, d, mem, an) =
1094              move'(immedOrReg(operand d), address(ea, mem), an)              move'(immedOrReg(operand d), address(ea, mem), an)
1095    
# Line 1172  Line 1199 
1199            in  if isMemOpnd opnd andalso (ty = 16 orelse ty = 32)            in  if isMemOpnd opnd andalso (ty = 16 orelse ty = 32)
1200                then (INTEGER, ty, opnd, [])                then (INTEGER, ty, opnd, [])
1201                else                else
1202                  let val {instrs, tempMem, cleanup} = cvti2f{ty=ty, src=opnd}                  let val {instrs, tempMem, cleanup} =
1203                            cvti2f{ty=ty, src=opnd, an=getAnnotations()}
1204                  in  emits instrs;                  in  emits instrs;
1205                      (INTEGER, 32, tempMem, cleanup)                      (INTEGER, 32, tempMem, cleanup)
1206                  end                  end
# Line 1743  Line 1771 
1771               entryLabel  = entryLabel,               entryLabel  = entryLabel,
1772               comment     = comment,               comment     = comment,
1773               annotation  = annotation,               annotation  = annotation,
1774                 getAnnotations = getAnnotations,
1775               exitBlock   = fn mlrisc => exitBlock(cellset mlrisc)               exitBlock   = fn mlrisc => exitBlock(cellset mlrisc)
1776            }            }
1777    

Legend:
Removed from v.804  
changed lines
  Added in v.815

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