Annotation of researchv10no/cmd/sml/src/sparc/sparcmc.sml, revision 1.1.1.1

1.1       root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
                      2: (* sparcmc.sml
                      3:  *
                      4:  * J.H. Reppy
                      5:  * Cornell University
                      6:  * Ithaca, NY 14853
                      7:  * [email protected]
                      8:  *
                      9:  * HISTORY:
                     10:  *   11/20/89  created
                     11:  *
                     12:  *    The SPARC machine code emitter.
                     13:  *)
                     14: 
                     15: structure SparcMCode =
                     16: struct
                     17:     local open ByteArray in
                     18: 
                     19:     val code = ref (array(0, 0))
                     20: 
                     21:     fun getCodeString () = let
                     22:          val s = extract (!code, 0, length (!code))
                     23:          in
                     24:            code := array(0, 0);
                     25:            s
                     26:          end
                     27: 
                     28:     end (* local *)
                     29: end (* SparcMCode *)
                     30: 
                     31: structure SparcMCEmit : EMITTER =
                     32: struct
                     33: 
                     34: (* +DEBUG *)
                     35:     fun diag (s : string) f x = (f x) handle e => (
                     36:        print "?exception "; print (System.exn_name e);
                     37:        print " in SparcCM."; print s; print "\n";
                     38:        raise e)
                     39: (* -DEBUG *)
                     40: 
                     41:     open SparcMCode SparcInstr
                     42: 
                     43:   (* Bit-wise operations *)
                     44:     val << = Bits.lshift
                     45:     val >> = Bits.rshift
                     46:     val ++ = Bits.orb
                     47:     val & = Bits.andb
                     48:     infix << >> ++ &
                     49: 
                     50:     val loc = ref 0     (* the location counter *)
                     51: 
                     52:     fun emitByte n = let
                     53:          val i = !loc
                     54:          in
                     55:            loc := i+1;  ByteArray.update (!code, i, n)
                     56:          end
                     57: (* +DEBUG *)
                     58: handle ByteArray.Subscript => (
                     59:   print "?exception Subscript in SparcMCEmit.emitByte. loc = ";
                     60:   print(!loc); print "\n";
                     61:   raise ByteArray.Subscript)
                     62: (* -DEBUG *)
                     63: (* DEBUG *) val emitByte = diag "emitByte" emitByte
                     64: 
                     65:     fun emitWord n = if (n < 0)
                     66:          then emitWord (n + 65536)
                     67:          else (emitByte (n >> 8); emitByte (n & 255))
                     68: 
                     69:     fun emitLong n = if (n < 0)
                     70:          then let
                     71:            val a = ~n
                     72:            val b = (a >> 16)
                     73:            val c = (a & 65535);
                     74:            in
                     75:              emitWord (~c + (if b = 0 then 0 else ~1)); emitWord (~b)
                     76:            end
                     77:          else (emitWord(n >> 16); emitWord (n & 65535))
                     78: 
                     79:     fun emitString s = let
                     80:          fun copy i = (emitByte(ordof(s, i)); copy(i+1))
                     81:          in
                     82:            (copy 0) handle Ord => ()
                     83:          end
                     84: 
                     85:     structure IEEERealConst = RealConst(IEEEReal(val emitWord = emitWord))
                     86: 
                     87:     val emitReal = IEEERealConst.realconst
                     88: 
                     89:     fun emitAddr (lab as Label{addr = ref a, ...}, k) = emitLong (k + a - !loc)
                     90: 
                     91:     fun define _ = ()
                     92: 
                     93:     local
                     94:       open System.Tags
                     95:     in
                     96:     fun mark () = emitLong (((!loc + 4) div 4) * power_tags + tag_backptr)
                     97:     end (* local *)
                     98: 
                     99:     local
                    100: 
                    101:       fun valOf (LABELexp{base, dst, offset}) = ((addrOf dst) + offset) - (addrOf base)
                    102: 
                    103:       fun immed13 (IMrand i) = (i & 8191)                     (* 13 bits *)
                    104:        | immed13 (LABrand labexp) = ((valOf labexp) & 8191)  (* 13 bits *)
                    105:        | immed13 (LOrand labexp) = ((valOf labexp) & 1023)   (* 10 bits *)
                    106:        | immed13 _ = ErrorMsg.impossible "[SparcMCEmit.immed13]"
                    107: 
                    108:     (* emit a 3 operand instruction with "11" in bits 31-30 *)
                    109:       fun emitOp11 opcode (REG a, REGrand(REG b), REG c) = (
                    110:            emitWord(49152 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
                    111:            emitWord(((a & 3) << 14) ++ b))
                    112:        | emitOp11 opcode (REG a, b, REG c) = (
                    113:            emitWord(49152 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
                    114:            emitWord(((a & 3) << 14) ++ 8192 ++ (immed13 b)))
                    115: 
                    116:       val emit_ld = emitOp11 0
                    117:       val emit_st = emitOp11 4
                    118:       val emit_ldb = emitOp11 1
                    119:       val emit_stb = emitOp11 5
                    120:       fun emit_ldf (r, ri, FREG fr) = emitOp11 32 (r, ri, REG fr)
                    121:       fun emit_stf (r, ri, FREG fr) = emitOp11 36 (r, ri, REG fr)
                    122: 
                    123:     (* emit a branch instruction *)
                    124:     fun emitBcc opcode lab = let
                    125:          val disp = (((addrOf lab) - !loc) div 4)
                    126:          val d = if disp < 0 then (disp + 4194304) else disp
                    127:          in
                    128:            if ((disp < ~2097152) orelse (2097152 <= disp))
                    129:              then ErrorMsg.impossible "[SparcMCEmit.emitBcc]" else ();
                    130:            emitLong ((opcode << 22) ++ d)
                    131:          end
                    132: 
                    133:     val emit_ba = emitBcc 66        (* 1000010 *)
                    134:     val emit_be = emitBcc 10        (* 0001010 *)
                    135:     val emit_bne = emitBcc 74       (* 1001010 *)
                    136:     val emit_ble = emitBcc 18       (* 0010010 *)
                    137:     val emit_bge = emitBcc 90       (* 1011010 *)
                    138:     val emit_bl = emitBcc 26        (* 0011010 *)
                    139:     val emit_bg = emitBcc 82        (* 1010010 *)
                    140:     val emit_fbe = emitBcc 78       (* 1001110 *)
                    141:     val emit_fbne = emitBcc 14      (* 0001110 *)
                    142:     val emit_fble = emitBcc 110     (* 1101110 *)
                    143:     val emit_fbge = emitBcc 94      (* 1011110 *)
                    144:     val emit_fbl = emitBcc 38       (* 0100110 *)
                    145:     val emit_fbg = emitBcc 54       (* 0110110 *)
                    146: 
                    147:     (* emit a 3 operand instructions with "10" in bits 31-30. *)
                    148:       fun emitOp10 opcode (REG a, REGrand(REG b), REG c) = (
                    149:            emitWord(32768 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
                    150:            emitWord(((a & 3) << 14) ++ b))
                    151:        | emitOp10 opcode (REG a, b, REG c) = (
                    152:            emitWord(32768 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
                    153:            emitWord(((a & 3) << 14) ++ 8192 ++ (immed13 b)))
                    154: 
                    155:       val emit_jmpl = emitOp10 56       (* 111000 *)
                    156: 
                    157:     (* integer operations *)
                    158:       val emit_add = emitOp10 0         (* 000000 *)
                    159:       val emit_addcc = emitOp10 16      (* 010000 *)
                    160:       val emit_taddcctv = emitOp10 34   (* 100010 *)
                    161:       val emit_sub = emitOp10 4         (* 000100 *)
                    162:       val emit_subcc = emitOp10 20      (* 010100 *)
                    163:       val emit_sll = emitOp10 37        (* 100101 *)
                    164:       val emit_sra = emitOp10 39        (* 100111 *)
                    165:       val emit_and = emitOp10 1         (* 000001 *)
                    166:       val emit_andcc = emitOp10 17      (* 010001 *)
                    167:       val emit_or = emitOp10 2          (* 000010 *)
                    168:       val emit_xor = emitOp10 3         (* 000011 *)
                    169:       val emit_xnor = emitOp10 7        (* 000111 *)
                    170: 
                    171:       (* emit a floating-point instruction of three args; this has "10" in
                    172:        * bits 31-30 and "110100" in bits 24-19.
                    173:        *)
                    174:       fun emitFOp3 opcode (FREG a, FREG b, FREG c) = (
                    175:            emitWord (33184 ++ (c << 9) ++ (a >> 2));
                    176:            emitWord (((a & 3) << 14) ++ (opcode << 5) ++ b))
                    177:        (* emit a 2 operand floating-point instruction (same bits as above) *)
                    178:       fun emitFOp2 opcode (FREG a, FREG b) = (
                    179:            emitWord (33184 ++ (b << 9));
                    180:            emitWord ((opcode << 5) ++ a))
                    181:        (* emit a 2 operand floating-point instruction with "110101" in bits 24-19. *)
                    182:       fun emitFOp2' opcode (FREG a, FREG b) = (
                    183:            emitWord (33192 ++ (a >> 2));
                    184:            emitWord (((a & 3) << 14) ++ (opcode << 5) ++ b))
                    185:       val emit_fadd = emitFOp3 66       (* 001000010 *)
                    186:       val emit_fsub = emitFOp3 70       (* 001000110 *)
                    187:       val emit_fmul = emitFOp3 74       (* 001001010 *)
                    188:       val emit_fdiv = emitFOp3 78       (* 001001110 *)
                    189:       val emit_fneg = emitFOp2 5        (* 000000101 *)
                    190:       val emit_fcmp = emitFOp2' 82      (* 001010010 *)
                    191:     in
                    192: 
                    193:     fun emitInstr (I_nop) = emitLong 16777216 (* really "sethi 0,%g0" *)
                    194:       | emitInstr (I_ld args) = emit_ld args
                    195:       | emitInstr (I_ldb args) = emit_ldb args
                    196:       | emitInstr (I_ldf args) = emit_ldf args
                    197:       | emitInstr (I_st args) = emit_st args
                    198:       | emitInstr (I_stb args) = emit_stb args
                    199:       | emitInstr (I_stf args) = emit_stf args
                    200:       | emitInstr (I_sethi(arg, REG rd)) = let
                    201:          val im = case arg
                    202:                 of (IMrand i) => i
                    203:                  | (HIrand labexp) => ((valOf labexp) >> 10)
                    204:                  | _ => ErrorMsg.impossible "[SparcMCEmit.emitInstr:sethi]"
                    205:          in
                    206:            emitWord(256 ++ (rd << 9) ++ ((im >> 16) & 63));
                    207:            emitWord(im & 65535)
                    208:          end
                    209:       | emitInstr (I_ba lab) = emit_ba lab
                    210:       | emitInstr (I_bcc(EQL, lab)) = emit_be lab
                    211:       | emitInstr (I_bcc(NEQ, lab)) = emit_bne lab
                    212:       | emitInstr (I_bcc(LSS, lab)) = emit_bl lab
                    213:       | emitInstr (I_bcc(LEQ, lab)) = emit_ble lab
                    214:       | emitInstr (I_bcc(GTR, lab)) = emit_bg lab
                    215:       | emitInstr (I_bcc(GEQ, lab)) = emit_bge lab
                    216:       | emitInstr (I_fbcc(EQL, lab)) = emit_fbe lab
                    217:       | emitInstr (I_fbcc(NEQ, lab)) = emit_fbne lab
                    218:       | emitInstr (I_fbcc(LSS, lab)) = emit_fbl lab
                    219:       | emitInstr (I_fbcc(LEQ, lab)) = emit_fble lab
                    220:       | emitInstr (I_fbcc(GTR, lab)) = emit_fbg lab
                    221:       | emitInstr (I_fbcc(GEQ, lab)) = emit_fbge lab
                    222:       | emitInstr (I_jmpl args) = emit_jmpl args
                    223:       | emitInstr (I_add args) = emit_add args
                    224:       | emitInstr (I_addcc args) = emit_addcc args
                    225:       | emitInstr (I_taddcctv args) = emit_taddcctv args
                    226:       | emitInstr (I_sub args) = emit_sub args
                    227:       | emitInstr (I_subcc args) = emit_subcc args
                    228:       | emitInstr (I_sll args) = emit_sll args
                    229:       | emitInstr (I_sra args) = emit_sra args
                    230:       | emitInstr (I_and args) = emit_and args
                    231:       | emitInstr (I_andcc args) = emit_andcc args
                    232:       | emitInstr (I_or args) = emit_or args
                    233:       | emitInstr (I_xor args) = emit_xor args
                    234:       | emitInstr (I_not(r1, rd)) = emit_xnor (r1, REGrand(REG 0), rd)
                    235:       | emitInstr (I_tvs) = (emitWord 36816; emitWord 8199)  (* "tvs 0x7" *)
                    236:       | emitInstr (I_fadd args) = emit_fadd args
                    237:       | emitInstr (I_fsub args) = emit_fsub args
                    238:       | emitInstr (I_fmul args) = emit_fmul args
                    239:       | emitInstr (I_fdiv args) = emit_fdiv args
                    240:       | emitInstr (I_fneg args) = emit_fneg args
                    241:       | emitInstr (I_fcmp args) = emit_fcmp args
                    242: (* DEBUG *) val emitInstr = diag "emitInstr" emitInstr
                    243: 
                    244:     end (* local *)
                    245: 
                    246:     fun comment _ = ()
                    247: 
                    248:     fun init n = (code := ByteArray.array(n, 0); loc := 0)
                    249: 
                    250: end (* structure SparcMCEmit *)

unix.superglobalmegacorp.com

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