PPC/s390x: Use INT32_MIN s an overflow indicator

To match the behaviour of other architectures, Float32ToInt32
needs to return INT32_MIN as an overflow indicator instead of 0.

Change-Id: I68140daf06f8575fc38fb857033b5c56fec6bb2f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2316398
Reviewed-by: Junliang Yan <jyan@ca.ibm.com>
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#69030}
This commit is contained in:
Milad Farazmand 2020-07-23 17:45:11 +00:00 committed by Commit Bot
parent 020fcb77a3
commit 0f35ee7851
7 changed files with 29 additions and 5 deletions

View File

@ -1851,6 +1851,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.OutputDoubleRegister());
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_Float32ToInt32: {
__ mtfsb0(VXCVI); // clear FPSCR:VXCVI bit
__ fctiwz(kScratchDoubleReg, i.InputDoubleRegister(0));
__ MovDoubleLowToInt(i.OutputRegister(), kScratchDoubleReg);
// Use INT32_MIN s an overflow indicator because it allows for easier
// out-of-bounds detection.
CRegister cr = cr7;
int crbit = v8::internal::Assembler::encode_crbit(
cr, static_cast<CRBit>(VXCVI % CRWIDTH));
__ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7
__ lis(kScratchReg, Operand(static_cast<int16_t>(0x8000)));
__ isel(i.OutputRegister(0), kScratchReg, i.OutputRegister(0), crbit);
break;
}
case kPPC_DoubleToInt32:
case kPPC_DoubleToUint32:
case kPPC_DoubleToInt64: {

View File

@ -95,6 +95,7 @@ namespace compiler {
V(PPC_Int32ToFloat32) \
V(PPC_Int32ToDouble) \
V(PPC_Uint32ToFloat32) \
V(PPC_Float32ToInt32) \
V(PPC_Uint32ToDouble) \
V(PPC_Float32ToDouble) \
V(PPC_Float64SilenceNaN) \

View File

@ -92,6 +92,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_Int32ToDouble:
case kPPC_Uint32ToFloat32:
case kPPC_Uint32ToDouble:
case kPPC_Float32ToInt32:
case kPPC_Float32ToDouble:
case kPPC_Float64SilenceNaN:
case kPPC_DoubleToInt32:

View File

@ -1227,7 +1227,7 @@ void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) {
}
void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) {
VisitRR(this, kPPC_DoubleToInt32, node);
VisitRR(this, kPPC_Float32ToInt32, node);
}
void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) {

View File

@ -2421,7 +2421,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ ConvertFloat32ToInt32(i.OutputRegister(0), i.InputDoubleRegister(0),
kRoundToZero);
__ b(Condition(0xE), &done, Label::kNear); // normal case
__ lghi(i.OutputRegister(0), Operand::Zero());
// Use INT32_MIN s an overflow indicator because it allows for easier
// out-of-bounds detection.
__ llilh(i.OutputRegister(0), Operand(0x8000));
__ bind(&done);
break;
}

View File

@ -3331,6 +3331,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
int64_t frt_val;
int64_t kMinVal = kMinInt;
int64_t kMaxVal = kMaxInt;
bool invalid_convert = false;
if (std::isnan(frb_val)) {
frt_val = kMinVal;
@ -3360,13 +3361,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
}
if (frb_val < kMinVal) {
frt_val = kMinVal;
invalid_convert = true;
} else if (frb_val > kMaxVal) {
frt_val = kMaxVal;
invalid_convert = true;
} else {
frt_val = (int64_t)frb_val;
}
}
set_d_register(frt, frt_val);
if (invalid_convert) SetFPSCR(VXCVI);
return;
}
case FNEG: {

View File

@ -5956,9 +5956,11 @@ EVALUATE(LLIHL) {
}
EVALUATE(LLILH) {
UNIMPLEMENTED();
USE(instr);
return 0;
DCHECK_OPCODE(LLILH);
DECODE_RI_A_INSTRUCTION(instr, r1, i2);
uint64_t imm = static_cast<uint64_t>(i2);
set_register(r1, (imm << 48) >> 32);
return length;
}
EVALUATE(LLILL) {