File:  [Research Unix] / researchv10no / cmd / sml / src / sparc / sparcmc.sml
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:34 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

(* Copyright 1989 by AT&T Bell Laboratories *)
(* sparcmc.sml
 *
 * J.H. Reppy
 * Cornell University
 * Ithaca, NY 14853
 * [email protected]
 *
 * HISTORY:
 *   11/20/89  created
 *
 *    The SPARC machine code emitter.
 *)

structure SparcMCode =
struct
    local open ByteArray in

    val code = ref (array(0, 0))

    fun getCodeString () = let
	  val s = extract (!code, 0, length (!code))
	  in
	    code := array(0, 0);
	    s
	  end

    end (* local *)
end (* SparcMCode *)

structure SparcMCEmit : EMITTER =
struct

(* +DEBUG *)
    fun diag (s : string) f x = (f x) handle e => (
	print "?exception "; print (System.exn_name e);
	print " in SparcCM."; print s; print "\n";
	raise e)
(* -DEBUG *)

    open SparcMCode SparcInstr

  (* Bit-wise operations *)
    val << = Bits.lshift
    val >> = Bits.rshift
    val ++ = Bits.orb
    val & = Bits.andb
    infix << >> ++ &

    val loc = ref 0     (* the location counter *)

    fun emitByte n = let
	  val i = !loc
	  in
	    loc := i+1;  ByteArray.update (!code, i, n)
	  end
(* +DEBUG *)
handle ByteArray.Subscript => (
  print "?exception Subscript in SparcMCEmit.emitByte. loc = ";
  print(!loc); print "\n";
  raise ByteArray.Subscript)
(* -DEBUG *)
(* DEBUG *) val emitByte = diag "emitByte" emitByte

    fun emitWord n = if (n < 0)
	  then emitWord (n + 65536)
	  else (emitByte (n >> 8); emitByte (n & 255))

    fun emitLong n = if (n < 0)
	  then let
	    val a = ~n
	    val b = (a >> 16)
	    val c = (a & 65535);
	    in
	      emitWord (~c + (if b = 0 then 0 else ~1)); emitWord (~b)
	    end
	  else (emitWord(n >> 16); emitWord (n & 65535))

    fun emitString s = let
	  fun copy i = (emitByte(ordof(s, i)); copy(i+1))
	  in
	    (copy 0) handle Ord => ()
	  end

    structure IEEERealConst = RealConst(IEEEReal(val emitWord = emitWord))

    val emitReal = IEEERealConst.realconst

    fun emitAddr (lab as Label{addr = ref a, ...}, k) = emitLong (k + a - !loc)

    fun define _ = ()

    local
      open System.Tags
    in
    fun mark () = emitLong (((!loc + 4) div 4) * power_tags + tag_backptr)
    end (* local *)

    local

      fun valOf (LABELexp{base, dst, offset}) = ((addrOf dst) + offset) - (addrOf base)

      fun immed13 (IMrand i) = (i & 8191)                     (* 13 bits *)
	| immed13 (LABrand labexp) = ((valOf labexp) & 8191)  (* 13 bits *)
	| immed13 (LOrand labexp) = ((valOf labexp) & 1023)   (* 10 bits *)
	| immed13 _ = ErrorMsg.impossible "[SparcMCEmit.immed13]"

    (* emit a 3 operand instruction with "11" in bits 31-30 *)
      fun emitOp11 opcode (REG a, REGrand(REG b), REG c) = (
	    emitWord(49152 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
	    emitWord(((a & 3) << 14) ++ b))
	| emitOp11 opcode (REG a, b, REG c) = (
	    emitWord(49152 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
	    emitWord(((a & 3) << 14) ++ 8192 ++ (immed13 b)))

      val emit_ld = emitOp11 0
      val emit_st = emitOp11 4
      val emit_ldb = emitOp11 1
      val emit_stb = emitOp11 5
      fun emit_ldf (r, ri, FREG fr) = emitOp11 32 (r, ri, REG fr)
      fun emit_stf (r, ri, FREG fr) = emitOp11 36 (r, ri, REG fr)

    (* emit a branch instruction *)
    fun emitBcc opcode lab = let
	  val disp = (((addrOf lab) - !loc) div 4)
	  val d = if disp < 0 then (disp + 4194304) else disp
	  in
	    if ((disp < ~2097152) orelse (2097152 <= disp))
	      then ErrorMsg.impossible "[SparcMCEmit.emitBcc]" else ();
	    emitLong ((opcode << 22) ++ d)
	  end

    val emit_ba = emitBcc 66        (* 1000010 *)
    val emit_be = emitBcc 10        (* 0001010 *)
    val emit_bne = emitBcc 74       (* 1001010 *)
    val emit_ble = emitBcc 18       (* 0010010 *)
    val emit_bge = emitBcc 90       (* 1011010 *)
    val emit_bl = emitBcc 26        (* 0011010 *)
    val emit_bg = emitBcc 82        (* 1010010 *)
    val emit_fbe = emitBcc 78       (* 1001110 *)
    val emit_fbne = emitBcc 14      (* 0001110 *)
    val emit_fble = emitBcc 110     (* 1101110 *)
    val emit_fbge = emitBcc 94      (* 1011110 *)
    val emit_fbl = emitBcc 38       (* 0100110 *)
    val emit_fbg = emitBcc 54       (* 0110110 *)

    (* emit a 3 operand instructions with "10" in bits 31-30. *)
      fun emitOp10 opcode (REG a, REGrand(REG b), REG c) = (
	    emitWord(32768 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
	    emitWord(((a & 3) << 14) ++ b))
	| emitOp10 opcode (REG a, b, REG c) = (
	    emitWord(32768 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2));
	    emitWord(((a & 3) << 14) ++ 8192 ++ (immed13 b)))

      val emit_jmpl = emitOp10 56       (* 111000 *)

    (* integer operations *)
      val emit_add = emitOp10 0         (* 000000 *)
      val emit_addcc = emitOp10 16      (* 010000 *)
      val emit_taddcctv = emitOp10 34   (* 100010 *)
      val emit_sub = emitOp10 4         (* 000100 *)
      val emit_subcc = emitOp10 20      (* 010100 *)
      val emit_sll = emitOp10 37        (* 100101 *)
      val emit_sra = emitOp10 39        (* 100111 *)
      val emit_and = emitOp10 1         (* 000001 *)
      val emit_andcc = emitOp10 17      (* 010001 *)
      val emit_or = emitOp10 2          (* 000010 *)
      val emit_xor = emitOp10 3         (* 000011 *)
      val emit_xnor = emitOp10 7        (* 000111 *)

      (* emit a floating-point instruction of three args; this has "10" in
       * bits 31-30 and "110100" in bits 24-19.
       *)
      fun emitFOp3 opcode (FREG a, FREG b, FREG c) = (
	    emitWord (33184 ++ (c << 9) ++ (a >> 2));
	    emitWord (((a & 3) << 14) ++ (opcode << 5) ++ b))
       (* emit a 2 operand floating-point instruction (same bits as above) *)
      fun emitFOp2 opcode (FREG a, FREG b) = (
	    emitWord (33184 ++ (b << 9));
	    emitWord ((opcode << 5) ++ a))
       (* emit a 2 operand floating-point instruction with "110101" in bits 24-19. *)
      fun emitFOp2' opcode (FREG a, FREG b) = (
	    emitWord (33192 ++ (a >> 2));
	    emitWord (((a & 3) << 14) ++ (opcode << 5) ++ b))
      val emit_fadd = emitFOp3 66       (* 001000010 *)
      val emit_fsub = emitFOp3 70       (* 001000110 *)
      val emit_fmul = emitFOp3 74       (* 001001010 *)
      val emit_fdiv = emitFOp3 78       (* 001001110 *)
      val emit_fneg = emitFOp2 5        (* 000000101 *)
      val emit_fcmp = emitFOp2' 82      (* 001010010 *)
    in

    fun emitInstr (I_nop) = emitLong 16777216 (* really "sethi 0,%g0" *)
      | emitInstr (I_ld args) = emit_ld args
      | emitInstr (I_ldb args) = emit_ldb args
      | emitInstr (I_ldf args) = emit_ldf args
      | emitInstr (I_st args) = emit_st args
      | emitInstr (I_stb args) = emit_stb args
      | emitInstr (I_stf args) = emit_stf args
      | emitInstr (I_sethi(arg, REG rd)) = let
	  val im = case arg
		 of (IMrand i) => i
		  | (HIrand labexp) => ((valOf labexp) >> 10)
		  | _ => ErrorMsg.impossible "[SparcMCEmit.emitInstr:sethi]"
	  in
	    emitWord(256 ++ (rd << 9) ++ ((im >> 16) & 63));
	    emitWord(im & 65535)
	  end
      | emitInstr (I_ba lab) = emit_ba lab
      | emitInstr (I_bcc(EQL, lab)) = emit_be lab
      | emitInstr (I_bcc(NEQ, lab)) = emit_bne lab
      | emitInstr (I_bcc(LSS, lab)) = emit_bl lab
      | emitInstr (I_bcc(LEQ, lab)) = emit_ble lab
      | emitInstr (I_bcc(GTR, lab)) = emit_bg lab
      | emitInstr (I_bcc(GEQ, lab)) = emit_bge lab
      | emitInstr (I_fbcc(EQL, lab)) = emit_fbe lab
      | emitInstr (I_fbcc(NEQ, lab)) = emit_fbne lab
      | emitInstr (I_fbcc(LSS, lab)) = emit_fbl lab
      | emitInstr (I_fbcc(LEQ, lab)) = emit_fble lab
      | emitInstr (I_fbcc(GTR, lab)) = emit_fbg lab
      | emitInstr (I_fbcc(GEQ, lab)) = emit_fbge lab
      | emitInstr (I_jmpl args) = emit_jmpl args
      | emitInstr (I_add args) = emit_add args
      | emitInstr (I_addcc args) = emit_addcc args
      | emitInstr (I_taddcctv args) = emit_taddcctv args
      | emitInstr (I_sub args) = emit_sub args
      | emitInstr (I_subcc args) = emit_subcc args
      | emitInstr (I_sll args) = emit_sll args
      | emitInstr (I_sra args) = emit_sra args
      | emitInstr (I_and args) = emit_and args
      | emitInstr (I_andcc args) = emit_andcc args
      | emitInstr (I_or args) = emit_or args
      | emitInstr (I_xor args) = emit_xor args
      | emitInstr (I_not(r1, rd)) = emit_xnor (r1, REGrand(REG 0), rd)
      | emitInstr (I_tvs) = (emitWord 36816; emitWord 8199)  (* "tvs 0x7" *)
      | emitInstr (I_fadd args) = emit_fadd args
      | emitInstr (I_fsub args) = emit_fsub args
      | emitInstr (I_fmul args) = emit_fmul args
      | emitInstr (I_fdiv args) = emit_fdiv args
      | emitInstr (I_fneg args) = emit_fneg args
      | emitInstr (I_fcmp args) = emit_fcmp args
(* DEBUG *) val emitInstr = diag "emitInstr" emitInstr

    end (* local *)

    fun comment _ = ()

    fun init n = (code := ByteArray.array(n, 0); loc := 0)

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.