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

📄 sparcjitcodegen.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        /* Sanity checks: frame size must be double-word aligned, and         * must fit in a signed 13-bit immediate (for the version of         * SAVE we're using) */        if (0 != (frame_size % 8)) {            throw new InternalError ("frame size not multiple of 8");        }        if (4096 <= frame_size) {            throw new InternalError ("can't handle frame sizes exceeding 2^12-1");        }                /* Create a new AR of the right size. */        code.SAVE ("%sp", -frame_size, "%sp");        /* Stuff the name of this function in the standard location. */        i = (int)getStringAddress (m.cl.name + "." + m.fl.name);        code.SETHI (i, "%o0");        code.SetLo (i, "%o0");        code.ST ("%o0", "%fp", excOheadOffs [ARLV_methname]);//        code.PUSH (excOheadAddr (ARLV_methname));//        code.reserveCode (CodeBlock.brACALL, m.instrs[0], null, getFuncAddr (FID_puts));//        code.ADD (new Immediate (2), R_esp);        /* If we're creating a standard frame for executing Java code, then         * store the arguments into the local variable arena.  If not,         * whoever's creating us should take responsibility for preserving         * arguments. */        if (0 > ndata) {            /* Figure out how many arguments we need to save.  Add one             * for the object reference of instance methods. */            aw = Instr.argwords (m.fl.signature);            if (0 == (m.fl.access & ClassData.ACC_STATIC)) {                aw++;            }            for (i = 0; i < aw; i++) {                if (6 > i) {                    /* Already in %ii. */                    code.ST ("%i" + i, "%fp", LVOffs (i));                } else {                    /* In caller's activation record.  Copy from there into                     * local variables. */                    code.LD ("%fp", SPARC.ARGPUSH + (i-6) * 4, "%o7");                    code.ST ("%o7", "%fp", LVOffs (i));                }            }            /* Initialize the register we use for the evaluation stack pointer.             * Not useful for non-standard frames. */            code.ADD ("%fp", LVOffs (m.max_locals), "%l7");        }        return;    }    /** Generate code to initialize a class if necessary, leaving the class      * reference in %o0.      * @param i the instruction that induced the initialization requirement      * @param or the reference to the object (FieldRef or ClassRef) that may need to be initialized      */    private void    emitClassInit (Instr i,                   Object or)    {        int boffs;                /* Load the address of the native struct class object that is the         * basis of the object referred to by fr.  Put it into %o0 so         * it's ready to be used as a parameter to the initializer. */        code.reserveCode (CodeBlock.brLOADNatCl, i, "%o0", or);        /* The first word of the class object is the flag indicating         * whether it needs to be initialized.  If that's zero, the class         * has been initialized, and we skip over the call to the         * initializer.*/        code.LD ("%o0", 0, "%o7");        code.CMP ("%o7", 0);        boffs = code.nextByteOffs ();        code.BE (0);        code.NOP ();        code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_initclass));        code.NOP ();        code.PatchDisp22 (boffs, (code.nextByteOffs() - boffs) >>> 2);    }    /** Pop arguments off evaluation stack and put into outgoing SPARC registers.      * @param na number of argument words to pop      * @param abase start as if from the abase'th output argument      */    private void    setCallArgs (int na,                 int abase)    {        /* Don't do anything if there are no words to pop */        if (0 >= na) {            return;        }        /* Copy the values off the evaluation stack into the proper location */        for (int a = 1; a <= na; a++) {            int ai;            /* Get which argument this is in the actual call. */            ai = abase + (a - 1);            if (6 > ai) {                /* First six values go into ALU output registers 0 through 5 */                code.peekES (na-a, "%o"+ai);            } else {                /* Remainder go into the outoing parameter dump area in this                 * function's AR */                code.peekES (na-a, "%o7");                code.ST ("%o7", "%sp", 4*(ai-6) + SPARC.ARGPUSH);            }        }        /* Update the evaluation stack pointer to pop the arguments all         * at once. */        code.tossES (na);        return;    }    /** Pull elements off stack and prepare to use them as the first args to      * a function call.       * @param na number of elements to use as arguments      */    private void    setCallArgs (int na)    {        setCallArgs (na, 0);    }    /** 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. */    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) {            /* If this is a jump backwards, get the address of the function             * we call on back edges, and call it if it exists. */            long bjfn = getFuncAddr (FID_backjumpfn);            if (0 != bjfn) {                code.reserveCode (CodeBlock.brACALL, ci, null, bjfn);            }        }        return;    }    /** Pull object off stack and make sure it's not a null pointer.      * After this, the object reference is in treg.      * @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,                    String treg,                    Instr ins)    {        /* Load the value from the execution stack */        code.peekES (i, treg);        /* Compare it to zero */        code.CMP (treg, 0);        /* If nonzero, jump over the next two instructions */        int boffs = code.nextByteOffs ();        code.BNE (0);        code.NOP ();            // fill delay slot        /* Call throwNullPointerException (0) */        code.MOV (0, "%o0");        code.reserveCode (CodeBlock.brACALL, ins, "noreg", getFuncAddr (FID_throwNPE));        code.NOP ();            // fill delay slot                // Here's where we continue        code.PatchDisp22 (boffs, (code.nextByteOffs() - boffs) >>> 2);        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 ("%l0");            code.CMP ("%l0", 0);        } else {            // Better be IFCMP            code.popES ("%l1");            code.popES ("%l0");            code.CMP ("%l0", "%l1");        }        /* 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.  That's not supported for conditional jumps, so         * for test X, we do "if !X goto afterjump; jump T; afterjump..." */        boffs = code.nextByteOffs ();        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.BNE (0);                code.NOP ();                break;            case Opcode.IF_ICMPNE:            case Opcode.IF_ACMPNE:            case Opcode.IFNE:            case Opcode.IFNONNULL:                // Inquality test: skip jump if equal                code.BE (0);                code.NOP ();                break;            case Opcode.IF_ICMPLT:            case Opcode.IFLT:                code.BGE (0);                code.NOP ();                break;            case Opcode.IF_ICMPGT:            case Opcode.IFGT:                code.BLE (0);                code.NOP ();                break;            case Opcode.IF_ICMPLE:            case Opcode.IFLE:                code.BG (0);                code.NOP ();                break;            case Opcode.IF_ICMPGE:            case Opcode.IFGE:                code.BL (0);                code.NOP ();                break;        }//        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, "noreg", m.instrs[m.pcmap [i.val]].label);        code.NOP ();    // fill delay slot        /* Continues here if OK */        code.PatchDisp22 (boffs, (code.nextByteOffs() - boffs) >>> 2);    }    /** 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;        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 -> %l0 */                code.popES ("%l0");                break;            case Opcode.FNEG:            case Opcode.F2D:            case Opcode.F2I:            case Opcode.F2L:                /* stack: op1  -> %f2 */                code.FpopES ("%f2");                break;            case Opcode.LNEG:            case Opcode.L2I:            case Opcode.L2F:            case Opcode.L2D:                /* stack: op1.w1 op1.w2  -> %l2 */                code.LpopES ("%l2");                break;            case Opcode.DNEG:            case Opcode.D2F:            case Opcode.D2I:            case Opcode.D2L:                /* stack: op1.w1 op1.w2  -> %f2 */                code.DpopES ("%f2");                break;;            default:                throw new InternalError ("Bad opcode in binop." + i);        }        /* Emit the code to operate on the results */        donestore = false;        switch (i.opcode.code) {            /* int operands: %l0  -> %l0 */            case Opcode.INEG:                code.SUB ("%g0", "%l0", "%l0");                break;            case Opcode.I2L:                code.MOV ("%l0", "%l1");                code.SRA ("%l0", 31, "%l0");                break;            case Opcode.I2F:            case Opcode.I2D:                code.ST ("%l0", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LDF ("%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE), "%f2");                if (Opcode.I2F == i.opcode.code) {                    code.FiTOs ("%f2", "%f0");                } else {                    code.FiTOd ("%f2", "%f0");                }

⌨️ 快捷键说明

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