|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: structure VaxMCode : VAXMCODER = struct ! 3: ! 4: structure Jumps = struct ! 5: datatype JumpKind = MODE | WHICH of (int ref * int * int) ! 6: | BYTEDISPL ! 7: | LABPTR of int ! 8: | COND of (int ref * int * int) | JBR ! 9: fun sbyte i = chr(if i<0 then 256+i else i) ! 10: fun eword i = ! 11: if i<0 then eword(65536+i) ! 12: else [chr(i mod 256), chr(i div 256)] ! 13: fun elong i = ! 14: if i<0 ! 15: then let val a = ~i; ! 16: val b = a mod 65536; ! 17: val c = a div 65536; ! 18: in eword(~b) @ eword(~c + if b=0 then 0 else ~1) ! 19: end ! 20: else eword(i mod 65536) @ eword(i div 65536) ! 21: fun intsize(i) = ! 22: if i >= ~128 andalso i < 128 ! 23: then 1 ! 24: else if i >= ~32768 andalso i < 32768 ! 25: then 2 ! 26: else 4; ! 27: ! 28: fun emitlong i = implode(elong i) ! 29: ! 30: fun sizejump(mode,oldsize,s,d) = ! 31: let fun which (r,a,b) = ! 32: case oldsize of 1 => r := a | _ => r := b ! 33: in case (mode,intsize(d-(s+oldsize))) ! 34: of (MODE,i) => i+1 ! 35: | (LABPTR _, _) => 4 ! 36: | (BYTEDISPL, _) => 1 ! 37: | (WHICH _, _) => 1 ! 38: | (COND x, 1) => (which x; 1) ! 39: | (COND x, 2) => (which x; 4) ! 40: | (COND x, _) => (which x; 7) ! 41: | (JBR,1) => 2 ! 42: | (JBR,2) => 3 ! 43: | (JBR,_) => 6 ! 44: end ! 45: ! 46: fun emitjump(MODE,2,s,d) = chr(10*16+15) ^ sbyte(d-s-2) ! 47: | emitjump(MODE,3,s,d) = implode(chr(12*16+15) :: eword(d-s-3)) ! 48: | emitjump(MODE,5,s,d) = implode(chr(14*16+15) :: elong (d-s-5)) ! 49: | emitjump(BYTEDISPL,1,s,d) = sbyte(d-s-1) ! 50: | emitjump(LABPTR i, _,s,d) = emitlong(d-s+i) ! 51: | emitjump(WHICH(ref i,_,_), _,_,_) = chr i ! 52: | emitjump(COND _, 1,s,d) = sbyte(d-s-1) ! 53: | emitjump(COND _, 4,s,d) = implode(chr 3 :: chr(3*16+1) :: eword(d-s-4)) ! 54: | emitjump(COND _, 7,s,d) = implode(chr 6 :: chr(16+7) :: chr(14*16+15) ! 55: :: elong (d-s-7)) ! 56: | emitjump(JBR,2,s,d) = chr(16+1) ^ sbyte (d-s-2) ! 57: | emitjump(JBR,3,s,d) = implode(chr(3*16+1) :: eword (d-s-3)) ! 58: | emitjump(JBR,6,s,d) = implode(chr(16+7):: chr(14*16+15) :: elong (d-s-6)) ! 59: | emitjump _ = ErrorMsg.impossible "emitjump" ! 60: ! 61: end (* Jumps *) ! 62: ! 63: structure Emitter : BACKPATCH = Backpatch(Jumps) ! 64: ! 65: structure Coder : VAXCODER = struct ! 66: ! 67: open Emitter Jumps ! 68: ! 69: fun emitbyte i = emitstring(chr i) ! 70: fun signedbyte i = emitbyte(if i<0 then 256+i else i) ! 71: fun emitword i = ! 72: if i<0 then emitword(65536+i) ! 73: else (emitbyte(i mod 256); emitbyte(i div 256)); ! 74: fun emitlong i = ! 75: if i<0 ! 76: then let val a = ~i; ! 77: val b = a mod 65536; ! 78: val c = a div 65536; ! 79: in emitword(~b); ! 80: emitword(~c + if b=0 then 0 else ~1) ! 81: end ! 82: else (emitword(i mod 65536); emitword(i div 65536)) ! 83: fun intsize(i) = ! 84: if i >= ~128 andalso i < 128 ! 85: then 1 ! 86: else if i >= ~32768 andalso i < 32768 ! 87: then 2 ! 88: else 4; ! 89: ! 90: datatype Register = reg of int ! 91: ! 92: val r0 = reg 0 ! 93: val r1 = reg 1 ! 94: val r2 = reg 2 ! 95: val r3 = reg 3 ! 96: val r4 = reg 4 ! 97: val r5 = reg 5 ! 98: val r6 = reg 6 ! 99: val r7 = reg 7 ! 100: val r8 = reg 8 ! 101: val r9 = reg 9 ! 102: val r10 = reg 10 ! 103: val r11 = reg 11 ! 104: val r12 = reg 12 ! 105: val r13 = reg 13 ! 106: val sp = reg 14 ! 107: val pc = reg 15 ! 108: ! 109: datatype EA = direct of Register ! 110: | autoinc of Register ! 111: | autodec of Register ! 112: | displace of int * Register ! 113: | deferred of int * Register ! 114: | immed of int ! 115: | immedlab of Label ! 116: | address of Label ! 117: | index of EA * Register ! 118: ! 119: (* This is identical to M68PrimReal except that emitword is different, ! 120: and the bias is off by two. *) ! 121: structure VaxPrimReal : PRIMREAL = ! 122: struct ! 123: val significant = 53 (* 52 + redundant 1/2 bit *) ! 124: fun outofrange s = ErrorMsg.complain("Real constant "^s^" out of range") ! 125: (* Convert a portion of a boolean array to the appropriate integer. *) ! 126: exception Bits ! 127: fun bits(a,start,width) = ! 128: let fun b true = 1 ! 129: | b false = 0 ! 130: fun f 0 = b (a sub start) ! 131: | f n = b (a sub (start+n)) + 2 * f(n-1) ! 132: in if Array.length a < start+width orelse start < 0 orelse width < 0 ! 133: then raise Bits ! 134: else f (width-1) ! 135: end ! 136: fun emitreal (sign,frac,exp) = ! 137: let val exponent = exp + 1024 ! 138: fun emit () = ! 139: let val word0 = ! 140: case frac sub 0 of (* zero? *) ! 141: true => Bits.orb(Bits.lshift(sign,15), ! 142: Bits.orb(Bits.lshift(exponent,4), ! 143: bits(frac,1,4))) ! 144: | false => 0 ! 145: val word1 = bits(frac,5,16) ! 146: val word2 = bits(frac,21,16) ! 147: val word3 = bits(frac,37,16) ! 148: in emitword word0; ! 149: emitword word1; ! 150: emitword word2; ! 151: emitword word3 ! 152: end ! 153: in if exponent < 1 orelse exponent > 2047 ! 154: then outofrange "" (* A hack *) ! 155: else emit() ! 156: end ! 157: end ! 158: structure VaxRealConst = RealConst(VaxPrimReal) ! 159: open VaxRealConst ! 160: ! 161: fun regmode(mode,r) = emitbyte(mode*16+r) ! 162: ! 163: fun emitarg (direct(reg r)) = regmode(5,r) ! 164: | emitarg (autoinc(reg r)) = regmode(8,r) ! 165: | emitarg (autodec(reg r)) = regmode(7,r) ! 166: | emitarg (immed i) = ! 167: if i>=0 andalso i<64 then emitbyte i ! 168: else (emitarg(autoinc pc); emitlong i) ! 169: | emitarg (displace(i,reg r)) = ! 170: if i=0 then regmode(6,r) ! 171: else (case intsize i ! 172: of 1 => (regmode(10,r); signedbyte i) ! 173: | 2 => (regmode(12,r); emitword i) ! 174: | 4 => (regmode(14,r); emitlong i)) ! 175: | emitarg (deferred(i,reg r)) = ! 176: (case intsize i of ! 177: 1 => (regmode(11,r); signedbyte i) ! 178: | 2 => (regmode(13,r); emitword i) ! 179: | 4 => (regmode(15,r); emitlong i)) ! 180: | emitarg (index(ea, reg r)) = (regmode(4,r); emitarg ea) ! 181: | emitarg (address lab) = jump(MODE,lab) (* no good for branches *) ! 182: ! 183: fun emit2arg (arg1,arg2) = (emitarg arg1; emitarg arg2) ! 184: ! 185: fun emit3arg (arg1,arg2,arg3) = (emitarg arg1; emitarg arg2; emitarg arg3) ! 186: ! 187: fun pure (autoinc _) = false ! 188: | pure (autodec _) = false ! 189: | pure _ = true ! 190: ! 191: fun args23(f2,f3) (args as (a,b,c)) = ! 192: if b=c andalso pure b then (f2(a,b)) else f3 args ! 193: ! 194: fun immedbyte(i) = ! 195: if i>=0 andalso i<64 then emitbyte i ! 196: else (emitarg(autoinc pc); signedbyte i); ! 197: ! 198: fun immedword(i) = ! 199: if i>=0 andalso i<64 then emitbyte i ! 200: else (emitarg(autoinc pc); emitword i); ! 201: ! 202: fun emitlab (i,lab) = jump(LABPTR i, lab) ! 203: ! 204: fun jbr (address lab) = jump(JBR,lab) ! 205: fun bbc (immed 0, arg, address lab) = ! 206: let val r = (ref 0, 14*16+9,14*16+8) ! 207: in jump(WHICH r, lab); emitarg arg; jump(COND r, lab) ! 208: end ! 209: | bbc (arg1, arg2, address lab) = ! 210: let val r = (ref 0, 14*16+1,14*16+0) ! 211: in jump(WHICH r, lab); emitarg arg1; emitarg arg2; jump(COND r, lab) ! 212: end ! 213: fun bbs (immed 0, arg, address lab) = ! 214: let val r = (ref 0, 14*16+8,14*16+9) ! 215: in jump(WHICH r, lab); emitarg arg; jump(COND r, lab) ! 216: end ! 217: | bbs (arg1, arg2, address lab) = ! 218: let val r = (ref 0, 14*16+0,14*16+1) ! 219: in jump(WHICH r, lab); emitarg arg1; emitarg arg2; jump(COND r, lab) ! 220: end ! 221: ! 222: fun movb (immed i, arg2) = (emitbyte(9*16); immedbyte i; emitarg arg2) ! 223: | movb args = (emitbyte (9*16); emit2arg args) ! 224: ! 225: fun movzbl args = (emitbyte (9*16+10); emit2arg args) ! 226: ! 227: fun pushal args = (emitbyte (13*16+15); emitarg args) ! 228: ! 229: fun addl2 (immed 1, arg) = (emitbyte(13*16+6); emitarg arg) ! 230: | addl2 args = (emitbyte (12*16); emit2arg args) ! 231: ! 232: fun moval (arg, autodec(reg 14)) = pushal arg ! 233: | moval (args as (displace(i, reg p),direct (reg q))) = ! 234: if p=q andalso i> ~128 andalso i < 128 ! 235: then addl2(immed i, direct(reg p)) ! 236: else (emitbyte (13*16+14); emit2arg args) ! 237: | moval args = (emitbyte (13*16+14); emit2arg args) ! 238: ! 239: fun movl (immedlab l, arg) = moval(address l, arg) ! 240: | movl (arg, autodec(reg 14)) = (emitbyte(13*16+13); emitarg arg) ! 241: | movl (immed 0, arg) = (emitbyte(13*16+4); emitarg arg) ! 242: | movl args = (emitbyte (13*16); emit2arg args) ! 243: ! 244: fun movq args = (emitbyte (7*16+13); emit2arg args) ! 245: ! 246: fun rsb () = emitbyte 5 ! 247: fun cmpl args = (emitbyte (13*16+1); emit2arg args) ! 248: fun addl3 args = (emitbyte (12*16+1); emit3arg args) ! 249: val addl3 = args23 (addl2,addl3) ! 250: fun subl2 args = (emitbyte (12*16+2); emit2arg args) ! 251: fun subl3 args = (emitbyte (12*16+3); emit3arg args) ! 252: val subl3 = args23 (subl2,subl3) ! 253: fun bisl3 args = (emitbyte (12*16+9); emit3arg args) ! 254: fun bicl3 args = (emitbyte (12*16+11); emit3arg args) ! 255: fun xorl3 args = (emitbyte (12*16+13); emit3arg args) ! 256: fun ashl(immed i,arg2,arg3)=(emitbyte(7*16+8);immedbyte i;emitarg arg2;emitarg arg3) ! 257: | ashl args = (emitbyte (7*16+8); emit3arg args) ! 258: fun mull2 args = (emitbyte (12*16+4); emit2arg args) ! 259: fun divl3 args = (emitbyte (12*16+7); emit3arg args) ! 260: fun divl2 args = (emitbyte (12*16+6); emit2arg args) ! 261: val divl3 = args23 (divl2,divl3) ! 262: fun jmp (arg as address lab) = jbr arg ! 263: | jmp arg = (emitbyte (16+7); emitarg arg) ! 264: fun brb (displace(i,reg 15)) = (emitbyte (16+1); signedbyte i) ! 265: fun brw (displace(i,reg 15)) = (emitbyte (3*16+1); emitword i) ! 266: ! 267: local fun condj(i,j) = ! 268: fn (address lab) => let val r = (ref 0,16+i,16+j) ! 269: in jump(WHICH r, lab); jump(COND r, lab) ! 270: end ! 271: | displace(k, reg 15) => (emitbyte (16+i); signedbyte k) ! 272: in val beql = condj(3,2) ! 273: val bneq = condj(2,3) ! 274: val jne = bneq ! 275: val bgeq = condj(8,9) ! 276: val bgtr = condj(4,5) ! 277: val blss = condj(9,8) ! 278: val bleq = condj(5,4) ! 279: end ! 280: fun sobgeq (arg,address lab) = (emitbyte (15*16+4); emitarg arg; ! 281: jump(BYTEDISPL,lab)) ! 282: ! 283: fun movg args = (emitword(20733); emit2arg args) ! 284: fun mnegg args = (emitword(21245); emit2arg args) ! 285: fun addg3 args = (emitword(16893); emit3arg args) ! 286: fun subg3 args = (emitword(17405); emit3arg args) ! 287: fun mulg3 args = (emitword(17917); emit3arg args) ! 288: fun divg3 args = (emitword(18429); emit3arg args) ! 289: fun cmpg args = (emitword(20989); emit2arg args) ! 290: ! 291: fun push arg = movl(arg,autodec sp) ! 292: fun pusha arg = pushal arg ! 293: fun pop arg = movl(autoinc sp,arg) ! 294: ! 295: fun comment _ = () ! 296: ! 297: end (* Coder *) ! 298: ! 299: val finish = Emitter.finish ! 300: ! 301: end (* structure MCode *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.