summaryrefslogtreecommitdiff
path: root/src/jit/codegenarm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/codegenarm.cpp')
-rw-r--r--src/jit/codegenarm.cpp109
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