Annotation of researchv10no/cmd/sml/src/mips/mips.sml, revision 1.1.1.1

1.1       root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
                      2: functor MipsCM(MipsC : MIPSCODER) : CMACHINE = struct
                      3: 
                      4:     open MipsC System.Tags
                      5: 
                      6:     fun three f (Direct x, ea, Direct y) = f(x,ea,y)
                      7:       | three f (ea, Direct x, Direct y) = f(x,ea,y)
                      8:       | three f _ =ErrorMsg.impossible "neither arg to three f is register in mips"
                      9: 
                     10: 
                     11:     val immed = Immed
                     12:     fun isimmed(Immed i) = SOME i
                     13:       | isimmed _ = NONE
                     14:     
                     15:     fun isreg(Direct(Reg i)) = SOME i | isreg _ = NONE
                     16:     fun eqreg (a: EA) b = a=b
                     17:     
                     18: 
                     19: 
                     20:     val standardarg = Direct(Reg 2)
                     21:     val standardcont = Direct(Reg 3)
                     22:     val standardclosure = Direct(Reg 4)
                     23:     val miscregs = map (Direct o Reg) [5,6,7,8,9,10,11,12,13,14,
                     24:                                        15,16,17,18,19]
                     25:     val storeptr as Direct storeptr' = Direct(Reg 22)
                     26:     val dataptr  as Direct dataptr'  = Direct(Reg 23)
                     27:     val exnptr = Direct(Reg 30)
                     28:     
                     29:       (* internal use only *)
                     30:     val my_arithtemp as Direct my_arithtemp'= Direct(Reg 20) 
                     31:     val my_ptrtemp as Direct my_ptrtemp' = Direct(Reg 21)
                     32:     
                     33:       (* exported for external use *)
                     34:     val arithtemp as Direct arithtemp' = Direct(Reg 24) 
                     35:     val arithtemp2 as Direct arithtemp2'= Direct(Reg 25)
                     36: 
                     37: 
                     38:     fun move (src,Direct dest) = M.move(src, dest)
                     39:       | move _ = ErrorMsg.impossible "destination of move not register in mips"
                     40:     val align = M.align
                     41:     val mark = M.mark
                     42:     
                     43:     val emitlong = M.emitlong
                     44:     val realconst = M.realconst
                     45:     val emitstring = M.emitstring
                     46: 
                     47:     fun emitlab(i,Immedlab lab) = M.emitlab(i,lab)
                     48:       | emitlab _ = ErrorMsg.impossible "bad emitlab arg in mips"
                     49:     fun newlabel() = Immedlab(M.newlabel())
                     50:     fun define (Immedlab lab) = M.define lab
                     51:       | define _ = ErrorMsg.impossible "bad define arg in mips"
                     52:     fun record(vl, Direct z) =
                     53:         let open CPS
                     54:             val len = List.length vl
                     55:             fun f(i,nil) = ()
                     56:               | f(i,(r, SELp(j,p))::rest) = (* follow ptrs to get the item *)
                     57:                     (M.lw(my_ptrtemp', r, j*4); f(i,(my_ptrtemp,p)::rest))
                     58:               | f(i,(Direct r,OFFp 0)::rest) =  (* simple store, last first *) 
                     59:                     (M.sw(r, dataptr, i*4); f(i-1,rest))
                     60:               | f(i,(Direct r, OFFp j)::rest) = 
                     61:                     (M.add(r, Immed(4*j), my_ptrtemp'); 
                     62:                                     f(i,(my_ptrtemp,OFFp 0)::rest))
                     63:               | f(i,(ea,p)::rest) = (* convert to register-based *)
                     64:                     (M.move(ea, my_ptrtemp'); f(i,(my_ptrtemp,p)::rest))
                     65:           in f(len - 1, rev vl); (* store first word in [[0(dataptr')]] *)
                     66:              M.add(dataptr', Immed 4, z);
                     67:              M.add(dataptr', Immed(4*len), dataptr')
                     68:          end
                     69:        | record _ = ErrorMsg.impossible "result of record not register in mips"
                     70:     
                     71:     fun select(i, r, Direct s) = M.lw(s, r, i*4)
                     72:       | select _ = ErrorMsg.impossible "result of select not register in mips"
                     73:     
                     74:     fun offset(i, Direct r, Direct s) = M.add(r,Immed(i*4), s)
                     75:       | offset _ = ErrorMsg.impossible "nonregister arg to offset in mips"
                     76:     (* fetchindexb(x,y) fetches a byte: y <- mem[x+arithtemp]
                     77:             y cannot be arithtemp *)
                     78:     fun fetchindexb(x,Direct y) =
                     79:         (M.add(arithtemp',x,my_arithtemp');    
                     80:          M.lbu(y,my_arithtemp,0))
                     81:       | fetchindexb _ = ErrorMsg.impossible "fetchb result not register in mips"
                     82:     
                     83:     (* storeindexb(x,y) stores a byte: mem[y+arithtemp] <- x; *)
                     84:     fun storeindexb(Direct x,y) =
                     85:         (M.add(arithtemp',y,my_arithtemp');
                     86:          M.sb(x,my_arithtemp,0))
                     87:       | storeindexb _ = ErrorMsg.impossible "storeb arg not register in mips"
                     88:     
                     89:     (* jmpindexb(x)    pc <- (x+arithtemp) *)
                     90:     fun jmpindexb x = (M.add(arithtemp',x,my_arithtemp');
                     91:                          M.jump(my_arithtemp'))
                     92: 
                     93:        (* fetchindexl(x,y,z) fetches a word:   y <- mem[x+2*(z-1)] *)
                     94:        (* storeindexl(x,y,z) stores a word:    mem[y+2*(z-1)] <- x *)
                     95:     
                     96:     fun fetchindexl(x,Direct y, Direct z) = 
                     97:           (M.sll(Immed 1,z,my_arithtemp');
                     98:            M.add(my_arithtemp',x,my_arithtemp');
                     99:            M.lw(y, my_arithtemp,~2))
                    100:       | fetchindexl(x,Direct y, Immed z) = M.lw(y, x, z+z-2)
                    101:       | fetchindexl _ = ErrorMsg.impossible "fetchl result not register in mips"
                    102:     
                    103:     fun storeindexl(Direct x,y, Immed 1) = M.sw(x,y,0)
                    104:       | storeindexl(Direct x,y,Direct z) = 
                    105:         (M.sll(Immed 1,z,my_arithtemp');
                    106:          M.add(my_arithtemp',y,my_arithtemp');
                    107:          M.sw(x, my_arithtemp,~2))
                    108:       | storeindexl(Direct x,y,Immed z) = M.sw(x,y,z+z-2)
                    109:     
                    110:       | storeindexl(Direct _,_,Immedlab _) =
                    111:        ErrorMsg.impossible "storeindexl(Direct _,_,Immedlab _) in mips"
                    112:     
                    113:       | storeindexl(Immedlab label,y,z) =
                    114:         (M.move(Immedlab label,my_ptrtemp');
                    115:          storeindexl(my_ptrtemp,y,z))
                    116:     
                    117:       | storeindexl(Immed constant,y,offset) =
                    118:        (M.move(Immed constant,my_ptrtemp');
                    119:         storeindexl(my_ptrtemp,y,offset))
                    120: 
                    121:     val addl3 = three M.add
                    122:     
                    123:     fun subl3(Immed k, x, y) = addl3(x, Immed(~k), y)
                    124:       | subl3(Direct x, Direct y, Direct z) = M.sub(y,x,z)
                    125:       | subl3(x, Immed k, dest) = 
                    126:                 (M.move(Immed k, my_arithtemp');
                    127:                  subl3(x, my_arithtemp, dest))
                    128:       | subl3 _ = ErrorMsg.impossible "subl3 args don't match in mips"
                    129:     
                    130:     fun mull2(Direct x, Direct y) = M.mult(y,x,y)
                    131:       | mull2(Immed x, Direct y) = (M.move(Immed x,my_arithtemp');
                    132:                                M.mult(y,my_arithtemp',y))
                    133:       | mull2 _ = ErrorMsg.impossible "mull2 args don't match in mips"
                    134:     fun divl2(Direct x, Direct y) = M.div(y,x,y)
                    135:       | divl2(Immed x, Direct y) = (M.move(Immed x,my_arithtemp');
                    136:                                M.div(y,my_arithtemp',y))
                    137:       | divl2 _ = ErrorMsg.impossible "divl2 args don't match in mips"
                    138: 
                    139:     fun ashr(shamt, Direct op1, Direct result) = M.sra(shamt,op1,result)
                    140:       | ashr(shamt, Immed op1, Direct result) = 
                    141:        (M.move(Immed op1,my_arithtemp'); M.sra(shamt,my_arithtemp',result))
                    142:       | ashr _ = ErrorMsg.impossible "ashr args don't match in mips"
                    143:     fun ashl(shamt, Direct op1, Direct result) = M.sll(shamt,op1,result)
                    144:       | ashl(shamt, Immed op1, Direct result) = 
                    145:        (M.move(Immed op1,my_arithtemp'); M.sll(shamt,my_arithtemp',result))
                    146:       | ashl _ = ErrorMsg.impossible "ashl args don't match in mips"
                    147:     val addl3t = addl3
                    148:     val subl3t = subl3
                    149:     val ashlt = ashl
                    150:     fun mull2t(x,y as Direct y') = 
                    151:         let val ok = M.newlabel()
                    152:         in  mull2(x,y);
                    153:        M.mfhi(my_arithtemp');
                    154:        M.slt(y',Direct (Reg 0),my_ptrtemp'); (* 0 or 1 OK in pointer *)
                    155:        M.add(my_arithtemp',my_ptrtemp,my_arithtemp');
                    156:        M.beq(true,my_arithtemp',Reg 0,ok);    (* OK if not overflow *)
                    157:        M.lui(my_arithtemp',32767);
                    158:        M.add(my_arithtemp',my_arithtemp,my_arithtemp');  (* overflows *)
                    159:        M.define(ok)
                    160:         end
                    161:       | mull2t _ = ErrorMsg.impossible "result of mull2t not register in mips"
                    162: 
                    163:     val orb = three M.or
                    164:     val andb = three M.and'
                    165:     fun notb (a,b) = subl3(a, Immed ~1, b) (* ~1 - a == one's complement *)
                    166:     val xorb = three M.xor
                    167:     datatype condition = NEQ | EQL | LEQ | GEQ | LSS | GTR
                    168:     local 
                    169:     fun makeibranch reverse = 
                    170:     let
                    171:     fun ibranch (cond, Immed a, Immed b, Immedlab label) =
                    172:                 if (case cond of EQL => a=b | NEQ => a<>b | LSS => a<b |
                    173:                                  LEQ => a<=b | GTR => a>b | GEQ => a>=b)
                    174:                     then M.beq(true,Reg 0, Reg 0, label) else ()
                    175:       | ibranch (NEQ, Direct r, Direct s, Immedlab label) =
                    176:                         M.beq(false, r, s, label)
                    177:       | ibranch (NEQ, Direct r, x, Immedlab label) =
                    178:                         (M.move(x, my_arithtemp');
                    179:                          M.beq(false, r, my_arithtemp', label))
                    180:       | ibranch (EQL, Direct r, Direct s, Immedlab label) =
                    181:                         M.beq(true, r, s, label)
                    182:       | ibranch (EQL, Direct r, x, Immedlab label) =
                    183:                         (M.move(x, my_arithtemp');
                    184:                          M.beq(true, r, my_arithtemp', label))
                    185:       | ibranch (LSS, Direct r, x, Immedlab lab) =
                    186:                     (M.slt(r,x,my_arithtemp');
                    187:                      M.beq(false,Reg 0, my_arithtemp',lab))
                    188:       | ibranch (GEQ, Direct r, x, Immedlab lab) =
                    189:                     (M.slt(r,x,my_arithtemp'); 
                    190:                      M.beq(true,Reg 0, my_arithtemp',lab))
                    191:       | ibranch (GTR, x, Direct r, Immedlab lab) =
                    192:                     (M.slt(r,x,my_arithtemp'); 
                    193:                      M.beq(false,Reg 0, my_arithtemp',lab))
                    194:       | ibranch (LEQ, x, Direct r, Immedlab lab) =
                    195:                     (M.slt(r,x,my_arithtemp'); 
                    196:                      M.beq(true,Reg 0, my_arithtemp',lab))
                    197:     (* These two cases added to prevent infinite reversal *)
                    198:       | ibranch (GTR, Direct r, x, Immedlab lab) =
                    199:                (M.move(x, my_arithtemp');
                    200:                 M.slt(my_arithtemp',Direct r,my_arithtemp');
                    201:                 M.beq(false,Reg 0,my_arithtemp',lab))
                    202:       | ibranch (LEQ, Direct r, x, Immedlab lab) =
                    203:                (M.move(x, my_arithtemp');
                    204:                 M.slt(my_arithtemp',Direct r,my_arithtemp');
                    205:                 M.beq(true,Reg 0,my_arithtemp',lab))
                    206:       | ibranch (_, Immedlab _, Immedlab _, _) = 
                    207:                     ErrorMsg.impossible "bad ibranch args 1 in mips"
                    208:       | ibranch (_, Immedlab _, _, _) = 
                    209:                     ErrorMsg.impossible "bad ibranch args 1a in mips"
                    210:       | ibranch (_, _, Immedlab _, _) = 
                    211:                     ErrorMsg.impossible "bad ibranch args 1b in mips"
                    212:       | ibranch (_, _, _, Direct _) = 
                    213:                     ErrorMsg.impossible "bad ibranch args 2 in mips"
                    214:       | ibranch (_, _, _, Immed _) = 
                    215:                     ErrorMsg.impossible "bad ibranch args 3 in mips"
                    216:       | ibranch (cond, x, y, l) = 
                    217:             let fun rev LEQ = GEQ
                    218:                   | rev GEQ = LEQ
                    219:                   | rev LSS = GTR
                    220:                   | rev GTR = LSS
                    221:                   | rev NEQ = NEQ
                    222:                   | rev EQL = EQL
                    223:             in  if reverse then (makeibranch false) (rev cond, y,x,l) 
                    224:            else ErrorMsg.impossible "infinite ibranch reversal in mips"
                    225:        
                    226:             end
                    227:     in ibranch
                    228:     end
                    229:     in
                    230:     val ibranch = makeibranch true
                    231:     end
                    232:         
                    233:     fun jmp (Direct r) = M.jump(r)
                    234:       | jmp (Immedlab lab) = M.beq(true,Reg 0,Reg 0,lab)
                    235:       | jmp (Immed i) = ErrorMsg.impossible "jmp (Immed i) in mips"
                    236:     
                    237:     
                    238:             (* branch on bit set *)
                    239:     fun bbs (Immed k, Direct y, Immedlab label) =
                    240:             (M.and'(y,Immed (Bits.lshift(1,k)),my_arithtemp');
                    241:              M.beq(false,my_arithtemp',Reg 0,label))
                    242:       | bbs _ = ErrorMsg.impossible "bbs args don't match in mips"
                    243: 
                    244: 
                    245:     val floatop1 = Reg 0
                    246:     val floatop2 = Reg 2
                    247:     val floatresult = Reg 0
                    248:     
                    249:     val real_tag = Immed(8*System.Tags.power_tags + System.Tags.tag_string)
                    250:     
                    251:     fun store_float(Reg n,ea,offset) = 
                    252:         if n mod 2 <> 0 then ErrorMsg.impossible "bad float reg in mips"
                    253:         else (M.swc1(Reg (n+1),ea,offset+4);M.swc1(Reg n,ea,offset))
                    254:     
                    255:     fun finish_real (Direct result) = (
                    256:         store_float(floatresult,dataptr,4);
                    257:         M.move(real_tag,my_arithtemp');
                    258:         M.sw(my_arithtemp',dataptr,0);
                    259:         M.add(dataptr',Immed 4,result);
                    260:         M.add(dataptr',Immed 12,dataptr'))
                    261:       | finish_real _ = 
                    262:          ErrorMsg.impossible "ptr to result of real operation not register in mips"
                    263:     
                    264:     fun load_float(Reg dest,src,offset) =
                    265:         if dest mod 2 <> 0 then ErrorMsg.impossible "bad float reg in mips"
                    266:         else (M.lwc1(Reg dest,src,offset); M.lwc1(Reg (dest+1),src,offset+4))
                    267:     
                    268:     fun two_float instruction (op1,result) = (
                    269:         load_float(floatop1,op1,0);
                    270:         instruction(floatop1,floatresult);
                    271:         finish_real(result))
                    272:     
                    273:     fun three_float instruction (op1,op2,result) = (
                    274:         load_float(floatop1,op1,0);
                    275:         load_float(floatop2,op2,0);
                    276:         instruction(floatop1,floatop2,floatresult);
                    277:         finish_real(result))
                    278:     
                    279:     val mnegg = two_float M.neg_double
                    280:     val mulg3 = three_float M.mul_double
                    281:     val divg3 = three_float M.div_double
                    282:     val addg3 = three_float M.add_double
                    283:     val subg3 = three_float M.sub_double
                    284:     
                    285:     
                    286:     local
                    287:         fun compare(LSS,op1,op2) = (M.slt_double(op1,op2); true)
                    288:           | compare(GEQ,op1,op2) = (M.slt_double(op1,op2); false)
                    289:           | compare(EQL,op1,op2) = (M.seq_double(op1,op2); true)
                    290:           | compare(NEQ,op1,op2) = (M.seq_double(op1,op2); false)
                    291:           | compare(LEQ,op1,op2) = compare(GEQ,op2,op1)
                    292:           | compare(GTR,op1,op2) = compare(LSS,op2,op1)
                    293:     in
                    294:         fun gbranch (cond, op1, op2, Immedlab label) = (
                    295:                 load_float(floatop1,op1,0);
                    296:                 load_float(floatop2,op2,0);
                    297:                 M.bcop1(compare(cond,floatop1,floatop2),label))
                    298:           | gbranch _ = ErrorMsg.impossible "insane gbranch target in mips.nw"
                    299:     end
                    300:        
                    301:     
                    302:     fun checkLimit max_allocation = M.sw(Reg 0, dataptr, max_allocation-4)
                    303:                              (* store zero in last location to be used *)
                    304:     
                    305: 
                    306: 
                    307:     fun beginStdFn _ = ()           (* do nothing, just like the Vax *)
                    308:     
                    309:     fun profile(i,incr) = ()
                    310: 
                    311: 
                    312:     val comment = M.comment
                    313: 
                    314: (* +DEBUG *)
                    315:     fun diag (s : string) f x =
                    316:        f x handle e =>
                    317:                (print "?exception "; print (System.exn_name e);
                    318:                 print " in mips."; print s; print "\n";
                    319:                 raise e)
                    320:     
                    321:     val emitlab = diag "emitlab" emitlab
                    322:     val define = diag "define" define
                    323:     
                    324:     
                    325:     val record = diag "record" record
                    326:     val select = diag "select" select
                    327:     val offset = diag "offset" offset
                    328:     
                    329:     val fetchindexb = diag "fetchindexb" fetchindexb
                    330:     val storeindexb = diag "storeindexb" storeindexb
                    331:     val jmpindexb = diag "jmpindexb" jmpindexb
                    332:     
                    333:     
                    334:     val fetchindexl = diag "fetchindexl" fetchindexl
                    335:     val storeindexl = diag "storeindexl" storeindexl
                    336:     
                    337:     
                    338:     val ashr = diag "ashr" ashr
                    339:     val ashl = diag "ashl" ashl
                    340:     
                    341:     val orb = diag "orb" orb
                    342:     val andb = diag "andb" andb
                    343:     val notb = diag "notb" notb
                    344:     val xorb = diag "xorb" xorb
                    345:     
                    346:     
                    347:     val addl3 = diag "addl3" addl3
                    348:     val subl3 = diag "subl3" subl3
                    349:     val mull2 = diag "mull2" mull2
                    350:     val divl2 = diag "divl2" divl2
                    351:     
                    352:     
                    353:     val addl3t = diag "addl3t" addl3t
                    354:     val subl3t = diag "subl3t" subl3t
                    355:     val mull2t = diag "mull2t" mull2t
                    356:     val ashlt = diag "ashlt" ashlt
                    357:     
                    358:     
                    359:     val ibranch = diag "ibranch" ibranch
                    360:     val jmp = diag "jmp" jmp
                    361:     val bbs = diag "bbs" bbs
                    362: 
                    363: (* -DEBUG *)
                    364: 
                    365: end (* MipsCM *)
                    366: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.