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

📄 intel86jitcodegen.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                an += 2;            } else {                /* Copy over a single word */                code.PUSH (new MemoryRef (new Immediate (code.peekEStackOffs (an)), R_ebp));                naw--;                an++;            }        }        /* Update the estack pointer based on what we pushed */        code.tossES (an);//        System.out.println ("Set " + an + " arg words from " + sig);        /* Return the number of bytes we pushed. */        return 4*an;    }    private void    emitBackJumpCall (Instr ci)    {        long bjfn;        int boffs;        /* Get the address of the function we call on back edges.  If there         * is none, just return. */        bjfn = FA_backjumpfn;        if (0 == bjfn) {            return;        }        /* If we're running with scout thread preemption, see if the         * time slice is over. */        boffs = -1;        if (useScoutThreadPreemption) {            code.MOV (FMA_timeSliceEnd, R_eax);            code.CMP (R_eax, FMA_timeNow);            code.Jccn (Intel86.CND_b, IMM_0);            boffs = code.nextByteOffs ();        }        code.reserveCode (CodeBlock.brACALL, ci, null, bjfn);        if (0 <= boffs) {            code.PatchNearJump (boffs, code.nextByteOffs () - boffs);        }    }    /** If the source is past the destination, this is a backedge, and we      * insert a call to some routine that needs to be called regularly.      * E.g., a thread yield function on a non-preemptive thread system.      * NB: This may trash registers %eax, %ecx, and flags. */    private void    checkBackJump (Instr ci,    // Current instruction                   int src,     // Where we are now (label, addr, ??)                   int dst)     // Where we're jumping to (label, addr, ??)    {        if (src > dst) {            emitBackJumpCall (ci);        }        return;    }    /** Pull object off stack and make sure it's not a null pointer.      * After this, the object reference is in the specified register.      * @param i how far back down stack to look, zero is top elt      * @param treg what register to put object reference into      * @param npeCode indicate what NullPointerException argument to throw      */    private void    checkObjectRef (int i,                    Register treg,                    Instr ins)    {        /* Load the value from the JVM stack */        code.peekES (i, treg);        /* Compare it to zero */        code.OR (treg, treg);        /* If not zero, jump next few instructions */        code.Jccn (Intel86.CND_nz, IMM_0);        int boffs = code.nextByteOffs ();        /* Call throwNullPointerException (0) */        code.PUSH (IMM_0);        code.reserveCode (CodeBlock.brACALL, ins, null, FA_throwNPE);        /* No need to pop args; we never return here. */        code.UNIMP (0);        // sure about that?        /* Here's where we end up if we were nz */        code.PatchNearJump (boffs, code.nextByteOffs() - boffs);        return;    }    /** Emit code for an if_cmp/ifcond instruction, including the jumps.      * @param i the instruction we're executing code for.      * @param m the method i belongs to, for looking up target addresses      */    private void    EmitIfCmp (Instr i,         // Instruction to codegen               Method m)        // Method info    {        int boffs;                /* Operands are either one or two words.  Pop what's necessary,         * and set the condition codes to represent the status of the         * condition variable. */        if (Opcode.IFZRO == i.opcode.kind) {            code.popES (R_eax);            code.OR (R_eax, R_eax);        } else {            // Better be IFCMP            code.popES (R_ebx);            code.popES (R_eax);            // Subtracts source from dest            code.CMP (R_ebx, R_eax);        }        /* Because we're jumping to a JVM offset, which may be in code         * we haven't built yet, we need to generate a brJUMP-style         * backpatch.  Rather than make a backpatch type for each condition,         * we invert the test result and jump around an unconditional         * jump if the test failed. */        switch (i.opcode.code) {            case Opcode.IF_ICMPEQ:            case Opcode.IF_ACMPEQ:            case Opcode.IFNULL:            case Opcode.IFEQ:                // Equality test: skip jump if not equal                code.Jccn (Intel86.CND_ne, IMM_0);                break;            case Opcode.IF_ICMPNE:            case Opcode.IF_ACMPNE:            case Opcode.IFNE:            case Opcode.IFNONNULL:                // Inquality test: skip jump if equal                code.Jccn (Intel86.CND_e, IMM_0);                break;            case Opcode.IF_ICMPLT:            case Opcode.IFLT:                code.Jccn (Intel86.CND_ge, IMM_0);                break;            case Opcode.IF_ICMPGT:            case Opcode.IFGT:                code.Jccn (Intel86.CND_le, IMM_0);                break;            case Opcode.IF_ICMPLE:            case Opcode.IFLE:                code.Jccn (Intel86.CND_g, IMM_0);                break;            case Opcode.IF_ICMPGE:            case Opcode.IFGE:                code.Jccn (Intel86.CND_l, IMM_0);                break;        }        boffs = code.nextByteOffs ();//        System.out.println ("Jump to pc " + i.val + " is label " + m.instrs[m.pcmap [i.val]].label);        checkBackJump (i, i.pc, i.val);        code.reserveCode (CodeBlock.brJUMP, i, null, m.instrs[m.pcmap [i.val]].label);        code.PatchNearJump (boffs, (code.nextByteOffs () - boffs));        /* Continues here if OK */    }    /** Emit code for a unary operation      * @param i instruction for codegen      */    private void    EmitUnOp (Instr i)    {        String opdtype;         // Type of operands of instruction        boolean donestore;        int boffs;        int boffs2;        opdtype = i.opcode.push;        /* Load the operand into its registers.  Boy it'd be cool if the         * operand input type was available, but all we have is the         * output type, and there be cast operations here. */        switch (i.opcode.code) {            case Opcode.INEG:            case Opcode.I2L:            case Opcode.I2F:            case Opcode.I2D:            case Opcode.INT2BYTE:            case Opcode.INT2CHAR:            case Opcode.INT2SHORT:                /* stack: op1 -> %eax */                code.popES (R_eax);                break;            case Opcode.FNEG:            case Opcode.F2D:            case Opcode.F2I:            case Opcode.F2L:                /* stack: op1  -> %ST(0) */                code.FpopES ();                break;            case Opcode.LNEG:            case Opcode.L2I:            case Opcode.L2F:            case Opcode.L2D:                /* stack: op1.w1 op1.w2  -> %l2 */                code.LpopES (R_edx, R_eax);                break;            case Opcode.DNEG:            case Opcode.D2F:            case Opcode.D2I:            case Opcode.D2L:                /* stack: op1.w1 op1.w2  -> ST(0) */                code.DpopES ();                break;;            default:                throw new InternalError ("Bad opcode in unop." + i);        }        /* Emit the code to operate on the results */        donestore = false;        switch (i.opcode.code) {            /* int operands: %eax  -> %eax */            case Opcode.INEG:                code.NEG (R_eax);                break;            case Opcode.I2L:                code.CWD ();                break;            case Opcode.I2F:            case Opcode.I2D:                code.SUB (IMM_8, R_esp);                code.MOV (R_eax, MR_esp);                code.FILD (MR_esp);                code.ADD (IMM_8, R_esp);                break;            case Opcode.INT2BYTE:                code.AND (new Immediate (0xFF, 1, false), R_eax);                // Now, sign-extend back to an int                code.PrefixOPSIZE ();                code.CBW ();                code.CBW ();                break;            case Opcode.INT2CHAR:                code.AND (new Immediate (0xFFFF), R_eax);                // Don't sign extend this: char is unsigned                break;            case Opcode.INT2SHORT:                code.AND (new Immediate (0xFFFF), R_eax);                // Now, sign-extend back to an int                code.CBW ();                break;                            /* long operands: %edx:%eax -> %edx:%eax */            case Opcode.LNEG:                code.NEG (R_eax);                code.ADC (IMM_0, R_edx);                code.NEG (R_edx);                break;            case Opcode.L2I:                // Don't have to do anything                break;            case Opcode.L2F:            case Opcode.L2D:                code.PUSH (R_edx);                code.PUSH (R_eax);                code.FILD (new MemoryRef (R_esp).setRefSize (8));                code.ADD (IMM_8, R_esp);                break;            /* Float operands: %f2 -> %f0 */            case Opcode.FNEG:                code.FCHS ();                break;            case Opcode.D2I:            case Opcode.F2I:            case Opcode.D2L:            case Opcode.F2L://NaNsup                /* First, let's go hunting for special cases.  See whether//NaNsup                 * the value is NaN. *///NaNsup                code.FTST ();//NaNsup                code.FNSTSW ();//NaNsup                code.SHR (IMM_8, R_eax);//NaNsup                code.AND (new Immediate (0x45), "%al");//NaNsup                code.CMP (new Immediate (0x45), "%al");//NaNsup                code.Jccn (Intel86.CND_ne, IMM_0);//NaNsup                boffs = code.nextByteOffs ();//NaNsup                /* Is a NaN.  Result is should be zero. *///NaNsup                code.XOR (R_eax, R_eax);//NaNsup                if ((Opcode.D2L == i.opcode.code) ||//NaNsup                    (Opcode.F2L == i.opcode.code)) {//NaNsup                    code.XOR (R_edx, R_edx);//NaNsup                }//NaNsup                code.JMPn (IMM_0);//NaNsup                boffs2 = code.nextByteOffs ();//NaNsup                code.PatchNearJump (boffs, (boffs2 - boffs));                /* Yes, we really do reset the FPU control word every time                 * we do a cast.  So do gcc-generated casts to ints. */                code.SUB (new Immediate (12), R_esp);                code.FNSTCW (new MemoryRef (IMM_8, R_esp).setRefSize (2));                code.MOV (new MemoryRef (IMM_8, R_esp), R_edx);                /* Bits 12 and 11 of the 16-bit control word are the rounding                 * control field.  Normally 00 (round-to-nearest), we want                 * it to be 11 (round-to-zero).   GCC wipes out the other                 * flags in that byte, so we'll presume that's OK to do. */                /* Note that, for foo-to-int, we allocate one more word                 * of stack space than necessary; that eliminates the                 * need to duplicate this sequence. */                code.MOV (new Immediate (0x0C), R_dh);                code.MOV (R_edx, MR_esp);                code.FLDCW (new MemoryRef (R_esp).setRefSize (2));                /* This generates the wrong answer for NaN and values above                 * MAX_VALUE; for those, it stores the integer indefinite                 * value which is MIN_VALUE.  We'd have to special-case to                 * fix that. */                if ((Opcode.F2L == i.opcode.code) ||                    (Opcode.D2L == i.opcode.code)) {                    code.FISTP (new MemoryRef (R_esp).setRefSize (8));                } else {                    code.FISTP (new MemoryRef (R_esp).setRefSize (4));                }                code.FLDCW (new MemoryRef (IMM_8, R_esp).setRefSize (2));                code.POP (R_eax); // lsw                code.POP (R_edx); // msw, if long                code.POP (R_ebx); // throwaway//NaNsup                // End up here after special-case handling *///NaNsup                code.PatchNearJump (boffs2, (code.nextByteOffs () - boffs2));

⌨️ 快捷键说明

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