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

📄 sparcjitcodegen.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                break;            case Opcode.INT2BYTE:                code.ST ("%l0", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LDSB ("%fp", 3 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%l0");                break;            case Opcode.INT2CHAR:                code.ST ("%l0", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LDUH ("%fp", 2 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%l0");                break;            case Opcode.INT2SHORT:                code.ST ("%l0", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LDSH ("%fp", 2 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%l0");                break;                            /* long operands: %l2 -> %l0 */            case Opcode.LNEG:                code.SUBcc ("%g0", "%l3", "%l1");                code.SUBX ("%g0", "%l2", "%l0");                break;            case Opcode.L2I:                code.MOV ("%l3", "%l0");                break;            case Opcode.L2F:            case Opcode.L2D:                code.MOV ("%l2", "%o0");                code.MOV ("%l3", "%o1");                code.reserveCode (CodeBlock.brACALL, i, "noreg",                                  getFuncAddr ((Opcode.L2F == i.opcode.code) ? FID_long2f : FID_long2d));                code.NOP ();                break;            /* Float operands: %f2 -> %f0 */            case Opcode.FNEG:                code.FNEGs ("%f2", "%f0");                break;            case Opcode.F2I:                code.FsTOi ("%f2", "%f0");                code.FpushES ("%f0");                donestore = true;                break;            case Opcode.F2L:                code.FsTOd ("%f2", "%f0");                code.STDF ("%f0", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LD ("%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o0");                code.LD ("%fp", 4 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o1");                code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_dtol));                code.NOP ();                code.LpushES ("%o0");                donestore = true;                break;            case Opcode.F2D:                code.FsTOd ("%f2", "%f0");                break;                            /* Double operands: %f2 -> %f0 */            case Opcode.DNEG:                code.FNEGs ("%f2", "%f0");                code.FMOVs ("%f3", "%f1");                break;            case Opcode.D2I:                code.FdTOi ("%f2", "%f0");                code.FpushES ("%f0");                donestore = true;                break;            case Opcode.D2F:                code.FdTOs ("%f2", "%f0");                break;            case Opcode.D2L:                code.STDF ("%f2", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LD ("%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o0");                code.LD ("%fp", 4 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o1");                code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_dtol));                code.NOP ();                code.LpushES ("%o0");                donestore = true;                break;                            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 ("%l0");            } else if (opdtype.equals ("f")) {                /* stack: %f0 -> val */                code.FpushES ("%f0");            } else if (opdtype.equals ("xl")) {                /* stack: %l0 -> val.w1 val.w2 */                code.LpushES ("%l0");            } else if (opdtype.equals ("xd")) {                /* stack: %f0 -> val.w1 val.w2 */                code.DpushES ("%f0");            } else {                throw new InternalError ("Bad type in binop.");            }        }        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  -> %l0 %l1 */            code.popES ("%l1");            code.popES ("%l0");        } else if (opdtype.equals ("f")) {            /* stack: op1 op2  -> %f2 %f3 */            code.FpopES ("%f3");            code.FpopES ("%f2");        } 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 ("%o2");                code.LpopES ("%o0");            } else {                /* stack: op1.w1 op1.w2 op2.w1 op2.w2  -> %l2 %l4 */                code.LpopES ("%l4");                code.LpopES ("%l2");            }        } else if (opdtype.equals ("xd")) {            /* stack: op1.w1 op1.w2 op2.w1 op2.w2  -> %f2 %f4 */            code.DpopES ("%f4");            code.DpopES ("%f2");        } else {            throw new InternalError ("Bad type in binop.");        }        /* Emit the code to operate on the results */        switch (i.opcode.code) {            /* int operands: %l0 op %l1 -> %l0 */            case Opcode.IADD:                code.ADD ("%l0", "%l1", "%l0");                break;            case Opcode.ISUB:                code.SUB ("%l0", "%l1", "%l0");                break;            case Opcode.IMUL:                code.SMUL ("%l0", "%l1", "%l0");                break;            case Opcode.IREM:            case Opcode.IDIV:                /* We'll have to cheat until we get a v8 sparchitecture manual */                code.MOV ("%l0", "%o0");                code.MOV ("%l1", "%o1");                code.reserveCode (CodeBlock.brACALL, i, "noreg",                                  getFuncAddr ((Opcode.IREM == i.opcode.code) ? FID_intrem : FID_intdiv));                code.NOP ();                code.MOV ("%o0", "%l0");                break;            case Opcode.IAND:                code.AND ("%l0", "%l1", "%l0");                break;            case Opcode.IOR:                code.OR ("%l0", "%l1", "%l0");                break;            case Opcode.IXOR:                code.XOR ("%l0", "%l1", "%l0");                break;            case Opcode.ISHL:                code.SLL ("%l0", "%l1", "%l0");                break;            case Opcode.ISHR:                code.SRA ("%l0", "%l1", "%l0");                break;            case Opcode.IUSHR:                code.SRL ("%l0", "%l1", "%l0");                break;                                /* long operands: %l2 op %l4 -> %l0 */            case Opcode.LADD:                code.ADDcc ("%l3", "%l5", "%l1");                code.ADDX ("%l2", "%l4", "%l0");                break;            case Opcode.LSUB:                code.SUBcc ("%l3", "%l5", "%l1");                code.SUBX ("%l2", "%l4", "%l0");                break;            case Opcode.LMUL:                /* This is the sequence that gcc -mv8 -O3 uses. */                code.UMUL ("%l3", "%l5", "%l1");                code.RDY ("%l0");                code.SMUL ("%l3", "%l4", "%o7");                code.ADD ("%l0", "%o7", "%l0");                code.SMUL ("%l5", "%l2", "%l2");                code.ADD ("%l0", "%l2", "%l0");                break;            case Opcode.LREM:            case Opcode.LDIV:                /* Everybody else does this with a function call; let's                 * do it that way too. */                code.MOV ("%l2", "%o0");                code.MOV ("%l3", "%o1");                code.MOV ("%l4", "%o2");                code.MOV ("%l5", "%o3");                code.reserveCode (CodeBlock.brACALL, i, "noreg",                                  getFuncAddr ((Opcode.LREM == i.opcode.code) ? FID_longrem : FID_longdiv));                code.NOP ();                code.MOV ("%o0", "%l0");                code.MOV ("%o1", "%l1");                break;            case Opcode.LAND:                code.AND ("%l2", "%l4", "%l0");                code.AND ("%l3", "%l5", "%l1");                break;            case Opcode.LOR:                code.OR ("%l2", "%l4", "%l0");                code.OR ("%l3", "%l5", "%l1");                break;            case Opcode.LXOR:                code.XOR ("%l2", "%l4", "%l0");                code.XOR ("%l3", "%l5", "%l1");                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.MOV (i.opcode.code, "%o3");                code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_longshift));                code.NOP ();                /* Move result back into local registers */                code.MOV ("%o0", "%l0");                code.MOV ("%o1", "%l1");                break;                /* Float operands: %f2 op %f3 -> %f0 */            case Opcode.FADD:                code.FADDs ("%f2", "%f3", "%f0");                break;            case Opcode.FSUB:                code.FSUBs ("%f2", "%f3", "%f0");                break;            case Opcode.FMUL:                code.FMULs ("%f2", "%f3", "%f0");                break;            case Opcode.FDIV:                /*!! UNFINISHED -- check for divbyzero !!*/                code.FDIVs ("%f2", "%f3", "%f0");                break;            case Opcode.FREM:                /*!! UNFINISHED -- is this correct? !!*/                /* Convert from single to double precision, and call                 * the remdr function in toba */                code.FsTOd ("%f2", "%f0");                code.FsTOd ("%f3", "%f2");                code.STDF ("%f0", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LD ("%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o0");                code.LD ("%fp", 4 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o1");                code.STDF ("%f2", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LD ("%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o2");                code.LD ("%fp", 4 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o3");                code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_remdr));                code.NOP ();                code.FdTOs ("%f0", "%f0");                break;                /* Double operands: %f2 %f4 -> %f0 */            case Opcode.DADD:                code.FADDd ("%f2", "%f4", "%f0");                break;            case Opcode.DSUB:                code.FSUBd ("%f2", "%f4", "%f0");                break;            case Opcode.DMUL:                code.FMULd ("%f2", "%f4", "%f0");                break;            case Opcode.DDIV:                /*!! UNFINISHED -- check for divbyzero !!*/                code.FDIVd ("%f2", "%f4", "%f0");                break;            case Opcode.DREM:                /* Call the remdr function in toba */                code.STDF ("%f2", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LD ("%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o0");                code.LD ("%fp", 4 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o1");                code.STDF ("%f4", "%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE));                code.LD ("%fp", - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o2");                code.LD ("%fp", 4 - (overheadSize + SPARC.ALUFPUXFERSIZE), "%o3");                code.reserveCode (CodeBlock.brACALL, i, "noreg", getFuncAddr (FID_remdr));                code.NOP ();                break;            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 ("%l0");        } else if (opdtype.equals ("f")) {            /* stack: %f0 -> val */            code.FpushES ("%f0");        } else if (opdtype.equals ("xl")) {            /* stack: %l0 -> val.w1 val.w2 */            code.LpushES ("%l0");        } else if (opdtype.equals ("xd")) {            /* stack: %f0 -> val.w1 val.w2 */            code.DpushES ("%f0");        } else {            throw new InternalError ("Bad type in binop.");        }        return;

⌨️ 快捷键说明

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