📄 sparc.java
字号:
/** * Implementation of CodeBlock for SPARC systems * @version $Id: SPARC.java,v 1.6 1998/04/18 23:30:29 pab Exp $ * @author Peter A. Bigot *//* This is part of the Just-In-Time compiler for the Toba system. */package toba.jit;import toba.classfile.*;import toba.runtime.*;class SPARC extends CodeBlock { private void BasicInit () { setBVlength (32); setLittleEndian (false); setCheckWordAlign (true); setJumpFromNextInstr (false); } /** Constructors: pass up to parent */ public SPARC (Method m, int imax) { super (m, imax); BasicInit (); } public SPARC (Method m) { super (m); BasicInit (); } /** Convert from symbolic register name to 5-bit string encoding * @param s String representation of SPARC register name * @returns bit string representing input register number */ private static String BS (String s) { /* The stack pointer is the 6th output register */ if (s.equals ("%sp")) { s = "%o6"; } /* The frame pointer is the 6th input register */ if (s.equals ("%fp")) { s = "%i6"; } /* Symbolic register names are in format '%' '[golir]' <digit>+ */ if (! s.startsWith ("%")) { if (5 != s.length()) { throw new InternalError ("illegal string representation of register: " + s); } return s; } int rn; // Absolute number of register in file switch (s.charAt (1)) { case 'i': // Input registers start at absolute 24 rn = 24; break; case 'l': // Local registers start at absolute 16 rn = 16; break; case 'o': // Output registers start at absolute 8 rn = 8; break; case 'r': // Unspecified, FP, and global registers case 'f': // all start at 0. case 'g': rn = 0; break; default: // Unrecognized register class throw new InternalError ("invalid register class"); } /* Add in the register file offset from the given string */ try { rn += Integer.valueOf (s.substring(2)).intValue(); } catch (Exception e) { /* Invalid register offset */ throw new InternalError ("at register decoding" + e); } /* Return the value, encoded in a bit string of 5 bits */ return BS (rn, 5); } /** Activation record layout for JIT-compiled SPARC code * * %fp->| | * |-------------------------------|-\ * | struct mythread * tdata | | * |-------------------------------| > Local data structures required * | void * oldbuf | | for handling of exceptions. * |-------------------------------| | Block is absent from frames * | volatile int pcormheld | | that don't need it. Size * |-------------------------------| | OHDATA is kept in JITCodeGen * | jmpbuf newbuf (non-const len)| | instance. * |-------------------------------|-/ * | 2 words for FPU/ALU xfers | * |-------------------------------| %fp[-(8+OHDATA)] * | Java local variables | * |-------------------------------| * %l7->| Java evaluation stack | (grows downward; %l7 points to top) * |-------------------------------| * | outgoing parameters past 6 | * |-------------------------------|-\ * | 6 words for callee to dump | | * | register arguments | | * |-------------------------------| > minimum stack frame * | One word struct-ret address | | * |-------------------------------| | * | 16 words to save IN and | | * %sp->| LOCAL register on overflow | | * |-------------------------------|-/ */ // Sun does not have an ALU/FPU transfer buffer just below the frame // pointer. GCC has a four-word one. We can get away with two words. static final int WINDOWSIZE = (16*4); static final int STRETADDRSIZE = 4; static final int ARGPUSHSIZE = (6*4); static final int ARGPUSH = (WINDOWSIZE+STRETADDRSIZE); static final int ALUFPUXFERSIZE = (2*4); static final int MINFRAME = (WINDOWSIZE + STRETADDRSIZE + ARGPUSHSIZE + ALUFPUXFERSIZE); /* Type codes in backpatch markers. Apply with resolveCode as: * int brcode, Instr ins, FieldRef fr * int brcode, Instr ins, long lv */ // Call to the MethodRef parameter: MethodRef mr protected static final int brCALL = 1; // Jump to the local label: long tlbl protected static final int brJUMP = 2; // Load from the VariableRef parameter: VariableRef vr protected static final int brLOAD = 3; // Set from the FieldRef table slot: FieldRef fr protected static final int brFIELDLOAD = 4; // Call to a fixed address: long addr protected static final int brACALL = 5; // Load a pointer to the native class for a reference: (ClassRef|FieldRef) fr protected static final int brLOADNatCl = 6; // Set from the FieldRef table slot: ClassRef cr protected static final int brCLREFLOAD = 7; // Set to the method entry point plus the offset: long offs protected static final int brLOADCodeRel = 8; // Initialize a switch address table: long swtaddr protected static final int brINITSwitchTable = 9; // Set to the address where the given jvm pc starts: long offs protected static final int brLOADCodeAbs = 10; // Set to the address where the given label starts: long offs protected static final int brLOADCodeLbl = 11; /** Add a format(1) (CALL) SPARC instruction to the code buffer * @param op the leading two-bit code indicating instruction value * @param disp30 a signed thirty-bit immediate value * @returns the encoded instruction */ private int Fmt1 (String op, // op value int disp30) // displacement { return addWord (BV (op + BS (disp30, 30))); } /** Add a format(2) immediate-value SPARC instruction to the code buffer * @param op The leading two-bit code indicating basic instruction type * @param rd name of destination register * @param op2 the three bit opcode value * @param imm22 the twenty-two bit immediate value * @returns the encoded instruction */ private int Fmt2 (String op, // op value String rd, // destination register String op2, // opcode int imm22) // immediate value { return addWord (BV (op + BS(rd) + op2 + BS(imm22,22))); } public int PatchDisp22 (int offs, // Offset, in bytes, of word to overwrite int imm22) // Immediate value to store there { int iv; iv = getCodeWord (offs); iv = ((iv & ~(0x3FF)) | (imm22 & 0x3FF)); return storeWord (iv, offs); } /** Add a format(2) immediate-value SPARC instruction to the code buffer * @param op The leading two-bit code indicating basic instruction type * @param ign value to store in the 5-bit ignored field * @param op2 the three bit opcode value * @param imm22 the twenty-two bit immediate value * @returns the encoded instruction */ private int Fmt2 (String op, // op value int ign, // ignored value String op2, // opcode int imm22) // immediate value { return addWord (BV (op + BS(ign,5) + op2 + BS(imm22,22))); } /** Add a format(3) binary immediate-value SPARC instruction to the code buffer * @param op The leading two-bit code indicating basic instruction type * @param rd name of destination register * @param op3 the six bit opcode value * @param rs1 name of first source register * @param i one-bit absolute/address-space tag * @param simm13 the signed thirteen bit immediate value * @returns the encoded instruction */ private int Fmt3 (String op, // op value String rd, // destination register String op3, // opcode String rs1, // first source register int simm13) // signed immediate { return addWord (BV (op + BS(rd) + op3 + BS(rs1) + "1" + BS(simm13,13))); } /** Add a format(3) trinary SPARC instruction to the code buffer * @param op The leading two-bit code indicating basic instruction type * @param rd name of destination register * @param op3 the six bit opcode value * @param rs1 name of first source register * @param i one-bit absolute/address-space tag * @param rs2 name of second source register * @returns the encoded instruction */ private int Fmt3 (String op, // op value String rd, // destination register String op3, // opcode String rs1, // first source register String rs2) // second source register { return addWord (BV (op + BS(rd) + op3 + BS(rs1) + "000000000" + BS(rs2))); } /** Add a format(3) trinary SPARC floating point instruction to the code buffer * @param op The leading two-bit code indicating basic instruction type * @param rd name of destination register * @param op3 the six bit opcode value * @param opf the nine bit fp opcode value * @param rs2 name of second source register * @returns the encoded instruction */ private int Fmt3FP (String op, // op value String rd, // destination register String op3, // opcode String opf, // fp opcode String rs2) // second source register { return addWord (BV (op + BS(rd) + op3 + "00000" + opf + BS(rs2))); } /** Add a format(3) trinary SPARC floating point instruction to the code buffer * @param op The leading two-bit code indicating basic instruction type * @param rd name of destination register * @param op3 the six bit opcode value * @param rs1 name of the first source register * @param opf the nine bit fp opcode value * @param rs2 name of second source register * @returns the encoded instruction */ private int Fmt3FP (String op, // op value String rd, // destination register String op3, // opcode String rs1, // first source register String opf, // fp opcode String rs2) // second source register { return addWord (BV (op + BS(rd) + op3 + BS (rs1) + opf + BS(rs2))); } /** Add a format(3) trinary SPARC floating point instruction to the code buffer * @param op The leading two-bit code indicating basic instruction type * @param op3 the six bit opcode value * @param rs1 name of first source register * @param opf the nine bit fp opcode value * @param rs2 name of second source register * @returns the encoded instruction */ private int Fmt3FPC (String op, // op value String op3, // opcode String rs1, // first source register String opf, // fp opcode String rs2) // second source register { return addWord (BV (op + "00000" + op3 + BS(rs1) + opf + BS(rs2))); } /** save rs1, imm, rd */ public int SAVE (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "111100", rs1, imm); } /** restore rs1, imm, rd */ public int RESTORE (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "111101", rs1, imm); } /** restore %g0, 0, %g0 */ public int RESTORE () { return RESTORE ("%g0", 0, "%g0"); } /** st rd, rs1[imm] */ public int ST (String rd, String rs1, int imm) { return Fmt3 ("11", rd, "000100", rs1, imm); } /** stb rd, rs1[imm] */ public int STB (String rd, String rs1, int imm) { return Fmt3 ("11", rd, "000101", rs1, imm); } /** sth rd, rs1[imm] */ public int STH (String rd, String rs1, int imm) { return Fmt3 ("11", rd, "000110", rs1, imm); } /** stf rd, rs1[imm] */ public int STF (String rd, String rs1, int imm) { return Fmt3 ("11", rd, "100100", rs1, imm); } /** stdf rd, rs1[imm] */ public int STDF (String rd, String rs1, int imm) { return Fmt3 ("11", rd, "100111", rs1, imm); } /** ld rs1[imm], rd */ public int LD (String rs1, int imm, String rd) { return Fmt3 ("11", rd, "000000", rs1, imm); } /** ld rs1[rs2], rd */ public int LD (String rs1, String rs2, String rd) { return Fmt3 ("11", rd, "000000", rs1, rs2); } /** ldsb rs1[imm], rd */ public int LDSB (String rs1, int imm, String rd) { return Fmt3 ("11", rd, "001001", rs1, imm); } /** ldub rs1[imm], rd */ public int LDUB (String rs1, int imm, String rd) { return Fmt3 ("11", rd, "000001", rs1, imm); } /** ldsh rs1[imm], rd */ public int LDSH (String rs1, int imm, String rd) { return Fmt3 ("11", rd, "001010", rs1, imm); } /** lduh rs1[imm], rd */ public int LDUH (String rs1, int imm, String rd) { return Fmt3 ("11", rd, "000010", rs1, imm); } /** ldf rs1[imm], rd */ public int LDF (String rs1, int imm, String rd) { return Fmt3 ("11", rd, "100000", rs1, imm); } /** lddf rs1[imm], rd */ public int LDDF (String rs1, int imm, String rd) { return Fmt3 ("11", rd, "100011", rs1, imm); } /** jmpl rs1+rs2, rd */ public int JMPL (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "111000", rs1, rs2); } /** jmpl rs1[imm], rd */ public int JMPL (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "111000", rs1, imm); } /** ret == jmpl %r31[8], %r0 */ public int RET () { return JMPL ("%r31", 8, "%r0"); } /** or rs1, imm, rd */ public int OR (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "000010", rs1, imm); } /** or rs1, rs2, rd */ public int OR (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "000010", rs1, rs2); } /** mov imm, rd == or %g0, imm, rd */ public int MOV (int imm, String rd) { // Do a quick catch of out-of-range values if ((4095 < imm) || (-4096 > imm)) { System.err.println ("Warning: MOV of too-large immediate: " + imm); } return OR ("%g0", imm, rd); } /** mov rs, rd == or %g0, rs, rd */ public int MOV (String rs, String rd) { return OR ("%g0", rs, rd); } /** and rs1, rs2, rd */ public int AND (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "000001", rs1, rs2); } /** andcc rs1, imm, rd */ public int ANDcc (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "010001", rs1, imm); } /** xor rs1, rs2, rd */ public int XOR (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "000011", rs1, rs2); } /** add rs1, imm, rd */ public int ADD (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "000000", rs1, imm); } /** add rs1, rs2, rd */ public int ADD (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "000000", rs1, rs2); } /** addcc rs1, rs2, rd */ public int ADDcc (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "010000", rs1, rs2); } /** addx rs1, rs2, rd */ public int ADDX (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "001000", rs1, rs2); } /** sub rs1, imm, rd */ public int SUB (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "000100", rs1, imm); } /** sub rs1, rs2, rd */ public int SUB (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "000100", rs1, rs2); } /** subcc rs1, imm, rd */ public int SUBcc (String rs1, int imm, String rd) { return Fmt3 ("10", rd, "010100", rs1, imm); } /** subcc rs1, rs2, rd */ public int SUBcc (String rs1, String rs2, String rd) { return Fmt3 ("10", rd, "010100", rs1, rs2); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -