diff options
Diffstat (limited to 'src/jit/codegenarm.cpp')
-rw-r--r-- | src/jit/codegenarm.cpp | 109 |
1 files changed, 30 insertions, 79 deletions
diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp index 41bd8040ac..c28b27bf9b 100644 --- a/src/jit/codegenarm.cpp +++ b/src/jit/codegenarm.cpp @@ -166,9 +166,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre if (targetType == TYP_FLOAT) { // Get a temp integer register - regMaskTP tmpRegMask = tree->gtRsvdRegs; - regNumber tmpReg = genRegNumFromMask(tmpRegMask); - assert(tmpReg != REG_NA); + regNumber tmpReg = tree->GetSingleTempReg(); float f = forceCastToFloat(constValue); genSetRegToIcon(tmpReg, *((int*)(&f))); @@ -181,15 +179,8 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre unsigned* cv = (unsigned*)&constValue; // Get two temp integer registers - regMaskTP tmpRegsMask = tree->gtRsvdRegs; - regMaskTP tmpRegMask = genFindHighestBit(tmpRegsMask); // set tmpRegMsk to a one-bit mask - regNumber tmpReg1 = genRegNumFromMask(tmpRegMask); - assert(tmpReg1 != REG_NA); - - tmpRegsMask &= ~genRegMask(tmpReg1); // remove the bit for 'tmpReg1' - tmpRegMask = genFindHighestBit(tmpRegsMask); // set tmpRegMsk to a one-bit mask - regNumber tmpReg2 = genRegNumFromMask(tmpRegMask); - assert(tmpReg2 != REG_NA); + regNumber tmpReg1 = tree->ExtractTempReg(); + regNumber tmpReg2 = tree->GetSingleTempReg(); genSetRegToIcon(tmpReg1, cv[0]); genSetRegToIcon(tmpReg2, cv[1]); @@ -225,14 +216,8 @@ void CodeGen::genCodeForBinary(GenTree* treeNode) var_types targetType = treeNode->TypeGet(); emitter* emit = getEmitter(); - assert(oper == GT_ADD || oper == GT_SUB || oper == GT_ADD_LO || oper == GT_ADD_HI || oper == GT_SUB_LO || - oper == GT_SUB_HI || oper == GT_OR || oper == GT_XOR || oper == GT_AND); - - if ((oper == GT_ADD || oper == GT_SUB || oper == GT_ADD_HI || oper == GT_SUB_HI) && treeNode->gtOverflow()) - { - // This is also checked in the importer. - NYI("Overflow not yet implemented"); - } + assert(oper == GT_ADD || oper == GT_SUB || oper == GT_MUL || oper == GT_ADD_LO || oper == GT_ADD_HI || + oper == GT_SUB_LO || oper == GT_SUB_HI || oper == GT_OR || oper == GT_XOR || oper == GT_AND); GenTreePtr op1 = treeNode->gtGetOp1(); GenTreePtr op2 = treeNode->gtGetOp2(); @@ -412,32 +397,9 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) case GT_SUB_HI: case GT_ADD: case GT_SUB: - genConsumeOperands(treeNode->AsOp()); - genCodeForBinary(treeNode); - break; - case GT_MUL: - { genConsumeOperands(treeNode->AsOp()); - - const genTreeOps oper = treeNode->OperGet(); - if (treeNode->gtOverflow()) - { - // This is also checked in the importer. - NYI("Overflow not yet implemented"); - } - - GenTreePtr op1 = treeNode->gtGetOp1(); - GenTreePtr op2 = treeNode->gtGetOp2(); - instruction ins = genGetInsForOper(treeNode->OperGet(), targetType); - - // The arithmetic node must be sitting in a register (since it's not contained) - noway_assert(targetReg != REG_NA); - - regNumber r = emit->emitInsTernary(ins, emitTypeSize(treeNode), treeNode, op1, op2); - assert(r == targetReg); - } - genProduceReg(treeNode); + genCodeForBinary(treeNode); break; case GT_LSH: @@ -529,7 +491,21 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) unsigned varNum = treeNode->gtLclVarCommon.gtLclNum; assert(varNum < compiler->lvaCount); - emit->emitIns_R_S(ins_Move_Extend(targetType, treeNode->InReg()), size, targetReg, varNum, offs); + if (varTypeIsFloating(targetType)) + { + if (treeNode->InReg()) + { + NYI("GT_LCL_FLD with reg-to-reg floating point move"); + } + else + { + emit->emitIns_R_S(ins_Load(targetType), size, targetReg, varNum, offs); + } + } + else + { + emit->emitIns_R_S(ins_Move_Extend(targetType, treeNode->InReg()), size, targetReg, varNum, offs); + } } genProduceReg(treeNode); break; @@ -804,22 +780,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) break; case GT_JTRUE: - { - GenTree* cmp = treeNode->gtOp.gtOp1->gtEffectiveVal(); - assert(cmp->OperIsCompare()); - assert(compiler->compCurBB->bbJumpKind == BBJ_COND); - - // Get the "kind" and type of the comparison. Note that whether it is an unsigned cmp - // is governed by a flag NOT by the inherent type of the node - // TODO-ARM-CQ: Check if we can use the currently set flags. - CompareKind compareKind = ((cmp->gtFlags & GTF_UNSIGNED) != 0) ? CK_UNSIGNED : CK_SIGNED; - - emitJumpKind jmpKind = genJumpKindForOper(cmp->gtOper, compareKind); - BasicBlock* jmpTarget = compiler->compCurBB->bbJumpDest; - - inst_JMP(jmpKind, jmpTarget); - } - break; + genCodeForJumpTrue(treeNode); + break; case GT_JCC: { @@ -1013,8 +975,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) case GT_NULLCHECK: { assert(!treeNode->gtOp.gtOp1->isContained()); - regNumber reg = genConsumeReg(treeNode->gtOp.gtOp1); - emit->emitIns_AR_R(INS_cmp, EA_4BYTE, reg, reg, 0); + regNumber addrReg = genConsumeReg(treeNode->gtOp.gtOp1); + emit->emitIns_R_R_I(INS_ldr, EA_4BYTE, targetReg, addrReg, 0); } break; @@ -1129,7 +1091,6 @@ void CodeGen::genLclHeap(GenTreePtr tree) // Also it used as temporary register in code generation // for storing allocation size regNumber regCnt = tree->gtRegNum; - regMaskTP tmpRegsMask = tree->gtRsvdRegs; regNumber pspSymReg = REG_NA; var_types type = genActualType(size->gtType); emitAttr easz = emitTypeSize(type); @@ -1198,10 +1159,7 @@ void CodeGen::genLclHeap(GenTreePtr tree) stackAdjustment += STACK_ALIGN; // Save a copy of PSPSym - assert(genCountBits(tmpRegsMask) >= 1); - regMaskTP pspSymRegMask = genFindLowestBit(tmpRegsMask); - tmpRegsMask &= ~pspSymRegMask; - pspSymReg = genRegNumFromMask(pspSymRegMask); + pspSymReg = tree->ExtractTempReg(); getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0); } #endif @@ -1266,12 +1224,7 @@ void CodeGen::genLclHeap(GenTreePtr tree) // Since we have to zero out the allocated memory AND ensure that RSP is always valid // by tickling the pages, we will just push 0's on the stack. - assert(tmpRegsMask != RBM_NONE); - assert(genCountBits(tmpRegsMask) >= 1); - - regMaskTP regCntMask = genFindLowestBit(tmpRegsMask); - tmpRegsMask &= ~regCntMask; - regNumber regTmp = genRegNumFromMask(regCntMask); + regNumber regTmp = tree->ExtractTempReg(); instGen_Set_Reg_To_Zero(EA_PTRSIZE, regTmp); // Loop: @@ -1285,7 +1238,7 @@ void CodeGen::genLclHeap(GenTreePtr tree) // If not done, loop // Note that regCnt is the number of bytes to stack allocate. assert(genIsValidIntReg(regCnt)); - getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, regCnt, regCnt, STACK_ALIGN); + getEmitter()->emitIns_R_I(INS_sub, EA_PTRSIZE, regCnt, STACK_ALIGN, INS_FLAGS_SET); emitJumpKind jmpNotEqual = genJumpKindForOper(GT_NE, CK_SIGNED); inst_JMP(jmpNotEqual, loop); } @@ -1323,15 +1276,13 @@ void CodeGen::genLclHeap(GenTreePtr tree) // // Setup the regTmp - assert(tmpRegsMask != RBM_NONE); - assert(genCountBits(tmpRegsMask) == 1); - regNumber regTmp = genRegNumFromMask(tmpRegsMask); + regNumber regTmp = tree->ExtractTempReg(); BasicBlock* loop = genCreateTempLabel(); BasicBlock* done = genCreateTempLabel(); // subs regCnt, SP, regCnt // regCnt now holds ultimate SP - getEmitter()->emitIns_R_R_R(INS_sub, EA_PTRSIZE, regCnt, REG_SPBASE, regCnt); + getEmitter()->emitIns_R_R_R(INS_sub, EA_PTRSIZE, regCnt, REG_SPBASE, regCnt, INS_FLAGS_SET); inst_JMP(EJ_vc, loop); // branch if the V flag is not set |