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

📄 jitemitter_cpu.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Emit a 32 bit value (aka .word). */voidCVMJITemitWord(CVMJITCompilationContext *con, CVMInt32 wordVal){    CVMJITcsSetEmitInPlace(con);    emitInstruction(con, wordVal);    CVMJITcsClearEmitInPlace(con);    CVMtraceJITCodegenExec({        printPC(con);        CVMconsolePrintf("	.word	%d", wordVal);    });    CVMJITdumpCodegenComments(con);}voidCVMCPUemitNop(CVMJITCompilationContext *con){    CVMJITcsSetEmitInPlace(con);    emitInstruction(con, CVMCPU_NOP_INSTRUCTION);    CVMJITcsClearEmitInPlace(con);    CVMtraceJITCodegenExec({        printPC(con);        CVMconsolePrintf("	nop");    });    CVMJITdumpCodegenComments(con);}/* * Binary ALU operation w/ 16-bit constant, always using two instructions. */static voidemitBinaryALUConstant16Conditional(CVMJITCompilationContext* con, int opcode,				   int destReg, int sourceReg,				   CVMUint32 constant,				   CVMBool setcc, CVMCPUCondCode condCode){    /* Scaled components of the 16-bit constant */    CVMUint32 constantHi = constant & 0xff00;    CVMUint32 constantLo = constant & 0x00ff;    CVMassert(constant < 0x10000); /* Better fit in 16-bits */    CVMassert(opcode == CVMCPU_BIC_OPCODE ||	      opcode == CVMCPU_OR_OPCODE ||	      opcode == CVMCPU_XOR_OPCODE ||	      opcode == CVMCPU_ADD_OPCODE ||	      opcode == CVMCPU_SUB_OPCODE);    /* Encode as two instructions */    CVMJITcsPushSourceRegister(con, sourceReg);    CVMCPUemitBinaryALUConditional(con, opcode, destReg, sourceReg,			CVMARMalurhsEncodeConstantToken(con, constantLo),			setcc, condCode);    CVMCPUemitBinaryALUConditional(con, opcode, destReg, destReg,			CVMARMalurhsEncodeConstantToken(con, constantHi),			setcc, condCode);}#ifdef CVMCPU_HAS_CP_REG/* Purpose: Set up constant pool base register */voidCVMCPUemitLoadConstantPoolBaseRegister(CVMJITCompilationContext *con){    CVMInt32 offset;    /*     * Load the constant pool base register. It can be as far     * as 64k-4 away, so it will take two adds to do this. Note     * that even if it could be done in one, we already reserved     * two instruction for it, so we might as well just use them     * both.     */    offset = con->target.cpLogicalPC - CVMJITcbufGetLogicalPC(con) - 8;    CVMJITprintCodegenComment(("setup cp base register"));    aluConstant16ScaledConditional(con, CVMCPU_ADD_OPCODE,				   CVMCPU_CP_REG, CVMARM_PC,				   offset, 0, CVMCPU_COND_AL);    /*     * Save the constant pool base register into the frame so it can     * be restored if we invoke another method.     */    CVMJITaddCodegenComment((con, "save to frame->cpBaseRegX"));    CVMassert(CVMCPUmemspecIsEncodableAsImmediate(                    CVMoffsetof(CVMCompiledFrame, cpBaseRegX)));    CVMCPUemitMemoryReferenceImmediate(        con, CVMCPU_STR32_OPCODE, CVMCPU_CP_REG, CVMCPU_JFP_REG,        CVMoffsetof(CVMCompiledFrame, cpBaseRegX));}#endif /* CVMCPU_HAS_CP_REG *//* Purpose:  Add/sub a 16-bits constant scaled by 2^scale. Called by *           method prologue and patch emission routines. * NOTE:     CVMCPUemitAddConstant16Scaled should not rely on regman *           states because the regman context used to emit the method *           prologue is gone at the patching time. * NOTE:     CVMCPUemitALUConstant16Scaled must always emit the same *           number of instructions, no matter what constant or scale *           is passed to it. */voidCVMCPUemitALUConstant16Scaled(CVMJITCompilationContext *con, int opcode,			      int destRegID, int srcRegID,			      CVMUint32 constant, int scale){    CVMUint32 value = constant << scale;    CVMassert(opcode == CVMCPU_ADD_OPCODE ||              opcode == CVMCPU_SUB_OPCODE);    if (CVMCPUalurhsIsEncodableAsImmediate(opcode, value)) {        /* Encode in one instruction */        CVMCPUemitBinaryALU(con, opcode, destRegID, srcRegID,			    CVMARMalurhsEncodeConstantToken(con, value),			    CVMJIT_NOSETCC);    } else {        /* The only time this would happen is if there are about 240+	 * words of locals, so it's ok to just not compile this method.         */	CVMJITerror(con, CANNOT_COMPILE, "too many locals");    }}/* * Purpose: Stack limit check at the start of each method, corresponding to: * *     ldr      a4, [sp, #OFFSET_CVMCCExecEnv_stackChunkEnd]; *     str      lr, [JFP, #OFFSET_CVMCCExecEnv_pcX]; *     cmp      a4, a2; *     bls      letInterpreterDoInvoke; * * Schedule the lr flush to give 'a4' time to "settle". */voidCVMCPUemitStackLimitCheckAndStoreReturnAddr(CVMJITCompilationContext* con){    CVMJITaddCodegenComment((con, "Store LR into frame"));    CVMassert(CVMCPUmemspecIsEncodableAsImmediate(                    CVMoffsetof(CVMCompiledFrame, pcX)));    CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_STR32_OPCODE, CVMARM_LR,        CVMCPU_JFP_REG, CVMoffsetof(CVMCompiledFrame, pcX));    CVMCPUemitCompareRegister(con, CVMCPU_CMP_OPCODE, CVMCPU_COND_LS,                              CVMCPU_ARG4_REG, CVMCPU_ARG2_REG);    CVMJITaddCodegenComment((con, "letInterpreterDoInvoke"));#ifdef CVM_JIT_COPY_CCMCODE_TO_CODECACHE    CVMCPUemitBranch(con,        CVMCCMcodeCacheCopyHelperOffset(con,            CVMCCMletInterpreterDoInvokeWithoutFlushRetAddr),        CVMCPU_COND_LS);#else    /*     * This accesses the CP, and such is incompatible with CP_REG code     * (can't access constant pool in prologue)     */#ifdef CVMCPU_HAS_CP_REG#error "Cannot support 'bls letInterpreterDoInvoke' when glue not in code cache and doing CP register setups"#else    /* load the new pc from memory */    CVMCPUemitLoadConstantConditional(con, CVMARM_PC,        (CVMInt32)CVMCCMletInterpreterDoInvokeWithoutFlushRetAddr,        CVMCPU_COND_LS);#endif#endif}/* *  Purpose: Emits code to invoke method through MB. *           MB is already in CVMCPU_ARG1_REG. */voidCVMCPUemitInvokeMethod(CVMJITCompilationContext* con){    CVMUint32 off;    /* MOV LR, PC */    CVMJITaddCodegenComment((con, "setup return address"));    CVMJITcsSetEmitInPlace(con);    CVMCPUemitMoveRegister(con, CVMCPU_MOV_OPCODE,			   CVMARM_LR, CVMARM_PC, CVMJIT_NOSETCC);    /* LDR PC, [MB + #OFFSET_JITInvoker]     */    CVMJITaddCodegenComment((con, "call method through mb"));    off = CVMoffsetof(CVMMethodBlock, jitInvokerX);    CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_LDR32_OPCODE, CVMARM_PC,                                       CVMCPU_ARG1_REG, off);    CVMJITcsClearEmitInPlace(con);    CVMJITcsBeginBlock(con);}/* * Move the JSR return address into regno. This is a no-op on * cpu's where the CVMCPU_JSR_RETURN_ADDRESS_SET == LR. */voidCVMCPUemitLoadReturnAddress(CVMJITCompilationContext* con, int regno){    CVMassert(regno == CVMARM_LR);}/* * Branch to the address in the specified register. */voidCVMCPUemitRegisterBranch(CVMJITCompilationContext* con, int regno){    CVMJITcsSetEmitInPlace(con);    CVMCPUemitMoveRegister(con, CVMCPU_MOV_OPCODE,			   CVMARM_PC, regno, CVMJIT_NOSETCC);    CVMJITcsClearEmitInPlace(con);}/* * Do a branch for a tableswitch. We need to branch into the dispatch * table. The table entry for index 0 will be generated right after * any instructions that are generated here.. */voidCVMCPUemitTableSwitchBranch(CVMJITCompilationContext* con, int indexRegNo){    /*     * Since on arm the pc is already offset by 8, we just need to add     * key*4 to pc and then pad with a nop so things line up right.     */    CVMCPUALURhsToken token;    token = CVMARMalurhsEncodeShiftByConstantToken(con,	indexRegNo, CVMCPU_SLL_OPCODE, 2);    CVMJITcsSetEmitInPlace(con);    CVMCPUemitBinaryALU(con, CVMCPU_ADD_OPCODE,			CVMARM_PC, CVMARM_PC, token, CVMJIT_NOSETCC);    CVMJITcsClearEmitInPlace(con);    CVMCPUemitNop(con);}voidCVMCPUemitPopFrame(CVMJITCompilationContext* con, int resultSize){    CVMUint32 offset; /* offset from JFP for new JSP */    CVMUint32 rotate;    CVMUint32 base;    /* We want to set JSP to the address of the locals + the resultSize */    offset = (con->numberLocalWords - resultSize) * sizeof(CVMJavaVal32);    if (CVMARMmode1EncodeImmediate(offset, &base, &rotate)) {        CVMJITcsSetDestRegister(con, CVMCPU_JSP_REG);        CVMJITcsPushSourceRegister(con, CVMCPU_JFP_REG);        /* If it's encodable, we quickly emit the instruction: */        emitInstruction(con, ARM_MAKE_CONDCODE_BITS(CVMCPU_COND_AL) |            (CVMUint32)CVMCPU_SUB_OPCODE |	    CVMCPU_JFP_REG << 16 | CVMCPU_JSP_REG << 12 |            CVMARM_MODE1_CONSTANT | rotate << 8 | base);        CVMtraceJITCodegenExec({            printPC(con);            CVMconsolePrintf("	sub	JSP, JFP, #%d", offset);        });        CVMJITdumpCodegenComments(con);    } else {        /* Else, we make use of all the other emitter functions that are           already available for emitting and tracking the pieces we need: */        CVMRMResource *offsetRes;        CVMUint32 offsetReg;        /* Load the offset as a constant into a register: */        offsetRes = CVMRMgetResource(CVMRM_INT_REGS(con),				     CVMRM_ANY_SET, CVMRM_EMPTY_SET, 1);        offsetReg = CVMRMgetRegisterNumber(offsetRes);        CVMCPUemitLoadConstant(con, offsetReg, offset);        /* Pop the frame: */        CVMCPUemitBinaryALURegister(con, CVMCPU_SUB_OPCODE,				    CVMCPU_JSP_REG, CVMCPU_JFP_REG, offsetReg,				    CVMJIT_NOSETCC);        CVMRMunpinResource(CVMRM_INT_REGS(con), offsetRes);    }}#ifdef CVM_JIT_PATCHED_METHOD_INVOCATIONS/* * Patch branch instruction at location "instrAddr" to branch to offset * "offset" from "instrAddr". */voidCVMCPUpatchBranchInstruction(int offset, CVMUint8* instrAddr){    CVMCPUInstruction branch;    /* There better already be an unconditional bl at this address */    CVMassert((*(CVMUint32*)instrAddr & 0xff000000) ==	      (ARM_BL_OPCODE | ARM_MAKE_CONDCODE_BITS(CVMCPU_COND_AL)));    branch = CVMARMgetBranchInstruction(CVMCPU_COND_AL, offset, CVM_TRUE);    *((CVMCPUInstruction*)instrAddr) = branch;}#endif/* * Make a PC-relative branch or branch-and-link instruction */CVMCPUInstructionCVMARMgetBranchInstruction(CVMCPUCondCode condCode, int offset, CVMBool link){    CVMUint32 opcode = (link ? ARM_BL_OPCODE : ARM_B_OPCODE);    int realoffset = (offset - 8) >> 2; /* adjust by 8 on ARM */    CVMassert((realoffset & 0xff800000) == 0 ||	      (realoffset & 0xff800000) == 0xff800000);    return (ARM_MAKE_CONDCODE_BITS(condCode) | opcode	    | ((CVMUint32)realoffset & 0x00ffffff));}/* Purpose: Emits a branch or branch and link instruction. */voidCVMARMemitBranch(CVMJITCompilationContext* con,	         int logicalPC, CVMCPUCondCode condCode,                 CVMBool link, CVMJITFixupElement** fixupList){    CVMUint32 branchInstruction;    CVMJITcsSetStatusInstruction(con, condCode);    CVMJITcsSetBranchInstruction(con);#ifdef IAI_CS_EXCEPTION_ENHANCEMENT2    CVMJITcsSetEmitInPlaceWithBufSizeAdjust(con, \        CVMJITcsIsArrayIndexOutofBoundsBranch(con), sizeof(CVMCPUInstruction));#else    CVMJITcsSetEmitInPlace(con);#endif    if (fixupList != NULL) {        CVMJITfixupAddElement(con, fixupList,                              CVMJITcbufGetLogicalPC(con));    }    branchInstruction =        CVMARMgetBranchInstruction(condCode,				   logicalPC - CVMJITcbufGetLogicalPC(con),				   link);    emitInstruction(con, branchInstruction);    CVMJITstatsRecordInc(con, CVMJIT_STATS_BRANCHES);    CVMtraceJITCodegenExec({        printPC(con);        CVMconsolePrintf("	%s%s	PC=(%d)",                         link ? "bl" : "b",                         conditions[condCode], logicalPC);    });    CVMJITcsClearEmitInPlace(con);    CVMJITdumpCodegenComments(con);}/* Purpose: Emits instructions to do the specified conditional 32 bit unary            ALU operation. */voidCVMCPUemitUnaryALUConditional(CVMJITCompilationContext *con, int opcode,			      int destRegID, int srcRegID,			      CVMBool setcc, CVMCPUCondCode condCode){    switch (opcode) {        case CVMCPU_NOT_OPCODE:            /* reg32 = (reg32 == 0)?1:0. */            CVMassert(condCode = CVMCPU_COND_AL);            CVMCPUemitCompareConstant(con, CVMCPU_CMP_OPCODE, CVMCPU_COND_AL,                                      srcRegID, 0);            CVMCPUemitLoadConstantConditional(con, destRegID, 0, CVMCPU_COND_NE);            CVMCPUemitLoadConstantConditional(con, destRegID, 1, CVMCPU_COND_EQ);            break;        case CVMCPU_INT2BIT_OPCODE:            /* reg32 = (reg32 != 0)?1:0. */            CVMassert(condCode = CVMCPU_COND_AL);

⌨️ 快捷键说明

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