Annotation of researchv10no/cmd/sml/src/vax/vaxmcode.sml, revision 1.1

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 *)

unix.superglobalmegacorp.com

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