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

📄 intel86jitcodegen.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                break;            case Opcode.F2D:                /* NOP */                break;                            /* Double operands: %f2 -> %f0 */            case Opcode.DNEG:                code.FCHS ();                break;                /* D2I: see F2I */            case Opcode.D2F:                /* NOP */                break;                /* D2L: see F2L */                            default:                throw new InternalError ("Unop code " + i.opcode + " not supported in JIT");        }        /* Store the result back on the execution stack, unless we did it         * already (e.g., for float-to-int conversions) */        if (! donestore) {            if (opdtype.equals ("i")) {                /* stack: %l0 -> val */                code.pushES (R_eax);            } else if (opdtype.equals ("f")) {                /* stack: %f0 -> val */                code.FpushES ();            } else if (opdtype.equals ("xl")) {                /* stack: %l0 -> val.w1 val.w2 */                code.LpushES (R_edx, R_eax);            } else if (opdtype.equals ("xd")) {                /* stack: %f0 -> val.w1 val.w2 */                code.DpushES ();            } else {                throw new InternalError ("Bad type in unop.");            }        }        return;    }    /** Emit code for a binary operation      * @param i instruction for codegen      */    private void    EmitBinOp (Instr i)    {        String opdtype;         // Type of operands of instruction        opdtype = i.opcode.push;        /* Load the operands into their registers.  Fortunately, no         * binary operators are cast operators, so the output and input         * types are the same.  Um, except for long shifts. */        if (opdtype.equals ("i")) {            /* stack: op1 op2  -> %eax %ecx */            code.popES (R_ecx);            code.popES (R_eax);        } else if (opdtype.equals ("f")) {            /* stack: op1 op2  -> ST(0) ST(1) */            code.FpopES ();            code.FpopES ();        } else if (opdtype.equals ("xl")) {            if ((Opcode.LSHL == i.opcode.code) ||                (Opcode.LSHR == i.opcode.code) ||                (Opcode.LUSHR == i.opcode.code)) {                /* stack: op1.w1 op1.w2 op2 -> %o0 %o2 */                /* We're going to call a function to do these, so pop                 * right into the outgoing args. */                code.popES (R_ecx);                code.LpopES (R_edx, R_eax);            } else {                /* stack: op1.w1 op1.w2 op2.w1 op2.w2  -> %l2 %l4 */                code.LpopES (R_ebx, R_ecx);                code.LpopES (R_edx, R_eax);            }        } else if (opdtype.equals ("xd")) {            /* stack: op1.w1 op1.w2 op2.w1 op2.w2  -> ST(0) ST(1) */            code.DpopES ();            code.DpopES ();        } else {            throw new InternalError ("Bad type in binop.");        }        /* Emit the code to operate on the results */        switch (i.opcode.code) {            /* int operands: %eax op %ecx -> %eax */            case Opcode.IADD:                code.ADD (R_ecx, R_eax);                break;            case Opcode.ISUB:                code.NEG (R_ecx);                code.ADD (R_ecx, R_eax);                break;            case Opcode.IMUL:                code.IMUL (R_ecx);                break;            case Opcode.IREM:                code.CWD ();                /* DIV and REM generate the wrong answer for MIN_VALUE/-1,                 * which is unrepresentable.  In fact, on Linux, this                 * throws an FPE.  We'd have to special-case that. */                code.IDIV (R_ecx);                code.MOV (R_edx, R_eax);                break;            case Opcode.IDIV:                code.CWD ();                code.IDIV (R_ecx);                break;            case Opcode.IAND:                code.AND (R_ecx, R_eax);                break;            case Opcode.IOR:                code.OR (R_ecx, R_eax);                break;            case Opcode.IXOR:                code.XOR (R_ecx, R_eax);                break;            case Opcode.ISHL:                code.SHL (R_cl, R_eax);                break;            case Opcode.ISHR:                code.SAR (R_cl, R_eax);                break;            case Opcode.IUSHR:                code.SHR (R_cl, R_eax);                break;                            /* long operands: %edx:%eax op %ebx:%ecx -> %edx:%eax */            case Opcode.LADD:                code.ADD (R_ecx, R_eax);                code.ADC (R_ebx, R_edx);                break;            case Opcode.LSUB:                code.SUB (R_ecx, R_eax);                code.SBB (R_ebx, R_edx);                break;            case Opcode.LMUL:            case Opcode.LREM:            case Opcode.LDIV:                /* Everybody else does this with a function call; let's                 * do it that way too. */                code.PUSH (R_ebx);                 code.PUSH (R_ecx);                 code.PUSH (R_edx);                 code.PUSH (R_eax);                 code.reserveCode (CodeBlock.brACALL, i, null,                                  getFuncAddr ((Opcode.LREM == i.opcode.code) ? FID_longrem :                                               (Opcode.LDIV == i.opcode.code) ? FID_longdiv :                                               FID_longmul));                code.ADD (IMM_16, R_esp);                break;            case Opcode.LAND:                code.AND (R_ecx, R_eax);                code.AND (R_ebx, R_edx);                break;            case Opcode.LOR:                code.OR (R_ecx, R_eax);                code.OR (R_ebx, R_edx);                break;            case Opcode.LXOR:                code.XOR (R_ecx, R_eax);                code.XOR (R_ebx, R_edx);                break;            case Opcode.LSHL:            case Opcode.LSHR:            case Opcode.LUSHR:                /* Already have op1 and op2 into %o0, %o1, %o2, so put in                 * the operator type, and call the function. */                code.PUSH (new Immediate (i.opcode.code));                code.PUSH (R_ecx);                code.PUSH (R_edx);                code.PUSH (R_eax);                code.reserveCode (CodeBlock.brACALL, i, null, FA_longshift);                code.ADD (IMM_16, R_esp);                break;                /* Float operands: %f2 op %f3 -> %f0 */            case Opcode.DADD:            case Opcode.FADD:                code.FADDP (R_ST1);                break;            case Opcode.DSUB:            case Opcode.FSUB:                code.FSUBRP (R_ST1);                break;            case Opcode.DMUL:            case Opcode.FMUL:                code.FMULP (R_ST1);                break;            case Opcode.DDIV:            case Opcode.FDIV:                /*!! UNFINISHED -- check for divbyzero !!*/                code.FDIVRP (R_ST1);                break;            case Opcode.DREM:            case Opcode.FREM:                /*!! UNFINISHED -- is this correct? !!*/                /* Convert from single to double precision, and call                 * the remdr function in toba */                code.SUB (IMM_16, R_esp);                code.FSTP (new MemoryRef (R_esp).setRefSize (8));                code.FSTP (new MemoryRef (IMM_8, R_esp).setRefSize (8));                code.reserveCode (CodeBlock.brACALL, i, null, FA_remdr);                code.ADD (IMM_16, R_esp);                break;            /* Double operands: same as single prec */            default:                throw new InternalError ("Binop code " + i.opcode + " not supported in JIT");        }        /* Store the result back on the execution stack */        if (opdtype.equals ("i")) {            /* stack: %l0 -> val */            code.pushES (R_eax);        } else if (opdtype.equals ("f")) {            /* stack: %f0 -> val */            code.FpushES ();        } else if (opdtype.equals ("xl")) {            /* stack: %l0 -> val.w1 val.w2 */            code.LpushES (R_edx, R_eax);        } else if (opdtype.equals ("xd")) {            /* stack: %f0 -> val.w1 val.w2 */            code.DpushES ();        } else {            throw new InternalError ("Bad type in binop.");        }        return;    }    /** Assuming we just got back from a call to the given method, push      * the return value onto the evaluation stack.      * @param mr MethodRef of called method (FieldRef if interface method)      */    private void    EmitRetvalStore (FieldRef mr)    {        String s = mr.signature;        switch (s.charAt (s.indexOf (')') + 1)) {            case Field.FT_byte:            case Field.FT_char:            case Field.FT_int:            case Field.FT_object:            case Field.FT_short:            case Field.FT_boolean:            case Field.FT_array:                code.pushES (R_eax);                break;            case Field.FT_float:                code.FpushES ();                break;            case Field.FT_long:                code.LpushES (R_edx, R_eax);                break;            case Field.FT_double:                code.DpushES ();                break;            case Field.FT_void:                break;            default:                throw new InternalError ("WTF in " + s + " from " + mr);        }        return;    }    /** Load the pointer to the C class for type into register      * @param i instruction inducing the load      * @param cr ClassRef to type we're looking for; not necessarily resolved      * @param getArray If nonzero, want the array-of-type instead of base type      * @param reg Register pointer should go into      */    private void    loadClassPointer (Instr i,  // Instruction inducing load                      ClassRef cr, // Reference to class                      int getArray, // Get array, or base type?                      Register reg) // Name of target register    {        int cp;                 // Integer representation of pointer        int arank;                /* We have here the name of a primitive or reference type.         * We need to get the pointer to the struct class that defines         * it. */        arank = 0;        while (Field.FT_array == cr.name.charAt(arank)) {            arank++;        }        cp = 0;        switch (cr.name.charAt (arank)) {            case Field.FT_byte:                cp = (int) getNPprimclass (Opcode.T_BYTE, getArray);                break;            case Field.FT_char:                cp = (int) getNPprimclass (Opcode.T_CHAR, getArray);                break;            case Field.FT_double:                cp = (int) getNPprimclass (Opcode.T_DOUBLE, getArray);                break;            case Field.FT_float:                cp = (int) getNPprimclass (Opcode.T_FLOAT, getArray);                break;            case Field.FT_int:                cp = (int) getNPprimclass (Opcode.T_INT, getArray);                break;            case Field.FT_long:                cp = (int) getNPprimclass (Opcode.T_LONG, getArray);                break;            case Field.FT_short:                cp = (int) getNPprimclass (Opcode.T_SHORT, getArray);                break;            case Field.FT_boolean:                cp = (int) getNPprimclass (Opcode.T_BOOLEAN, getArray);                break;            default:                /* Something not a primitive class.  We should just be able                 * to load the native class.  We'd better not want an                 * array version of it, though. */                if (0 != getArray) {                    throw new InternalError ("Don't support loadClassPointer of array non-primitives");                }                code.reserveCode (CodeBlock.brLOADNatCl, i, reg, cr);                cp = 0;

⌨️ 快捷键说明

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