|
|
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 *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.