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

📄 jitemitter_cpu.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 5 页
字号:
                    (CVMUint32)opcode | lhsRegID << 16 | rhsToken);    CVMtraceJITCodegenExec({        char mode1buf[48];        formatMode1(mode1buf, rhsToken);        printPC(con);        CVMconsolePrintf("	%s%s	%s, %s", getOpcodeName(opcode),            conditions[condCode], regNames[lhsRegID], mode1buf);    });    CVMJITdumpCodegenComments(con);}extern voidCVMCPUemitCompare(CVMJITCompilationContext* con,		  int opcode, CVMCPUCondCode condCode,		  int lhsRegID, CVMCPUALURhsToken rhsToken){    CVMARMemitCompareConditional(con, opcode, lhsRegID, rhsToken,				 CVMCPU_COND_AL);}extern voidCVMCPUemitCompareConstant(CVMJITCompilationContext* con,			  int opcode, CVMCPUCondCode condCode,			  int lhsRegID, CVMInt32 rhsConstValue){    CVMCPUALURhsToken rhsToken;    CVMRMResource* rhsRes;    /* rhsConstValue may not be encodable as an immediate value */    if (CVMCPUalurhsIsEncodableAsImmediate(opcode, rhsConstValue)) {        rhsRes = NULL;        rhsToken = CVMARMalurhsEncodeConstantToken(con, rhsConstValue);    } else {        rhsRes = CVMRMgetResourceForConstant32(CVMRM_INT_REGS(con),			CVMRM_ANY_SET, CVMRM_EMPTY_SET, rhsConstValue);        rhsToken =  CVMARMalurhsEncodeRegisterToken(con,		        CVMRMgetRegisterNumber(rhsRes));    }    CVMARMemitCompareConditional(con, opcode, lhsRegID, rhsToken,				 CVMCPU_COND_AL);    if (rhsRes != NULL) {        CVMRMrelinquishResource(CVMRM_INT_REGS(con), rhsRes);    }}/* * Putting a big, non-immediate value into a register * using the constant pool. */voidCVMCPUemitLoadConstant(    CVMJITCompilationContext* con,    int regno,    CVMInt32 v){    CVMCPUemitLoadConstantConditional(con, regno, v, CVMCPU_COND_AL);}voidCVMCPUemitLoadConstantConditional(    CVMJITCompilationContext* con,    int regno,    CVMInt32 v,    CVMCPUCondCode condCode){    CVMUint32 base;    CVMUint32 rotate;#ifdef CVM_JIT_USE_FP_HARDWARE    CVMRMResource *res = CVMRMfindResourceConstant32InRegister(CVMRM_FP_REGS(con), v);    if (res != NULL) {        CVMARMemitMoveFloatFP(con, CVMARM_MOVAF_OPCODE,            CVMRMgetRegisterNumberUnpinned(res),            regno);    } else#endif    /* Check to see if we can do this as a positive constant: */    if (CVMARMmode1EncodeImmediate(v, &base, &rotate)) {        CVMCPUemitMoveConditional(con, CVMCPU_MOV_OPCODE, regno,            CVMARMalurhsEncodeLargeConstantToken(base, rotate),            CVMJIT_NOSETCC, condCode);    /* Check to see if we can do this as a negative constant: */    } else if (CVMARMmode1EncodeImmediate(~v, &base, &rotate)) {        CVMCPUemitMoveConditional(con, ARM_MVN_OPCODE, regno,            CVMARMalurhsEncodeLargeConstantToken(base, rotate),            CVMJIT_NOSETCC, condCode);    /* Do a big constant stored at a PC relative location: */    } else {        CVMInt32 logicalPC = CVMJITcbufGetLogicalPC(con);        CVMInt32 targetLiteralOffset = 0;        CVMInt32 relativeOffset = 0;        int baseReg;	/*	 * Normally we call CVMJITgetRuntimeConstantReference32 first and	 * then emit the instruction to load the constant afterwards.	 * When code scheduling is enabled, the instruction to load the	 * constant might be emitted somewhere other than the current	 * logicalPC, so when code scheduling is enabled we need to wait	 * until after the load instruction is emitted before calling	 * CVMJITgetRuntimeConstantReference32.	 */#ifndef IAI_CODE_SCHEDULER_SCORE_BOARD        targetLiteralOffset =	    CVMJITgetRuntimeConstantReference32(con, logicalPC, v);#endif /* IAI_CODE_SCHEDULER_SCORE_BOARD */#ifdef CVMCPU_HAS_CP_REG	baseReg = CVMCPU_CP_REG;	/* offset of 0 will be patched after the constant pool is dumped */	relativeOffset = 0;#else	baseReg = CVMARM_PC;        logicalPC += 8; /* +8 ARM PC bias */        relativeOffset = (targetLiteralOffset != 0) ?                         targetLiteralOffset - logicalPC : 0;#endif	/* Emit the load relative to the constant pool base register. */        CVMCPUemitMemoryReferenceConditional(con, CVMCPU_LDR32_OPCODE, regno,            baseReg, CVMCPUmemspecEncodeImmediateToken(con, relativeOffset),            condCode);#ifdef IAI_CODE_SCHEDULER_SCORE_BOARD	/*	 * Find out where the load instruction was emitted and pass this to	 * CVMJITgetRuntimeConstantReference32. If the constant was	 * already emitted, then we need to patch up the load	 * instruction now.	 */        logicalPC = CVMJITcbufGetLogicalInstructionPC(con);        targetLiteralOffset =	    CVMJITgetRuntimeConstantReference32(con, logicalPC, v);        targetLiteralOffset = (targetLiteralOffset != 0) ?	    targetLiteralOffset : logicalPC;	/* Emit the load relative to the constant pool base register. */        CVMJITfixupAddress(con, logicalPC, targetLiteralOffset,			   CVMJIT_MEMSPEC_ADDRESS_MODE);#endif /* IAI_CODE_SCHEDULER_SCORE_BOARD */    }    CVMJITresetSymbolName(con);}static int absolute(int v){    return (v<0)?-v:v;}#ifdef CVM_JIT_USE_FP_HARDWARE/* This function can dump constant pool and so to update logical address  in the context */static CVMInt32CVMARMgetRuntimeConstantReferenceFP(    CVMJITCompilationContext* con,    CVMInt32 v){    if (con->constantPoolSize >= CVMARM_FP_MAX_LOADSTORE_OFFSET) {    	CVMRISCemitConstantPoolDumpWithBranchAround(con);    }    return CVMJITgetRuntimeFPConstantReference32(con,        CVMJITcbufGetLogicalPC(con), v);}voidCVMCPUemitLoadConstantConditionalFP(    CVMJITCompilationContext* con,    int regno,    CVMInt32 v,    CVMCPUCondCode condCode){    CVMInt32 targetLiteralOffset;    CVMInt32 logicalPC;    int baseReg;    CVMInt32 relativeOffset;    CVMRMResource *res =        CVMRMfindResourceConstant32InRegister(CVMRM_FP_REGS(con), v);    if (res != NULL) {	if (regno != CVMRMgetRegisterNumberUnpinned(res)) {            CVMCPUemitMoveConditional(con, CVMCPU_FMOV_OPCODE, regno,                CVMRMgetRegisterNumberUnpinned(res), CVMJIT_NOSETCC, condCode);	}        CVMJITresetSymbolName(con);	return;    }    res = CVMRMfindResourceConstant32InRegister(CVMRM_INT_REGS(con), v);    if (res != NULL) {        CVMARMemitMoveFloatFP(con, CVMARM_MOVFA_OPCODE, regno,            CVMRMgetRegisterNumberUnpinned(res));        CVMJITresetSymbolName(con);	return;    }    if (v == 0) {	res = CVMRMfindResourceForNonNaNConstant(CVMRM_FP_REGS(con));	if (res != NULL) {	    CVMCPUemitBinaryFP(con, CVMCPU_FSUB_OPCODE, regno,                CVMRMgetRegisterNumberUnpinned(res),                CVMRMgetRegisterNumberUnpinned(res));            CVMJITresetSymbolName(con);	    return;	}	res = CVMRMfindResourceForNonNaNConstant(CVMRM_INT_REGS(con));	if (res != NULL) {            CVMARMemitMoveFloatFP(con, CVMARM_MOVFA_OPCODE, regno,                CVMRMgetRegisterNumberUnpinned(res));            CVMCPUemitBinaryFP(con, CVMCPU_FSUB_OPCODE, regno, regno, regno);            CVMJITresetSymbolName(con);	    return;	}        {            /* Load 0 into ARM register */            CVMRMResource *tempReg = CVMRMgetResource(CVMRM_INT_REGS(con),                                       CVMRM_ANY_SET, CVMRM_EMPTY_SET, 1);            CVMInt32 tempRegID = CVMRMgetRegisterNumber(tempReg);            CVMCPUemitLoadConstant(con, tempRegID, 0);            CVMARMemitMoveFloatFP(con, CVMARM_MOVFA_OPCODE, regno, tempRegID);            CVMRMrelinquishResource(CVMRM_INT_REGS(con), tempReg);            CVMJITresetSymbolName(con);            return;        }    }    targetLiteralOffset =        CVMARMgetRuntimeConstantReferenceFP(con, v);    logicalPC = CVMJITcbufGetLogicalPC(con);#ifdef CVMCPU_HAS_CP_REG    baseReg = CVMCPU_CP_REG;    /* offset of 0 will be patched after the constant pool is dumped */    relativeOffset = 0;#else    baseReg = CVMARM_PC;    relativeOffset =        (targetLiteralOffset != 0) ? targetLiteralOffset - logicalPC - 8                                   : 0;#endif    /* Emit the load relative to the constant pool base register. */    CVMCPUemitMemoryReferenceConditional(con, CVMCPU_FLDR32_OPCODE, regno,	baseReg, CVMCPUmemspecEncodeImmediateToken(con, relativeOffset),	condCode);    CVMJITresetSymbolName(con);}#endif/* * This is for emitting the sequence necessary for doing a call to an * absolute target. The target can either be in the code cache * or to a vm function. For the former, it will choose the quicker bl * instruction. For the later, it will use the 2 instruction <mov, ldr> * pair to setup the lr and load the target address into the pc, plus * generate a constant for the target address. * * condCode is the condition that must be met to do the call. * * The constant pool will be dumped if necessary and if allowed. * If okToBranchAroundCpDump is FALSE and the lr can't be setup * use mode1 math to skip over the constant pool, then it will not * be dumped. * * WARNING: pass FALSE for okToBranchAroundCpDump if you are going * to capture a stackmap right after calling CVMCPUemitAbsoluteCall(). * Otherwise the pc flushed to the frame will not be the pc where the * stackmap was captured. */static voidemitReturnAddressComputation(CVMJITCompilationContext* con,			     CVMCPUCondCode condCode, int skip){    CVMassert(skip >= 0);    CVMJITcsSetEmitInPlace(con);    CVMJITcsSetDestRegister(con, CVMARM_LR);    CVMJITcsPushSourceRegister(con, CVMARM_PC);    if (skip == 0) {	emitInstruction(con, ARM_MAKE_CONDCODE_BITS(condCode) |            (CVMUint32)CVMCPU_MOV_OPCODE | CVMARM_LR << 12 | CVMARM_PC);    } else {        CVMUint32 base, rotate;        CVMBool success;	CVMassert(skip > 0);        /* Make sure skip is reachable via mode1 addressing: */        success = CVMARMmode1EncodeImmediate(skip, &base, &rotate);        CVMassert(success);	emitInstruction(con, ARM_MAKE_CONDCODE_BITS(condCode) |                    (CVMUint32)CVMCPU_ADD_OPCODE | CVMARM_PC << 16 |                    CVMARM_LR << 12 | CVMARM_MODE1_CONSTANT |                    rotate << 8 | base);    }    CVMtraceJITCodegenExec({        printPC(con);        if (skip == 0){            CVMJITaddCodegenComment((con, "lr = pc"));            CVMconsolePrintf("	mov%s	%s, %s", conditions[condCode],                             regNames[CVMARM_LR], regNames[CVMARM_PC]);        } else {            CVMJITaddCodegenComment((con, "lr = pc + offset"));            CVMconsolePrintf("	add%s	%s, %s, %d",                             conditions[condCode],                             regNames[CVMARM_LR], regNames[CVMARM_PC], skip);        }    });    CVMJITcsClearEmitInPlace(con);    CVMJITdumpCodegenComments(con);}voidCVMCPUemitFlushJavaStackFrameAndAbsoluteCall(CVMJITCompilationContext* con,                                             const void* target,                                             CVMBool okToDumpCp,                                             CVMBool okToBranchAroundCpDump){    CVMCodegenComment *comment;    CVMJITpopCodegenComment(con, comment);    /* Store the JSP into the compiled frame: */    CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_STR32_OPCODE,        CVMCPU_JSP_REG, CVMCPU_JFP_REG, offsetof(CVMFrame, topOfStack));    CVMJITpushCodegenComment(con, comment);    CVMARMemitAbsoluteCallConditional(con, target, okToDumpCp,                                      okToBranchAroundCpDump, CVMCPU_COND_AL,                                      CVM_TRUE);    CVMJITcsBeginBlock(con);}voidCVMARMemitAbsoluteCallConditional(CVMJITCompilationContext* con,                       const void* target,		       CVMBool okToDumpCp,		       CVMBool okToBranchAroundCpDump,		       CVMCPUCondCode condCode,                       CVMBool flushReturnPCToFrame){    CVMCodegenComment *comment;    CVMBool doCpDump = okToDumpCp && CVMJITcpoolNeedDump(con);    int cpSkip = 0;    CVMBool cpSkipIsMode1 = CVM_FALSE;    int minSkip = 0;    if (flushReturnPCToFrame) {        minSkip = 4;    }    /*     * Find out if we can use a mode1 instruction to adjust the lr to     * skip over the constant pool.     */    if (doCpDump) {        cpSkip = (con->numEntriesToEmit * 4) + minSkip;        if (condCode != CVMCPU_COND_AL) {	    cpSkip += 4; /* need to skip around absolute branch */	}	cpSkipIsMode1 = CVMARMmode1EncodeImmediate(cpSkip, NULL, NULL);	/*	 * If the call is conditional or the skip value is not mode1, then	 * we will have to branch around the the constant pool. If the	 * branch is not allowed, then we can't dump.	 */        if (condCode != CVMCPU_COND_AL || !cpSkipIsMode1) {	    doCpDump = okToBranchAroundCpDump;	    if (!doCpDump) {                cpSkip = minSkip;	    }	}    } else {        cpSkip = minSkip;    }    /*        The emitted code should look like one of the following cases:        CASE 1: No constants to dump.                add lr, pc, #4                str lr, [JFP, #offsetof(CVMCompiledFrame, pcX)]                ldr pc, #target  @ target not in code cache            return_ad

⌨️ 快捷键说明

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