📄 jitgrammarrules.jcs
字号:
lhs = CVMRMpinResourceSpecific(CVMRM_INT_REGS(con), lhs, lhsReg); } if (checkZero) { if (CVMRMdirtyJavaLocalsCount(con) == 0) { if (resultSize == 2) { CVMRMResource *scratch = CVMRMgetResource(CVMRM_INT_REGS(con), CVMRM_ANY_SET, CVMRM_EMPTY_SET, 1); int destReg = CVMRMgetRegisterNumber(scratch); CVMCPUemitBinaryALURegister(con, CVMCPU_OR_OPCODE, destReg, rhsReg, rhsReg+1, CVMJIT_SETCC);#ifndef CVMCPU_HAS_ALU_SETCC CVMCPUemitCompare(con, CVMCPU_CMP_OPCODE, CVMCPU_COND_EQ, destReg, CVMCPUALURhsTokenConstZero); #endif CVMRMrelinquishResource(CVMRM_INT_REGS(con), scratch); } else { CVMCPUemitCompare(con, CVMCPU_CMP_OPCODE, CVMCPU_COND_EQ, rhsReg, CVMCPUALURhsTokenConstZero); } CVMJITaddCodegenComment(( con, trapCheckComments[CVMJITIR_DIVIDE_BY_ZERO])); CVMCPUemitAbsoluteCallConditional(con, (void*)CVMCCMruntimeThrowDivideByZeroGlue, CVMJIT_CPDUMPOK, CVMJIT_CPBRANCHOK, CVMCPU_COND_EQ); CVMJITcsBeginBlock(con); } else { /* Dirty locals are not supported yet */ CVMassert(CVM_FALSE); } } /* Spill the outgoing registers if necessary: */ CVMRMminorSpill(con, outSet);#ifdef CVMCPU_HAS_64BIT_REGISTERS { if (argSize >= 3) { /* argSize >= 3 means the lhs argument is doubleword */ CVMCPUemitMoveTo64BitRegister(con, CVMCPU_ARG1_REG, CVMCPU_ARG1_REG); if (argSize == 4) { /* argSize = 4 means both lhs and rhs arguments are doubleword */ CVMCPUemitMoveTo64BitRegister(con, CVMCPU_ARG2_REG, CVMCPU_ARG3_REG); } else { /* argSize is 3, and rhs is a 32-bit type. We need to move * CVMCPU_ARG3_REG to CVMCPU_ARG2_REG to set up the second * argument. */ CVMassert(argSize == 3); CVMCPUemitMoveRegister(con, CVMCPU_MOV_OPCODE, CVMCPU_ARG2_REG, CVMCPU_ARG3_REG, CVMJIT_NOSETCC); } } }#endif /* Emit the call to the helper to compute the result: */ CVMJITpushCodegenComment(con, comment); CVMJITpushSymbolName(con, symbolName); CVMCPUemitAbsoluteCall(con, helperAddress, CVMJIT_CPDUMPOK, CVMJIT_CPBRANCHOK); CVMJITcsBeginBlock(con);#ifdef CVMCPU_HAS_64BIT_REGISTERS { if (resultSize == 2) { /* resultSize = 2 means the result is a doubleword type */ CVMCPUemitMoveFrom64BitRegister(con, CVMCPU_RESULT1_REG, CVMCPU_RESULT1_REG); } }#endif /* Release resources and publish the result: */ CVMRMrelinquishResource(CVMRM_INT_REGS(con), lhs); CVMRMrelinquishResource(CVMRM_INT_REGS(con), rhs); dest = CVMRMgetResourceSpecific(CVMRM_INT_REGS(con), CVMCPU_RESULT1_REG, resultSize); CVMRMoccupyAndUnpinResource(CVMRM_INT_REGS(con), dest, thisNode); pushResource(con, dest);}/* Purpose: Emits a call to a Binary CCM helper which return a word result. */static voidwordBinaryHelper( CVMJITCompilationContext *con, void* helperAddress, CVMJITIRNodePtr thisNode, CVMBool checkZero ){ binaryHelper(con, helperAddress, thisNode, checkZero, 2, 1);}/* Purpose: Emits a call to a Binary CCM helper which return a dword result. */static voidlongBinaryHelper( CVMJITCompilationContext *con, void *helperAddress, CVMJITIRNodePtr thisNode, CVMBool checkZero ){ binaryHelper(con, helperAddress, thisNode, checkZero, 4, 2);}/* Purpose: Emits a call to a Binary CCM helper which return a dword resul, * but whose 2nd argument is 32-bit, not 64-bit. */static voidlongBinaryHelper2( CVMJITCompilationContext *con, void *helperAddress, CVMJITIRNodePtr thisNode, CVMBool checkZero ){ binaryHelper(con, helperAddress, thisNode, checkZero, 3, 2);}/* Purpose: Emits a call to a Binary CCM helper which return a dword result. */static voidlongBinary2WordHelper( CVMJITCompilationContext *con, void *helperAddress, CVMJITIRNodePtr thisNode, CVMBool checkZero){ binaryHelper(con, helperAddress, thisNode, checkZero, 4, 1);}/* * For nodes of the form: * NODE .... reg<width> * * Pass the reg<width> value onto NODE */static voidpassLastEvaluated(CVMJITCompilationContext* con, CVMJITRMContext* rc, CVMJITIRNodePtr thisNode){ /* Associate the last evaluated sub-node on to its parent */ CVMRMResource* arg = popResource(con); CVMRMoccupyAndUnpinResource(rc, arg, thisNode); pushResource(con, arg);}/* * Inlining start */static voidbeginInlining(CVMJITCompilationContext* con, CVMJITIRNodePtr thisNode){ CVMJITUnaryOp* unop = CVMJITirnodeGetUnaryOp(thisNode); CVMJITConstantAddr* constAddr; CVMJITMethodContext* mc; CVMUint16 pcStart = CVMJITcbufGetLogicalPC(con); CVMJITInliningInfoStackEntry* newEntry; CVMassert(CVMJITirnodeIsConstMC(unop->operand)); constAddr = CVMJITirnodeGetConstantAddr(unop->operand); mc = constAddr->mc; /* Start a new inlining entry */ CVMassert(con->inliningDepth < con->maxInliningDepth); newEntry = &con->inliningStack[con->inliningDepth++]; /* Record the starting point and mb of this inlining record */ /* The end point will be recorded by the corresponding END_INLINING node */ newEntry->pcOffset1 = pcStart; newEntry->mc = mc; CVMJITprintCodegenComment(("Begin inlining of %C.%M (start pc=%d):", CVMmbClassBlock(mc->mb), mc->mb, pcStart));}/* * We have finished inlined code. Record this PC. */static voidendInlining(CVMJITCompilationContext* con, CVMJITIRNodePtr thisNode){ CVMJITInliningInfoStackEntry* topEntry; CVMCompiledInliningInfoEntry* recordedEntry; CVMUint16 pcEnd = CVMJITcbufGetLogicalPC(con); CVMJITMethodContext *mc; CVMUint16 count = CVMJITirnodeGetNull(thisNode)->data; CVMassert(count > 0); while (count-- > 0) { CVMassert(con->inliningDepth > 0); topEntry = &con->inliningStack[--con->inliningDepth]; mc = topEntry->mc; CVMassert(topEntry->pcOffset1 > 0); CVMassert(topEntry->mc != NULL); CVMassert(con->inliningInfoIdx < con->numInliningInfoEntries); /* Now commit another "permanent" entry */ recordedEntry = &con->inliningInfo->entries[con->inliningInfoIdx++]; recordedEntry->pcOffset1 = topEntry->pcOffset1; recordedEntry->mb = mc->mb; recordedEntry->pcOffset2 = pcEnd; recordedEntry->invokePC = mc->invokePC; recordedEntry->flags = 0; { recordedEntry->firstLocal = mc->firstLocal; if (CVMmbIs(mc->mb, SYNCHRONIZED)) { CVMassert(!CVMmbIs(mc->mb, STATIC)); recordedEntry->syncObject = mc->syncObject; } else { recordedEntry->syncObject = 0; } } CVMJITprintCodegenComment(("End inlining of %C.%M (end pc=%d):", CVMmbClassBlock(recordedEntry->mb), recordedEntry->mb, pcEnd)); }}#ifdef CVM_DEBUGstatic void printInliningInfo(CVMJITIRNode* thisNode, const char* what){ CVMJITUnaryOp* unop = CVMJITirnodeGetUnaryOp(thisNode); CVMJITConstantAddr* constAddr; CVMMethodBlock* mb; if (CVMJITirnodeIsConstMB(unop->operand)) { constAddr = CVMJITirnodeGetConstantAddr(unop->operand); mb = constAddr->mb; CVMJITprintCodegenComment(("%s of %C.%M:", what, CVMmbClassBlock(mb), mb)); } else { CVMJITprintCodegenComment(("%s (node id %d):", what, CVMJITirnodeGetID(unop->operand))); }}#else#define printInliningInfo(thisNode, what)#endif%}//// "R" Sequences://// SEQUENCE_R// / \// effect expr//// evaluates to the value of 'expr'. 'effect' does not produce a value.//%{#define SEQUENCE_R_INHERITANCE(thisNode, rc) { \ SET_ATTRIBUTE_TYPE(0, CVMJIT_EXPRESSION_ATTRIBUTE_TARGET_AVOID); \ goal_top[0].attributes[0].u.rs.target = CVMRM_GET_ANY_SET(rc); \ goal_top[0].attributes[0].u.rs.avoid = CVMCPU_AVOID_NONE; \ goal_top[0].attributes[1] = goal_top[-1].curr_attribute[0]; \}%}reg32: ISEQUENCE_R effect reg32 : 0 : : SEQUENCE_R_INHERITANCE($$, CVMRM_INT_REGS(con)); : : { passLastEvaluated(con, CVMRM_INT_REGS(con), $$);};reg64: LSEQUENCE_R effect reg64 : 0 : : SEQUENCE_R_INHERITANCE($$, CVMRM_INT_REGS(con)); : : { passLastEvaluated(con, CVMRM_INT_REGS(con), $$);};// "type-less" sequence. reg32: VSEQUENCE_R effect reg32 : 0 : : SEQUENCE_R_INHERITANCE($$, CVMRM_INT_REGS(con)); : : ;//// "L" Sequences://// SEQUENCE_L// / \// expr effect//// evaluates to the value of 'expr'. 'effect' does not produce a value.//%{#define SEQUENCE_L_INHERITANCE(thisNode, rc) { \ SET_ATTRIBUTE_TYPE(1, CVMJIT_EXPRESSION_ATTRIBUTE_TARGET_AVOID); \ goal_top[0].attributes[0] = goal_top[-1].curr_attribute[0]; \ goal_top[0].attributes[1].u.rs.target = CVMRM_GET_ANY_SET(rc); \ goal_top[0].attributes[1].u.rs.avoid = CVMCPU_AVOID_NONE; \}%}reg32: ISEQUENCE_L reg32 effect : 0 : : SEQUENCE_L_INHERITANCE($$, CVMRM_INT_REGS(con)); : : { passLastEvaluated(con, CVMRM_INT_REGS(con), $$);};reg64: LSEQUENCE_L reg64 effect : 0 : : SEQUENCE_L_INHERITANCE($$, CVMRM_INT_REGS(con)); : : { passLastEvaluated(con, CVMRM_INT_REGS(con), $$);};// "type-less" sequence. reg32: VSEQUENCE_L reg32 effect : 0 : : SEQUENCE_L_INHERITANCE($$, CVMRM_INT_REGS(con)); : : ;// this is always a root noderoot: BEGININLINING : 0 : : : : { beginInlining(con, $$);};//// The following node is to mark the end of the inlining of a method.//effect: VENDINLINING : 0 : : : : { endInlining(con, $$);};reg32: LOCAL32 : 10 : : : : { CVMJITLocal* l = CVMJITirnodeGetLocal( $$ ); CVMBool isRef = CVMJITirnodeIsReferenceType($$); CVMRMResource* dest = CVMRMbindResourceForLocal(CVMRM_INT_REGS(con), 1, isRef, l->localNo); CVMRMpinResourceEagerlyIfDesireable(CVMRM_INT_REGS(con), dest, GET_REGISTER_GOALS); CVMRMoccupyAndUnpinResource(CVMRM_INT_REGS(con), dest, $$); pushResource(con, dest); };reg64: LOCAL64 : 10 : : : : { CVMJITLocal* l = CVMJITirnodeGetLocal( $$ ); CVMRMResource* dest = CVMRMbindResourceForLocal(CVMRM_INT_REGS(con), 2, CVM_FALSE, l->localNo); CVMRMpinResourceEagerlyIfDesireable(CVMRM_INT_REGS(con), dest, GET_REGISTER_GOALS); CVMRMoccupyAndUnpinResource(CVMRM_INT_REGS(con), dest, $$); pushResource(con, dest); };%{/* Purpose: Gets a value from a static field of an object. */static void getStaticField(CVMJITCompilationContext *con, CVMJITRMContext* rc, CVMJITIRNodePtr thisNode, CVMRMregset target, CVMRMregset avoid, CVMInt32 opcode, int fieldSize, CVMBool isVolatile){ /* NOTE: For a non-LVM build, the staticFieldSpec is the staticFieldAddress. For an LVM build, the staticFieldSpec is the fieldblock of the static field. */ /* fetch over static-field-ref over fb constant */ CVMRMResource *staticField = popResource(con); CVMRMResource *dest = CVMRMgetResource(rc, target, avoid, fieldSize); /* %comment l026 */ CVMRMpinResource(CVMRM_INT_REGS(con), staticField, CVMRM_ANY_SET, CVMRM_EMPTY_SET); CVMJITcsSetGetStaticFieldInstruction(con); CVMCPUemitMemoryReferenceImmediate(con, opcode, CVMRMgetRegisterNumber(dest), CVMRMgetRegisterNumber(staticField), 0); if (isVolatile) { CVMCPUemitMemBarAcquire(con); } CVMRMrelinquishResource(CVMRM_INT_REGS(con), staticField); CVMRMoccupyAndUnpinResource(rc, dest, thisNode); pushResource(con, dest);}%}// Purpose: value32 = FETCH32(STATIC32(staticFieldSpec))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -