Annotation of researchv10no/cmd/sml/src/ns32/ns32mcode.sml, revision 1.1.1.1

1.1       root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
                      2: structure NS32MCode : NS32MCODER = struct
                      3: 
                      4: structure Jumps = struct
                      5:     datatype JumpKind = DISPL of int
                      6:                      | LNGDISPL of int
                      7:                      | LABPTR of int
                      8: fun isquick k = (k<=7 andalso k>= ~8)
                      9: 
                     10: fun eword i =
                     11:        if i<0 then eword(65536+i)
                     12:        else chr(i mod 256) ^ chr(i div 256)
                     13: 
                     14: fun erword i =
                     15:        if i<0 then erword(65536+i)
                     16:        else chr(i div 256) ^ chr(i mod 256)
                     17: 
                     18: fun elong i =
                     19:         if i<0 
                     20:          then let val a = ~i;
                     21:                   val b = a mod 65536;
                     22:                   val c = a div 65536;
                     23:                in eword(~b) ^ eword(~c + if b=0 then 0 else ~1)
                     24:               end
                     25:          else eword(i mod 65536) ^ eword(i div 65536)
                     26: 
                     27: val emitlong = elong
                     28: 
                     29: fun intsize(i) =
                     30:         if i<=63 andalso i>= ~64
                     31:            then 1
                     32:        else if i<=8191 andalso i>= ~8192
                     33:            then 2
                     34:        else 4;
                     35: 
                     36: fun Ldisp (len,d) =
                     37:        if len=1 andalso d<=63 andalso d>= ~64
                     38:            then if d>=0 then chr(d)
                     39:                         else chr(128+d)
                     40:            else if len=2 andalso d<=8191 andalso d>= ~8192
                     41:                then if d>=0 then erword(128*256+d)
                     42:                             else erword(128*256+d+16384)
                     43:            else if d>=0
                     44:                then erword(192*256+(d div 65536)) ^ erword(d mod 65536)
                     45:            else let val a = ~d
                     46:                     val b = a mod 65536
                     47:                     val c = a div 65536
                     48:                  in erword(~c + if b=0 then 0 else ~1) ^ erword(~b)
                     49:                 end
                     50: 
                     51: fun sizejump(LABPTR _,oldsize,s,d) = 4
                     52:   | sizejump(LNGDISPL _,oldsize,s,d) = 4
                     53:   | sizejump(DISPL i,oldsize,s,d) =
                     54:        case oldsize of
                     55:            0 => intsize(d-s+i)
                     56:          | 1 => 2     (* I question this! -- A. Appel *)
                     57:          | _ => 4
                     58: 
                     59: fun emitjump(LABPTR i,4,s,d) = elong(d-s+i)
                     60:   | emitjump(DISPL i,sz,s,d) = Ldisp(sz,d-s+i) (* initial pc is i bytes back *)
                     61:   | emitjump(LNGDISPL i,4,s,d) = Ldisp(4,d-s+i)        (* initial pc is i bytes back *)
                     62:   | emitjump(_,sz,s,d) = ErrorMsg.impossible "bad size in emitjump"
                     63: 
                     64:  end (* Jumps *)
                     65: 
                     66: structure Emitter : BACKPATCH = Backpatch(Jumps)
                     67: 
                     68: structure Coder : NS32CODER = struct
                     69: 
                     70: open Emitter Jumps
                     71: 
                     72: fun emitbyte i = emitstring(chr i)
                     73: fun signedbyte i = emitbyte(if i<0 then 256+i else i)
                     74: fun emitword i = emitstring(eword i)
                     75: fun emitrword i = emitstring(erword i)
                     76: fun emitlong i = emitstring(elong i)
                     77: 
                     78: val mkjump = jump
                     79: 
                     80: fun emitdisp d =
                     81:        if d<=63 andalso d>= ~64
                     82:            then ((if d>=0 then emitbyte(d)
                     83:                          else emitbyte(128+d));
                     84:                  1)
                     85:            else if d<=8191 andalso d>= ~8192
                     86:                then ((if d>=0 then emitrword(128*256+d)
                     87:                              else emitrword(128*256+d+16384));
                     88:                      2)
                     89:            else if d>=0
                     90:                then (emitrword(192*256+(d div 65536));
                     91:                      emitrword(d mod 65536);
                     92:                      4)
                     93:            else let val a = ~d
                     94:                     val b = a mod 65536
                     95:                     val c = a div 65536
                     96:                  in emitrword(~c + if b=0 then 0 else ~1);
                     97:                     emitrword(~b);
                     98:                     4
                     99:                 end
                    100: 
                    101: datatype Register = Genreg of int
                    102:                  | FloatReg of int
                    103:                  | FP
                    104:                  | SP
                    105:                  | SB
                    106:                  | PC
                    107: 
                    108: val r0 = Genreg 0
                    109: val r1 = Genreg 1
                    110: val r2 = Genreg 2
                    111: val r3 = Genreg 3
                    112: val r4 = Genreg 4
                    113: val r5 = Genreg 5
                    114: val r6 = Genreg 6
                    115: val r7 = Genreg 7
                    116: val fp = FP
                    117: val sp = SP
                    118: val sb = SB
                    119: val pc = PC
                    120: val fp0 = FloatReg 0
                    121: 
                    122: datatype Size = Byte | Word | Long
                    123: 
                    124: datatype EA = Direct of Register
                    125:            | Topofstack
                    126:            | Displace of int * Register
                    127:            | Immed of int
                    128:            | Immedlab of Label
                    129:            | Abs of int
                    130:            | OffAddress of Label * int
                    131:            | Index of EA * Register * Size
                    132: 
                    133: fun address lab = OffAddress(lab,0)    (* old Address style *)
                    134: 
                    135: (* This is identical to M68PrimReal except that emitword is different,
                    136:    and the bias is off by two. *)
                    137: (* This is broken, because it is really the VAX G-float rep, not
                    138:    the NS32 IEEE rep. *)
                    139: structure NS32PrimReal : PRIMREAL =
                    140: struct
                    141: val significant = 53 (* 52 + redundant 1/2 bit *)
                    142: fun outofrange s = ErrorMsg.complain("Real constant "^s^" out of range")
                    143: (* Convert a portion of a boolean array to the appropriate integer. *)
                    144: exception Bits
                    145: fun bits(a,start,width) =
                    146:     let fun b true = 1
                    147:          | b false = 0
                    148:        fun f 0 = b (a sub start)
                    149:          | f n = b (a sub (start+n)) + 2 * f(n-1)
                    150:     in  if Array.length a < start+width orelse start < 0 orelse width < 0
                    151:        then raise Bits
                    152:        else f (width-1)
                    153:     end
                    154: fun emitreal (sign,frac,exp) =
                    155:     let val exponent = exp + 1022
                    156:        fun emit () =
                    157:            let val word0 =
                    158:                case frac sub 0 of (* zero? *)
                    159:                  true => Bits.orb(Bits.lshift(sign,15),
                    160:                                   Bits.orb(Bits.lshift(exponent,4),
                    161:                                            bits(frac,1,4)))
                    162:                | false => 0
                    163:                val word1 = bits(frac,5,16)
                    164:                val word2 = bits(frac,21,16)
                    165:                val word3 = bits(frac,37,16)
                    166:            in  emitword word3;
                    167:                emitword word2;
                    168:                emitword word1;
                    169:                emitword word0
                    170:            end
                    171:     in  if exponent < 1 orelse exponent > 2047
                    172:        then outofrange "" (* A hack *)
                    173:        else emit()
                    174:     end
                    175: end
                    176: structure NS32RealConst = RealConst(NS32PrimReal)
                    177: open NS32RealConst
                    178: 
                    179: (* The label value, offset i, will be backpatched pc-relative. *)
                    180: fun emitlab (i,lab) = mkjump(LABPTR i, lab)
                    181: 
                    182: fun procreg (Direct FP) = 8
                    183:   | procreg (Direct SB) = 10
                    184:   | procreg _ = ErrorMsg.impossible "procreg in ns32mcode"
                    185: 
                    186: fun imsize k = if k<0 then 3
                    187:                else if k<128 then 0
                    188:                else 1
                    189: 
                    190: fun quick k = if k>=0 then k else k+16
                    191: 
                    192: fun gen (Direct(Genreg r)) = r
                    193:   | gen (Direct(FloatReg r)) = r
                    194:   | gen (Direct other) = ErrorMsg.impossible "gen direct in ns32mcode"
                    195:   | gen (Displace(d,Genreg r)) = r+8
                    196:   | gen (Displace(d,FP)) = 24
                    197:   | gen (Displace(d,SP)) = 25
                    198:   | gen (Displace(d,SB)) = 26
                    199:   | gen (Displace(d,PC)) = 27
                    200:   | gen (Displace(d,other)) = ErrorMsg.impossible "gen displace in ns32mcode"
                    201:   | gen (Topofstack) = 23
                    202:   | gen (Immed k) = 20
                    203:   | gen (Abs k) = 21
                    204:   | gen (Index(p,Genreg r,Byte)) = 28
                    205:   | gen (Index(p,Genreg r,Word)) = 29
                    206:   | gen (Index(p,Genreg r,Long)) = 30
                    207:   | gen (Index(p,other,sz)) = ErrorMsg.impossible "gen indexreg in ns32mcode"
                    208: (* Labels are always pc-relative, see jump widget in emitextn. *)
                    209:   | gen (OffAddress li) = 27 (* assuming all labels are done pc-relative *)
                    210:   | gen (Immedlab lab) = ErrorMsg.impossible "gen immedlab in ns32mcode"
                    211: 
                    212: fun emitimmed d =
                    213:        if d>=0
                    214:            then (emitrword(d div 65536);
                    215:                  emitrword(d mod 65536))
                    216:            else let val a = ~d
                    217:                     val b = a mod 25536
                    218:                     val c = a div 25536
                    219:                  in emitrword(~c + if b=0 then 0 else ~1);
                    220:                     emitrword(~b)
                    221:                 end
                    222: 
                    223: 
                    224: fun extnjumps (OffAddress _) = true
                    225:   | extnjumps (Index(OffAddress _,_,_)) = true
                    226:   | extnjumps _ = false
                    227: 
                    228: fun emitextnc (_,Direct _) = 0
                    229:   | emitextnc (_,Displace(d,_)) = emitdisp(d)
                    230:   | emitextnc (_,Topofstack) = 0
                    231:   | emitextnc (_,Immed k) = (emitimmed(k); 4)
                    232:   | emitextnc (_,Abs k) = emitdisp(k)
                    233:   | emitextnc (_,Index(Index _,_,_)) = ErrorMsg.impossible "illegal extn mode in ns32mcode"
                    234:   | emitextnc (off,Index(p,Genreg r,sz)) = (emitbyte(r+8*gen(p));
                    235:                                             emitextnc(off+1,p)) + 1
                    236:   | emitextnc (_,Index(p,other,sz)) = ErrorMsg.impossible "illegal extn reg in ns32mcode" 
                    237:   | emitextnc (off,OffAddress(lab,i)) = (mkjump(LNGDISPL(i+off),lab); 4)
                    238:   | emitextnc (_,Immedlab lab) = ErrorMsg.impossible "immedlab extn in ns32mcode"  
                    239: 
                    240: fun emitextn (_,Direct _) = ()
                    241:   | emitextn (_,Displace(d,_)) = (emitdisp(d); ())
                    242:   | emitextn (_,Topofstack) = ()
                    243:   | emitextn (_,Immed k) = emitimmed(k)
                    244:   | emitextn (_,Abs k) = (emitdisp(k); ())
                    245:   | emitextn (_,Index(Index _,_,_)) = ErrorMsg.impossible "illegal extn mode in ns32mcode"
                    246:   | emitextn (off,Index(p,Genreg r,sz)) = (emitbyte(r+8*gen(p));
                    247:                                             emitextn(off+1,p))
                    248:   | emitextn (_,Index(p,other,sz)) = ErrorMsg.impossible "illegal extn reg in ns32mcode" 
                    249:   | emitextn (off,OffAddress(lab,i)) = mkjump(DISPL(i+off),lab)
                    250:   | emitextn (_,Immedlab lab) = ErrorMsg.impossible "immedlab extn in ns32mcode"  
                    251: 
                    252: fun shortinstr(b,(src,dest)) =
                    253:        (emitword(b+64*gen(dest)+2048*gen(src));
                    254:         if extnjumps(dest)
                    255:             then let val off = emitextnc(2,src)
                    256:                   in emitextn(2+off,dest); ()
                    257:                  end
                    258:             else (emitextn(2,src); emitextn(0,dest)))
                    259: 
                    260: fun longinstr(w,(src,dest)) =
                    261:        (let val gd = gen(dest)
                    262:          in emitword(w+16384*(gd mod 4));
                    263:             emitbyte((gd div 4) + 8*gen(src))
                    264:         end;
                    265:         if extnjumps(dest)
                    266:             then let val off = emitextnc(3,src)
                    267:                   in emitextn(3+off,dest); ()
                    268:                  end
                    269:             else (emitextn(3,src); emitextn(0,dest)))
                    270: 
                    271: 
                    272: fun lprl (src,preg) = (emitword(111+128*procreg(preg)+2048*gen(src));
                    273:                       emitextn(2,src); ())
                    274: fun sprl (preg,dest) = (emitword(47+128*procreg(preg)+2048*gen(dest));
                    275:                        emitextn(2,dest); ())
                    276: fun tbit (off as Immed k,base) = shortinstr(55,(off,base))
                    277:   | tbit (off,base) = ErrorMsg.impossible "bad tbit in ns32mcode"
                    278: 
                    279: fun bfs (OffAddress(lab,i)) = (emitbyte(138);
                    280:                         mkjump(DISPL(1+i), lab))
                    281: 
                    282: fun movql (Immed k,dest) = (emitword(95+128*quick(k)+2048*gen(dest));
                    283:                            emitextn(2,dest); ())
                    284:   | movql (src,dest) = ErrorMsg.impossible "illegal movql in ns32mcode"
                    285: 
                    286: (* Size problem, must detect immediate. *)
                    287: fun movb (src as Immed k, dest) =
                    288:        (emitword(20+64*gen(dest)+2048*gen(src));
                    289:         if k>127 orelse k< ~128
                    290:             then ErrorMsg.impossible "illegal movb in ns32mcode"
                    291:             else signedbyte(k);        (* force to byte size *)
                    292:         emitextn(3,dest); ())
                    293:   | movb args = shortinstr(20,args)
                    294: 
                    295: (* Size problem, but will always be moving from mem, so ok. *)
                    296: fun movzbl args = longinstr(206+256*24,args)
                    297: 
                    298: fun lea args = shortinstr(39,args)
                    299: 
                    300: fun movl (Immedlab l, arg) = lea(address l, arg)
                    301:   | movl (args as (Immed k, dest)) = 
                    302:        if isquick(k)
                    303:            then movql args
                    304:            else shortinstr(23,args)
                    305:   | movl args = shortinstr(23,args)
                    306: 
                    307: (* Really addql for case Immed 1 *)
                    308: fun addl (args as (Immed k, dest)) =
                    309:        if isquick(k)
                    310:            then (emitword(15+128*quick(k)+2048*gen(dest));
                    311:                  emitextn(2,dest); ())
                    312:            else shortinstr(3,args)
                    313:   | addl args = shortinstr(3,args)
                    314: fun subl args = shortinstr(35,args)
                    315: fun negl args = longinstr(78+256*35,args)
                    316: (* Size problem, must force count to byte size *)
                    317: fun ashl (count as Immed k, dest) =
                    318:        (let val gd = gen(dest)
                    319:          in emitword(78+256*7+16384*(gd mod 4));
                    320:             emitbyte((gd div 4) + 8*gen(count))
                    321:         end;
                    322:         if k>127 orelse k< ~128
                    323:             then ErrorMsg.impossible "illegal ashl in ns32mcode"
                    324:             else signedbyte(k);        (* force to byte size *)
                    325:         emitextn(4,dest); ())
                    326:   | ashl args = longinstr(78+256*7,args)
                    327: fun andl args = shortinstr(43,args)
                    328: fun orl args = shortinstr(27,args)
                    329: fun xorl args = shortinstr(59,args)
                    330: fun coml args = longinstr(78+256*55,args)
                    331: fun mull args = longinstr(128+78+256*35,args)
                    332: fun divl args = longinstr(128+78+256*63,args)
                    333: 
                    334: fun br (OffAddress(lab,i)) = (emitbyte(234);
                    335:                              mkjump(DISPL(1+i),lab))
                    336: 
                    337: fun jump (arg as OffAddress _) = br arg
                    338:   | jump arg = (emitword(127+512+2048*gen(arg));
                    339:                emitextn(2,arg); ())
                    340: 
                    341: fun bfs (OffAddress(lab,i)) = (emitbyte(138);
                    342:                               mkjump(DISPL(1+i), lab))
                    343: 
                    344: local fun condj(c) =
                    345:        fn (OffAddress(lab,i)) => (emitbyte(10+16*c);
                    346:                                   mkjump(DISPL(1+i), lab))
                    347:         | Displace(k, PC) => (emitbyte(10+16*c);
                    348:                               emitdisp(k); ())
                    349:  in val beq = condj(0)
                    350:     val bne = condj(1)
                    351:     val bge = condj(13)
                    352:     val bgt = condj(6)
                    353:     val blt = condj(12)
                    354:     val ble = condj(7)
                    355: end
                    356: 
                    357: fun cmpl (args as (Immed k,arg2)) =
                    358:        if isquick(k)
                    359:            then (emitword(31+128*quick(k)+2048*gen(arg2));
                    360:                  emitextn(2, arg2); ())
                    361:            else shortinstr(7,args)
                    362:   | cmpl args = shortinstr(7,args)
                    363: 
                    364: fun movg args = longinstr(190+256*4,args)
                    365: fun negg args = longinstr(190+256*20,args)
                    366: fun addg args = longinstr(190,args)
                    367: fun subg args = longinstr(190+256*16,args)
                    368: fun mulg args = longinstr(190+256*48,args)
                    369: fun divg args = longinstr(190+256*32,args)
                    370: fun cmpg args = longinstr(190+256*8,args)
                    371: 
                    372: fun comment _ = ()
                    373: 
                    374: end (* Coder *)
                    375: 
                    376: val finish = Emitter.finish
                    377: 
                    378: end (* structure MCode *)

unix.superglobalmegacorp.com

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