return kNoCondition;
}
-FPUCondition FlagsConditionToConditionCmpD(bool& predicate,
- FlagsCondition condition) {
- switch (condition) {
- case kEqual:
- predicate = true;
- return EQ;
- case kNotEqual:
- predicate = false;
- return EQ;
- case kUnsignedLessThan:
- predicate = true;
- return OLT;
- case kUnsignedLessThanOrEqual:
- predicate = true;
- return OLE;
- case kUnorderedEqual:
- case kUnorderedNotEqual:
- predicate = true;
- break;
- default:
- predicate = true;
- break;
- }
- UNREACHABLE();
- return kNoFPUCondition;
-}
-
} // namespace
// in the false case, where we fall thru the branch, we reset the result
// false.
+ // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
+ // not separated by other instructions.
if (instr->arch_opcode() == kMipsTst) {
cc = FlagsConditionToConditionTst(condition);
__ And(at, i.InputRegister(0), i.InputOperand(1));
__ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg));
__ li(result, Operand(1)); // In delay slot.
+
} else if (instr->arch_opcode() == kMipsCmp) {
Register left = i.InputRegister(0);
Operand right = i.InputOperand(1);
} else if (instr->arch_opcode() == kMipsCmpD) {
FPURegister left = i.InputDoubleRegister(0);
FPURegister right = i.InputDoubleRegister(1);
-
- bool predicate;
- FPUCondition cc = FlagsConditionToConditionCmpD(predicate, condition);
- if (!IsMipsArchVariant(kMips32r6)) {
- __ li(result, Operand(1));
- __ c(cc, D, left, right);
- if (predicate) {
- __ Movf(result, zero_reg);
- } else {
- __ Movt(result, zero_reg);
- }
- } else {
- __ cmp(cc, L, kDoubleCompareReg, left, right);
- __ mfc1(at, kDoubleCompareReg);
- __ srl(result, at, 31); // Cmp returns all 1s for true.
- if (!predicate) // Toggle result for not equal.
- __ xori(result, result, 1);
+ // TODO(plind): Provide NaN-testing macro-asm function without need for
+ // BranchF.
+ FPURegister dummy1 = f0;
+ FPURegister dummy2 = f2;
+ switch (condition) {
+ case kEqual:
+ // TODO(plind): improve the NaN testing throughout this function.
+ __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+ cc = eq;
+ break;
+ case kNotEqual:
+ __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+ __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
+ cc = ne;
+ break;
+ case kUnsignedLessThan:
+ __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+ cc = lt;
+ break;
+ case kUnsignedGreaterThanOrEqual:
+ __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+ __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
+ cc = ge;
+ break;
+ case kUnsignedLessThanOrEqual:
+ __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+ cc = le;
+ break;
+ case kUnsignedGreaterThan:
+ __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+ __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
+ cc = gt;
+ break;
+ default:
+ UNSUPPORTED_COND(kMipsCmp, condition);
+ break;
}
- return;
+ __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
+ __ li(result, Operand(1)); // In delay slot - branch taken returns 1.
+ // Fall-thru (branch not taken) returns 0.
+
} else {
PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
instr->arch_opcode());
TRACE_UNIMPL();
UNIMPLEMENTED();
}
-
- // Fallthrough case is the false materialization.
+ // Fallthru case is the false materialization.
__ bind(&false_value);
__ li(result, Operand(0));
__ bind(&done);
return kNoCondition;
}
-
-FPUCondition FlagsConditionToConditionCmpD(bool& predicate,
- FlagsCondition condition) {
- switch (condition) {
- case kEqual:
- predicate = true;
- return EQ;
- case kNotEqual:
- predicate = false;
- return EQ;
- case kUnsignedLessThan:
- predicate = true;
- return OLT;
- case kUnsignedLessThanOrEqual:
- predicate = true;
- return OLE;
- case kUnorderedEqual:
- case kUnorderedNotEqual:
- predicate = true;
- break;
- default:
- predicate = true;
- break;
- }
- UNREACHABLE();
- return kNoFPUCondition;
-}
-
} // namespace
} else if (instr->arch_opcode() == kMips64CmpD) {
FPURegister left = i.InputDoubleRegister(0);
FPURegister right = i.InputDoubleRegister(1);
-
- bool predicate;
- FPUCondition cc = FlagsConditionToConditionCmpD(predicate, condition);
- if (kArchVariant != kMips64r6) {
- __ li(result, Operand(1));
- __ c(cc, D, left, right);
- if (predicate) {
- __ Movf(result, zero_reg);
- } else {
- __ Movt(result, zero_reg);
- }
- } else {
- __ cmp(cc, L, kDoubleCompareReg, left, right);
- __ dmfc1(at, kDoubleCompareReg);
- __ dsrl32(result, at, 31); // Cmp returns all 1s for true.
- if (!predicate) // Toggle result for not equal.
- __ xori(result, result, 1);
+ // TODO(plind): Provide NaN-testing macro-asm function without need for
+ // BranchF.
+ FPURegister dummy1 = f0;
+ FPURegister dummy2 = f2;
+ switch (condition) {
+ case kEqual:
+ // TODO(plind): improve the NaN testing throughout this function.
+ __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+ cc = eq;
+ break;
+ case kNotEqual:
+ __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+ __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
+ cc = ne;
+ break;
+ case kUnsignedLessThan:
+ __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+ cc = lt;
+ break;
+ case kUnsignedGreaterThanOrEqual:
+ __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+ __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
+ cc = ge;
+ break;
+ case kUnsignedLessThanOrEqual:
+ __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+ cc = le;
+ break;
+ case kUnsignedGreaterThan:
+ __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+ __ li(result, Operand(1)); // In delay slot - returns 1 on NaN.
+ cc = gt;
+ break;
+ default:
+ UNSUPPORTED_COND(kMips64Cmp, condition);
+ break;
}
- return;
+ __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
+ __ li(result, Operand(1)); // In delay slot - branch taken returns 1.
+ // Fall-thru (branch not taken) returns 0.
+
} else {
PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
instr->arch_opcode());