📄 jitgrammardefs.jcs
字号:
#define BINARY_UNARY_reg_BINARY_reg_reg_SYNTHESIS(con, thisNode_) { \ CVMJITIRNode *thisNode = (thisNode_); \ CVMJITIRNode *lhs = \ CVMJITirnodeGetLeftSubtree(CVMJITirnodeGetLeftSubtree(thisNode)); \ CVMJITIRNode *rhs = CVMJITirnodeGetRightSubtree(thisNode); \ DEFAULT_SYNTHESIS1((con), lhs); \ DEFAULT_SYNTHESIS2((con), rhs); \ thisNode->regsRequired = lhs->regsRequired | rhs->regsRequired; \}#define BINARY_UNARY_reg_BINARY_reg_reg_INHERITANCE DEFAULT_INHERITANCE3/* * TARGETING: Macros for specifying preferred target registers for an IR node. *//* NOTE: _SET_TARGET() is private and only to be called by other macros. */#define _SET_TARGET(n, regset) { \ SET_ATTRIBUTE_TYPE(n, CVMJIT_EXPRESSION_ATTRIBUTE_TARGET_AVOID); \ goal_top->attributes[n].u.rs.target = regset; \}#define SET_TARGET1(thisNode, regset) { \ DEFAULT_INHERITANCE1(con, (thisNode)); \ _SET_TARGET(0, (regset)); \}#define SET_TARGET2(thisNode, regset1, regset2) { \ DEFAULT_INHERITANCE2(con, (thisNode)); \ _SET_TARGET(0, (regset1)); \ _SET_TARGET(1, (regset2)); \}/* Set the register targetting information without doing any inheritance work. */#define SET_TARGET3_WO_INHERITANCE(thisNode, regset1, regset2, regset3) { \ _SET_TARGET(0, (regset1)); \ _SET_TARGET(1, (regset2)); \ _SET_TARGET(2, (regset3)); \}#define SET_TARGET2_0(thisNode, regset1) { \ DEFAULT_INHERITANCE2(con, (thisNode)); \ _SET_TARGET(0, (regset1)); \}#define SET_TARGET2_1(thisNode, regset2) { \ DEFAULT_INHERITANCE2(con, (thisNode)); \ _SET_TARGET(1, (regset2)); \}/* * AVOIDING: Macros for specifying registers that the IR node prefers to avoid * when doing register targeting. * * Targeting above is handled with full register sets. Avoiding below * is handled using predefined register sets. This allows us to encode * the avoid sets using just a few bits rather than 32-bits for GPRs * plus 32-bits for FPRs. This is significant because the avoid set has * to be stored in the regsRequired field if the IR node, so storing * in just a few bits saves us two words in each node. */#define CVMCPU_NUM_AVOID_SETS 4const CVMRMregset CVMCPUavoidSets[CVMCPU_NUM_AVOID_SETS] = { CVMRM_EMPTY_SET, /* nothing to avoid */ ~CVMRM_SAFE_SET, /* AVOID_C_CALL */ CVMRM_ANY_SET, /* AVOID_METHOD_CALL */ CVMRM_ANY_SET /* AVOID_C_CALL and AVOID_METHOD_CALL */};#define CVMCPUconvertAvoidBitsToAvoidSet(avoidBits) \ (CVMassert((CVMUint32)avoidBits < CVMCPU_NUM_AVOID_SETS), \ CVMCPUavoidSets[avoidBits])#ifdef CVM_JIT_USE_FP_HARDWAREconst CVMRMregset CVMCPUfloatAvoidSets[CVMCPU_NUM_AVOID_SETS] = { CVMRM_EMPTY_SET, /* nothing to avoid */ ~CVMRM_FP_SAFE_SET, /* AVOID_C_CALL */ CVMRM_FP_ANY_SET, /* AVOID_METHOD_CALL */ CVMRM_FP_ANY_SET /* AVOID_C_CALL and AVOID_METHOD_CALL */};#define CVMCPUconvertAvoidBitsToFloatAvoidSet(avoidBits) \ (CVMassert((CVMUint32)avoidBits < CVMCPU_NUM_AVOID_SETS), \ CVMCPUfloatAvoidSets[avoidBits])#endif /* CVM_JIT_USE_FP_HARDWARE */#define SET_AVOID(n, regset) \ ((n)->regsRequired = (regset))#define SET_AVOID_C_CALL(n) \ SET_AVOID((n), CVMCPU_AVOID_C_CALL)#define SET_AVOID_METHOD_CALL(n) \ SET_AVOID((n), CVMCPU_AVOID_METHOD_CALL)#define SET_CALL_CONTEXT(n, callContext_) \ SET_ATTRIBUTE_TYPE(n, CVMJIT_EXPRESSION_ATTRIBUTE_CALL_CONTEXT), \ goal_top->attributes[n].u.callContext = (callContext_)#define GET_CALL_CONTEXT(con) \ (CVMassert(((goal_top-1)->curr_attribute)->type == \ CVMJIT_EXPRESSION_ATTRIBUTE_CALL_CONTEXT), \ (CVMCPUCallContext *)(((goal_top-1)->curr_attribute)->u.callContext))#define SET_TARGET_IARG(con, node) \ iargTarget((con), (node), goal_top, subgoals_todo)#define END_TARGET_IARG(con, node) \ iargTarget((con), (node), goal_top, subgoals_todo)#define SET_AVOID_INTRINSIC_CALL(con, node) \ SET_AVOID((node), intrinsicRequired((con), (node), submatch_roots))#define SET_TARGET_INTRINSIC_CALL(con, node) \ DEFAULT_INHERITANCE2((con), (node))#ifdef CVMJIT_INTRINSICS#ifdef CVMJIT_INTRINSICS_HAVE_PLATFORM_SPECIFIC_REG_ARGS#define GET_REG_ARGS(properties) \ (((properties) & CVMJITINTRINSIC_REG_ARGS) != 0)#else#define GET_REG_ARGS(properties) CVM_FALSE#endifstatic CVMJITRegsRequiredTypeintrinsicRequired(CVMJITCompilationContext *con, CVMJITIRNode *intrinsicNode, CVMJITIRNodePtr *submatch_roots){ CVMJITRegsRequiredType required; CVMUint16 intrinsicID = CVMJITirnodeGetBinaryOp(intrinsicNode)->data; CVMJITIntrinsic *irec = &CVMglobals.jit.intrinsics[intrinsicID - 1]; const CVMJITIntrinsicConfig *config = irec->config; CVMUint16 properties = config->properties; required = submatch_roots[0]->regsRequired | submatch_roots[1]->regsRequired; if ((properties & CVMJITINTRINSIC_OPERATOR_ARGS) != 0) { const CVMJITIntrinsicEmitterVtbl *emitter; emitter = (const CVMJITIntrinsicEmitterVtbl *) config->emitterOrCCMRuntimeHelper; required = emitter->getRequired(con, intrinsicNode, required); } else { /* Just like a C call, we avoid the safe set because we'll be effectively making a C call to the helper: */ CVMBool useRegArgs = GET_REG_ARGS(properties); required = CVMCPUCCALLgetRequired(con, required, intrinsicNode, irec, useRegArgs); } return required;}static voidiargTarget(CVMJITCompilationContext *con, CVMJITIRNode *iargNode, struct CVMJITCompileExpression_rule_computation_state *goal_top, int subgoals_todo){ CVMUint16 intrinsicID; CVMJITIntrinsic *irec; const CVMJITIntrinsicConfig *config; CVMUint16 properties; if (iargNode->tag != CVMJIT_ENCODE_NULL_IARG) { intrinsicID = CVMJIT_IARG_INTRINSIC_ID(iargNode); } else { intrinsicID = CVMJIT_NULL_IARG_INTRINSIC_ID(iargNode); } irec = &CVMglobals.jit.intrinsics[intrinsicID - 1]; config = irec->config; properties = config->properties; if (iargNode->tag != CVMJIT_ENCODE_NULL_IARG) { int argType = CVMJITgetTypeTag(iargNode); int argNo = CVMJIT_IARG_ARG_NUMBER(iargNode); int argWordIndex = CVMJIT_IARG_WORD_INDEX(iargNode); CVMRMregset targetSet; CVMassert(CVMJITgetOpcode(iargNode) == (CVMJIT_IARG << CVMJIT_SHIFT_OPCODE)); if ((properties & CVMJITINTRINSIC_OPERATOR_ARGS) != 0) { const CVMJITIntrinsicEmitterVtbl *emitter = (const CVMJITIntrinsicEmitterVtbl *) config->emitterOrCCMRuntimeHelper; targetSet = emitter->getArgTarget(con, argType, argNo, argWordIndex); SET_TARGET2_0(iargNode, targetSet); } else { CVMCPUCallContext *callContext; CVMBool useRegArgs = GET_REG_ARGS(properties); CVMassert((properties & CVMJITINTRINSIC_C_ARGS) != 0 || useRegArgs); if (argNo == 0) { callContext = CVMCPUCCallnewContext(con); CVMCPUCCALLinitArgs(con, callContext, irec, CVM_TRUE, useRegArgs); } else { callContext = GET_CALL_CONTEXT(con); } targetSet = CVMCPUCCALLgetArgTarget(con, callContext, argType, argNo, argWordIndex, useRegArgs); SET_TARGET2_0(iargNode, targetSet); SET_CALL_CONTEXT(1, callContext); } } else { if ((properties & CVMJITINTRINSIC_C_ARGS) != 0) { if (irec->numberOfArgs != 0) { CVMBool useRegArgs = GET_REG_ARGS(properties); CVMCPUCallContext *callContext = GET_CALL_CONTEXT(con); CVMCPUCCALLdestroyArgs(con, callContext, irec, CVM_TRUE, useRegArgs); } } }}#else#define intrinsicRequired(con, node, submatch_roots) (CVMCPU_AVOID_NONE)#define iargTarget(con, node, goal_top, subgoals_todo)#endif /* CVMJIT_INTRINSICS */#define GET_REGISTER_GOALS \ (CVMassert((goal_top-1)->curr_attribute->type == \ CVMJIT_EXPRESSION_ATTRIBUTE_TARGET_AVOID), \ (goal_top-1)->curr_attribute->u.rs.target), \ CVMCPUconvertAvoidBitsToAvoidSet( \ (goal_top-1)->curr_attribute->u.rs.avoid)#ifdef CVM_JIT_USE_FP_HARDWARE#define GET_FLOAT_REGISTER_GOALS \ (CVMassert((goal_top-1)->curr_attribute->type == \ CVMJIT_EXPRESSION_ATTRIBUTE_TARGET_AVOID), \ (goal_top-1)->curr_attribute->u.rs.float_target), \ CVMCPUconvertAvoidBitsToFloatAvoidSet( \ (goal_top-1)->curr_attribute->u.rs.avoid)#endif#define FLUSH_GOAL_TOP(con) \ ((con)->goal_top = goal_top)/********************************************************************** * RISC common definition of the codegen-time expression stack and * operations on it. * ( Optimization: all references to tag should be ifdef DEBUG, so we don't * even set it if we're not going to do the assertions. ) *//* Purpose: Pushes a resource. */CVM_INLINE static voidpushResource(CVMJITCompilationContext* con, CVMRMResource* rp) { struct CVMJITStackElement* sp = ++(con->cgsp); statsPushResource();#ifdef CVM_DEBUG_ASSERTS sp->tag = CVMJITStackTagResource;#endif CVMassert(CVMRMgetRefCount(con, rp) > 0); sp->u.r = rp; validateStack((sp < con->cgstackLimit), Resource);}/* Purpose: Pops a resource. */CVM_INLINE static CVMRMResource*popResource(CVMJITCompilationContext* con){ CVMRMResource* rp; struct CVMJITStackElement* sp = (con->cgsp)--; statsPopResource(); CVMassert(sp >= con->cgstackInit); CVMassert(sp->tag == CVMJITStackTagResource); rp = sp->u.r; CVMassert(CVMRMgetRefCount(con, rp) > 0); return rp;}/* Purpose: Pushes a condition operand. */CVM_INLINE static voidpushIConst32(CVMJITCompilationContext* con, CVMInt32 value){ struct CVMJITStackElement* sp = ++(con->cgsp); statsPushResource();#ifdef CVM_DEBUG_ASSERTS sp->tag = CVMJITStackTagConstant;#endif sp->u.i = value; validateStack((sp < con->cgstackLimit), Resource);}/* Purpose: Pops a condition operand. */CVM_INLINE static CVMInt32popIConst32(CVMJITCompilationContext* con){ struct CVMJITStackElement* sp = (con->cgsp)--; statsPopResource(); CVMassert(sp >= con->cgstackInit); CVMassert(sp->tag == CVMJITStackTagConstant); return sp->u.i;}/* Purpose: Pushes an ALURhs operand. */CVM_INLINE static voidpushALURhs(CVMJITCompilationContext* con, CVMCPUALURhs* ap){ struct CVMJITStackElement* sp = ++(con->cgsp); statsPushResource();#ifdef CVM_DEBUG_ASSERTS sp->tag = CVMJITStackTagALURhs;#endif sp->u.aluRhs = ap; validateStack((sp < con->cgstackLimit), Resource);}/* Purpose: Pops an ALURhs operand. */CVM_INLINE static CVMCPUALURhs*popALURhs(CVMJITCompilationContext* con){ struct CVMJITStackElement* sp = (con->cgsp)--; statsPopResource(); CVMassert(sp >= con->cgstackInit); CVMassert(sp->tag == CVMJITStackTagALURhs); return sp->u.aluRhs;}/* Purpose: Pushes a MemSpec operand. */CVM_INLINE static voidpushMemSpec(CVMJITCompilationContext *con, CVMCPUMemSpec *mp){ struct CVMJITStackElement *sp = ++(con->cgsp); statsPushResource();#ifdef CVM_DEBUG_ASSERTS sp->tag = CVMJITStackTagMemSpec;#endif sp->u.memSpec = mp; validateStack((sp < con->cgstackLimit), Resource);}/* Purpose: Pops a MemSpec operand. */CVM_INLINE static CVMCPUMemSpec *popMemSpec(CVMJITCompilationContext *con){ struct CVMJITStackElement* sp = (con->cgsp)--; statsPopResource(); CVMassert(sp >= con->cgstackInit); CVMassert(sp->tag == CVMJITStackTagMemSpec); return sp->u.memSpec;}/* Push an Address */CVM_INLINE static voidpushAddress(CVMJITCompilationContext *con, CVMAddr p){ struct CVMJITStackElement *sp = ++(con->cgsp); statsPushResource();#ifdef CVM_DEBUG_ASSERTS sp->tag = CVMJITStackTagAddress;#endif sp->u.p = p; validateStack((sp < con->cgstackLimit), Resource);}/* Purpose: Pops a pointer to anything. */CVM_INLINE static CVMAddrpopAddress(CVMJITCompilationContext *con){ struct CVMJITStackElement* sp = (con->cgsp)--; statsPopResource(); CVMassert(sp >= con->cgstackInit); CVMassert(sp->tag == CVMJITStackTagAddress); return sp->u.p;}/* * "Convenience" functions. *//* Purpose: Pushes an ALURhs register operand. */CVM_INLINE static voidpushALURhsResource(CVMJITCompilationContext* con, CVMRMResource* rp){ pushALURhs(con, CVMCPUalurhsNewRegister(con, rp));}/* Purpose: Pushes an ALURhs constant operand. */CVM_INLINE static voidpushALURhsConstant(CVMJITCompilationContext* con, CVMInt32 cv){ pushALURhs(con, CVMCPUalurhsNewConstant(con, cv));}/* Purpose: Pushes a MemSpec immediate operand. */CVM_INLINE static voidpushMemSpecImmediate(CVMJITCompilationContext *con, CVMInt32 value){ pushMemSpec(con, CVMCPUmemspecNewImmediate(con, value));}/* Purpose: Pushes a MemSpec register operand. */CVM_INLINE static voidpushMemSpecRegister(CVMJITCompilationContext *con, CVMBool offsetIsToBeAdded, CVMRMResource *offsetReg){ pushMemSpec(con, CVMCPUmemspecNewRegister(con, offsetIsToBeAdded, offsetReg));}%}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -