Commit 0f35ee78 authored by Milad Farazmand's avatar Milad Farazmand Committed by Commit Bot

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/+/2316398Reviewed-by: 's avatarJunliang Yan <jyan@ca.ibm.com>
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#69030}
parent 020fcb77
...@@ -1851,6 +1851,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1851,6 +1851,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.OutputDoubleRegister()); i.OutputDoubleRegister());
DCHECK_EQ(LeaveRC, i.OutputRCBit()); DCHECK_EQ(LeaveRC, i.OutputRCBit());
break; 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_DoubleToInt32:
case kPPC_DoubleToUint32: case kPPC_DoubleToUint32:
case kPPC_DoubleToInt64: { case kPPC_DoubleToInt64: {
......
...@@ -95,6 +95,7 @@ namespace compiler { ...@@ -95,6 +95,7 @@ namespace compiler {
V(PPC_Int32ToFloat32) \ V(PPC_Int32ToFloat32) \
V(PPC_Int32ToDouble) \ V(PPC_Int32ToDouble) \
V(PPC_Uint32ToFloat32) \ V(PPC_Uint32ToFloat32) \
V(PPC_Float32ToInt32) \
V(PPC_Uint32ToDouble) \ V(PPC_Uint32ToDouble) \
V(PPC_Float32ToDouble) \ V(PPC_Float32ToDouble) \
V(PPC_Float64SilenceNaN) \ V(PPC_Float64SilenceNaN) \
......
...@@ -92,6 +92,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -92,6 +92,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_Int32ToDouble: case kPPC_Int32ToDouble:
case kPPC_Uint32ToFloat32: case kPPC_Uint32ToFloat32:
case kPPC_Uint32ToDouble: case kPPC_Uint32ToDouble:
case kPPC_Float32ToInt32:
case kPPC_Float32ToDouble: case kPPC_Float32ToDouble:
case kPPC_Float64SilenceNaN: case kPPC_Float64SilenceNaN:
case kPPC_DoubleToInt32: case kPPC_DoubleToInt32:
......
...@@ -1227,7 +1227,7 @@ void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) { ...@@ -1227,7 +1227,7 @@ void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) {
} }
void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) { void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) {
VisitRR(this, kPPC_DoubleToInt32, node); VisitRR(this, kPPC_Float32ToInt32, node);
} }
void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) { void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) {
......
...@@ -2421,7 +2421,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -2421,7 +2421,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ ConvertFloat32ToInt32(i.OutputRegister(0), i.InputDoubleRegister(0), __ ConvertFloat32ToInt32(i.OutputRegister(0), i.InputDoubleRegister(0),
kRoundToZero); kRoundToZero);
__ b(Condition(0xE), &done, Label::kNear); // normal case __ 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); __ bind(&done);
break; break;
} }
......
...@@ -3331,6 +3331,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) { ...@@ -3331,6 +3331,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
int64_t frt_val; int64_t frt_val;
int64_t kMinVal = kMinInt; int64_t kMinVal = kMinInt;
int64_t kMaxVal = kMaxInt; int64_t kMaxVal = kMaxInt;
bool invalid_convert = false;
if (std::isnan(frb_val)) { if (std::isnan(frb_val)) {
frt_val = kMinVal; frt_val = kMinVal;
...@@ -3360,13 +3361,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) { ...@@ -3360,13 +3361,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
} }
if (frb_val < kMinVal) { if (frb_val < kMinVal) {
frt_val = kMinVal; frt_val = kMinVal;
invalid_convert = true;
} else if (frb_val > kMaxVal) { } else if (frb_val > kMaxVal) {
frt_val = kMaxVal; frt_val = kMaxVal;
invalid_convert = true;
} else { } else {
frt_val = (int64_t)frb_val; frt_val = (int64_t)frb_val;
} }
} }
set_d_register(frt, frt_val); set_d_register(frt, frt_val);
if (invalid_convert) SetFPSCR(VXCVI);
return; return;
} }
case FNEG: { case FNEG: {
......
...@@ -5956,9 +5956,11 @@ EVALUATE(LLIHL) { ...@@ -5956,9 +5956,11 @@ EVALUATE(LLIHL) {
} }
EVALUATE(LLILH) { EVALUATE(LLILH) {
UNIMPLEMENTED(); DCHECK_OPCODE(LLILH);
USE(instr); DECODE_RI_A_INSTRUCTION(instr, r1, i2);
return 0; uint64_t imm = static_cast<uint64_t>(i2);
set_register(r1, (imm << 48) >> 32);
return length;
} }
EVALUATE(LLILL) { EVALUATE(LLILL) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment