⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sparcjitcodegen.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        Opcode opc;             // Opcode for instruction        int lvi;                // Local variable index        MethodRef mr;           // MethodRef for operand        VariableRef vr;         // VariableRef for operand        FieldRef fr;            // FieldRef for operand        Constant cn;            // Constant for operand        Class c;                // Class for m        Field f;                // Field for m in c        int aw;                 // Number of argwords        long adr;               // Generic address value        String opdtype;         // Type of operand        int iv;                 // Intermediate int value        long lv;                // Intermediate long value        ClassRef cr;            // Class reference value        char tychar;            // Type character, from Field.FT_*        int boffs;              // Branch offset, for local backpatching        int boffs2;             // Another branch offset, for local backpatching        int boffs3;             // Another branch offset, for local backpatching        BackpatchInfo bpi;      // Backpatch info structure created        i = m.instrs [idx];//        System.out.println (i.toString());        /* Mark where code related to this instruction starts. */        code.instrToByteOffs [idx] = code.nextByteOffs ();        /* If we're doing exception handling, we need to update the pc         * variable so we can tell where the exception was raised. */        if (0 < m.handlers.length) {            code.SETHI (i.pc, "%o7");            code.SetLo (i.pc, "%o7");            code.ST ("%o7", "%fp", excOheadOffs [ARLV_pc]);        }        /* If instrumentation is enabled, increment the counter for this         * instruction. */        if (null != instrcounts) {            code.SETHI ((int) (icaddr + 4 * i.opcode.code), "%o7");            code.SetLo ((int) (icaddr + 4 * i.opcode.code), "%o7");            code.LD ("%o7", 0, "%l0");            code.ADD ("%l0", 1, "%l0");            code.ST ("%l0", "%o7", 0);        }        /* We can often deal with a bunch of instructions at once, so         * we switch on the opcode kind, rather than the exact opcode. */        opc = i.opcode;        switch (opc.kind) {            case Opcode.CONST: /* Tconst_#, aconst_null, bipush, sipush */                opdtype = opc.push;                if ('x' == opdtype.charAt (0)) {                    /* Two-word constant.  Either a long or a double. */                    if ('d' == opdtype.charAt (1)) {                        lv = Double.doubleToLongBits ((double)(opc.var + i.val));                    } else {                        lv = (long) (opc.var + i.val);                    }                    code.SETHI ((int) (lv >>> 32), "%o7");                    code.SetLo ((int) (lv >>> 32), "%o7");                    code.pushES ("%o7");                    code.SETHI ((int) (lv & 0xFFFFFFFF), "%o7");                    code.SetLo ((int) (lv & 0xFFFFFFFF), "%o7");                    code.pushES ("%o7");                } else {                    /* One-word constant.  Either floating point or integral */                    if ('f' == opdtype.charAt (0)) {                        iv = Float.floatToIntBits ((float)(opc.var + i.val));                    } else {                        iv = (int) (opc.var + i.val);                    }                    code.SETHI (iv, "%o7");                    code.SetLo (iv, "%o7");                    code.pushES ("%o7");                }                break;            case Opcode.LDC: /* ldc, ldc_w, ldc2_w */                cn = i.con;                /* Load the constants through immediates; at the moment,                 * every constant can be interpreted as immediates, even                 * floating point, so we don't need a data area. */                switch (cn.tag) {                    case Constant.INTEGER:                    case Constant.FLOAT:                        /* Integer values can be loaded directly. */                        if (Constant.FLOAT == cn.tag) {                            iv = Float.floatToIntBits (((Float)cn.value).floatValue());                        } else {                            iv = ((Integer)cn.value).intValue();                        }                        code.SETHI (iv, "%o7");                        code.SetLo (iv, "%o7");                        code.pushES ("%o7");                        break;                    case Constant.STRING:                        /* Strings (i.e., references to java.lang.string)                         * don't need to be stored in a data area, but we                         * do need to convert from the reference to an                         * integral value. */                        iv = (int) code.getNativeObjectAddr ((Object)cn.value);                        code.SETHI (iv, "%o7");                        code.SetLo (iv, "%o7");                        code.pushES ("%o7");                        break;                    case Constant.LONG:                    case Constant.DOUBLE:                        /* Long values can be loaded directly. */                        if (Constant.DOUBLE == cn.tag) {                            lv = Double.doubleToLongBits (((Double)cn.value).doubleValue());                        } else {                            lv = ((Long)cn.value).longValue();                        }                        code.SETHI ((int) (lv >>> 32), "%o7");                        code.SetLo ((int) (lv >>> 32), "%o7");                        code.pushES ("%o7");                        code.SETHI ((int) (lv & 0xFFFFFFFF), "%o7");                        code.SetLo ((int) (lv & 0xFFFFFFFF), "%o7");                        code.pushES ("%o7");                        break;                }                break;            case Opcode.LOAD: /* [ilfda]load{,_[0123]} */                /* It appears that Toba will guarantee that the val field                 * of the Opcode will be zero if this is a ?LOAD_x variant,                 * so we can get the local variable number by adding the                 * val and var fields. */                lvi = opc.var + i.val;                /* Pull the value out of the local variable area and push                 * it onto the eval stack.  If it's a double-word type with                 * the high word in lvi, do the high word first, then                 * the low word. */                if ('x' == opc.push.charAt (0)) {                    code.LD ("%fp", LVOffs (lvi), "%o7");                    code.pushES ("%o7");                    lvi++;                }                code.LD ("%fp", LVOffs (lvi), "%o7");                code.pushES ("%o7");                break;            case Opcode.STORE: /* [ilfda]store{,_[0123]} */                lvi = opc.var + i.val;                /* Pop the value off the stack and stuff it into the local                 * variable area */                code.popES ("%o7");                /* If this is a double word type, it lives at the local vars                 * lvi and lvi+1.  However, the high word is at lvi, and the                 * low at lvi+1, so we've got to store into lvi+1 first. */                if (2 == opc.pop) {                    code.ST ("%o7", "%fp", LVOffs (lvi+1));                    code.popES ("%o7");                }                code.ST ("%o7", "%fp", LVOffs (lvi));                break;            case Opcode.IINC:                code.LD ("%fp", LVOffs (i.val), "%o7");                code.ADD ("%o7", i.more[0], "%o7");                code.ST ("%o7", "%fp", LVOffs (i.val));                break;            case Opcode.GETS: /* getstatic */                vr = (VariableRef) i.con.value;                /*!! UNFINISHED -- check access, existence !!*/                /* Emit code to call the class initializer if necessary */                emitClassInit (i, (Object) vr);                /* Reserve space for code that will load the address of the                 * variable into %l6.  Address may not known until link time. */                code.reserveCode (CodeBlock.brLOAD, i, "%l6", vr);                /* Load the whosis from the %l6 area */                pushFromMemory ("%l6", vr.signature.charAt (0));                break;            case Opcode.PUTS: /* putstatic */                vr = (VariableRef) i.con.value;                /*!! UNFINISHED -- check access, existence, type !!*/                /* Emit code to call the class initializer if necessary */                emitClassInit (i, (Object) vr);                /* Reserve space for code that will load the address of the                 * variable into %l6.  Address may not known until link time. */                code.reserveCode (CodeBlock.brLOAD, i, "%l6", vr);                /* Store the whosis into the %l6 area */                popIntoMemory ("%l6", vr.signature.charAt (0));                break;            case Opcode.GETF: /* getfield */                vr = (VariableRef) i.con.value;                /* Verify that the instance object is not null. */                checkObjectRef (0, "%l1", i);                /* Make like we popped it instead of just peeked */                code.tossES (1);                /* %l1 is now a pointer to an instance structure.  First field                 * of the instance structure is a pointer to the C class of                 * the object.  128 bytes into that is the pointer to the                 * array of instance variable specs (struct vt_generics). *///!! REQUIRE: 124 == offsetof (struct class, ivars)//!! REQUIRE: 0 == offsetof (struct vt_generic, offset)                code.LD ("%l1", 0, "%o0");                code.LD ("%o0", 124, "%o0");                /* Now: what we're interested in is the n'th element in the                 * array of vt_generic structures which follows the class structure                 * that's pointed to by %esi.  Unfortunately, we don't know                 * what n is yet.  Load that into %o1 at link time. */                code.reserveCode (CodeBlock.brFIELDLOAD, i, "%o1", vr);                /* Now access the offset field of the n'th vt_generic in the                 * array that starts at %o0; the offset field is the first                 * field in the structure.  We add that to the address of                 * the instance variable to get the address of the field. *///!! REQUIRE: 24 == sizeof (struct vt_generic)                code.SLL ("%o1", 3, "%o1");// *8                code.ADD ("%o1", "%o1", "%o2"); // *2*8                code.ADD ("%o2", "%o1", "%o1"); // *3*8 = 24                code.LD ("%o0", "%o1", "%o2");                code.ADD ("%o2", "%l1", "%l1");                /* Push from memory */                pushFromMemory ("%l1", vr.signature.charAt (0));                                break;            case Opcode.PUTF: /* putfield */                vr = (VariableRef) i.con.value;                /* Verify that the instance object is not null.  The object                 * is n words down the stack, where n is the size of the value                 * to store. */                if ((Field.FT_long == vr.signature.charAt(0)) ||                    (Field.FT_double == vr.signature.charAt(0))) {                    checkObjectRef (2, "%l1", i);                    aw = 3;                } else {                    checkObjectRef (1, "%l1", i);                    aw = 2;                }                /* %l1 is now a pointer to an instance structure.  First field                 * of the instance structure is a pointer to the C class of                 * the object.  128 bytes into that is the pointer to the                 * array of instance variable specs (struct vt_generics). *///!! REQUIRE: 124 == offsetof (struct class, ivars)//!! REQUIRE: 0 == offsetof (struct vt_generic, offset)                code.LD ("%l1", 0, "%o0");                code.LD ("%o0", 124, "%o0");                /* Now: what we're interested in is the n'th element in the                 * array of vt_generic structures which follows the class structure                 * that's pointed to by %esi.  Unfortunately, we don't know                 * what n is yet.  Load that into %o1 at link time. */                code.reserveCode (CodeBlock.brFIELDLOAD, i, "%o1", vr);                /* Now access the offset field of the n'th vt_generic in the                 * array that starts at %o0; the offset field is the first                 * field in the structure.  We add that to the address of                 * the instance variable to get the address of the field. *///!! REQUIRE: 24 == sizeof (struct vt_generic)                code.SLL ("%o1", 3, "%o1");// *8                code.ADD ("%o1", "%o1", "%o2"); // *2*8                code.ADD ("%o2", "%o1", "%o1"); // *3*8 = 24                code.LD ("%o0", "%o1", "%o2");                code.ADD ("%o2", "%l1", "%l1");                /* Pop result into memory */                popIntoMemory ("%l1", vr.signature.charAt (0));                                /* Throw away the object ref we don't need any more */                code.tossES (1);                break;            case Opcode.NEW: /* new */                /* Backpatch load struct class reference into %o0 */                cr = (ClassRef) i.con.value;                code.reserveCode (CodeBlock.brLOADNatCl, i, "%o0", cr);                /* Now, with C class structure, call the routine that allocates                 * an instance method */                code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_new));                code.NOP ();    // fill delay slot                /* Push the instance reference onto the stack */                code.pushES ("%o0");                break;            case Opcode.ACAST: /* checkcast */                /* Look at the top element, without popping it. */                code.peekES (0, "%o0");                /* If it's null, we're OK. */                code.TST ("%o0");                boffs = code.nextByteOffs ();                code.BE (0);                code.NOP ();    // fill delay slot                /* Otherwise, see if it can be cast to the required type */                EmitCkInstance (i, (ClassRef)i.con.value);                /* If %o0 is zero, throw a ClassCastException. */                code.TST ("%o0");                boffs2 = code.nextByteOffs ();                code.BNE (0);                code.NOP ();    // fill delay slot                code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_throwCCE));                code.NOP ();    // fill delay slot                code.PatchDisp22 (boffs, (code.nextByteOffs() - boffs) >>> 2);                code.PatchDisp22 (boffs2, (code.nextByteOffs() - boffs2) >>> 2);                break;            case Opcode.INSTC: /* instanceof */                /* Pop the object off the stack; instanceof consumes the ref */                code.popES ("%o0");                /* If it's null, we're going to push 0. */                code.TST ("%o0");                boffs = code.nextByteOffs ();                code.BE (0);                code.NOP ();    // fill delay slot                /* Otherwise, see if it can be cast to the required type */                EmitCkInstance (i, (ClassRef)i.con.value);                /* Here %o0 is 0 or 1 relative to whether the cast is legal. */                code.PatchDisp22 (boffs, (code.nextByteOffs() - boffs) >>> 2);                /* Push the result. */                code.pushES ("%o0");                break;            case Opcode.NEWA: /* newarray */                /* Allocate a new array.  Element type 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -