From 8478d4fd459df761cd88769d971a95f216c3ccba Mon Sep 17 00:00:00 2001
From: Wouter Vermeiren <wouter.vermeiren@essensium.com>
Date: Thu, 2 Jul 2020 10:12:16 +0200
Subject: [PATCH] Fix various DoubleToInt32 conversion

---
 .../v8/src/codegen/ppc/macro-assembler-ppc.cc | 67 ++++++++++++-------
 deps/v8/src/codegen/ppc/macro-assembler-ppc.h |  4 ++
 .../compiler/backend/instruction-selector.cc  | 14 ----
 .../backend/ppc/code-generator-ppc.cc         | 13 ++--
 .../backend/ppc/instruction-selector-ppc.cc   | 11 +--
 5 files changed, 54 insertions(+), 55 deletions(-)

diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
index 65a9f040..2ab66c43 100644
--- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
+++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
@@ -697,6 +697,25 @@ void TurboAssembler::CanonicalizeNaN(const DoubleRegister dst,
   fsub(dst, src, kDoubleRegZero);
 }
 
+void TurboAssembler::ConvertDoubleToInt32NoPPC64(
+  DoubleRegister src,
+  Register dest, Register dest_hi,
+  FPRoundingMode rounding_mode)  {
+    
+  if (rounding_mode == kRoundToZero) {
+    fctiwz(src, src);
+  } else {
+    SetRoundingMode(rounding_mode);
+    fctiw(src, src);
+    ResetRoundingMode();
+  }
+  subi(sp, sp, Operand(kDoubleSize));
+  stfd(src, MemOperand(sp, 0));
+  lwz(dest, MemOperand(sp, LO_WORD_OFFSET));
+  lwz(dest_hi, MemOperand(sp, HI_WORD_OFFSET));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
 void TurboAssembler::ConvertIntToFloatingPointNoPPC64(Register src,
     DoubleRegister double_dst,
     bool result_is_a_float,
@@ -705,7 +724,7 @@ void TurboAssembler::ConvertIntToFloatingPointNoPPC64(Register src,
     Register scratch = r11;
     DoubleRegister double_scratch = kScratchDoubleReg;
 
-  subi(sp, sp, Operand(8));  // reserve one temporary double on the stack
+  subi(sp, sp, Operand(kDoubleSize));  // reserve one temporary double on the stack
 
   // sign-extend src to 64-bit and store it to temp double on the stack
 #if V8_TARGET_ARCH_PPC64
@@ -713,14 +732,10 @@ void TurboAssembler::ConvertIntToFloatingPointNoPPC64(Register src,
   std(r0, MemOperand(sp, 0));
 #else
   srawi(r0, src, 31);
-#if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN
-  stw(r0, MemOperand(sp, 4));
-  stw(src, MemOperand(sp, 0));
-#else
-  stw(r0, MemOperand(sp, 0));
-  stw(src, MemOperand(sp, 4));
-#endif
+  stw(r0, MemOperand(sp, HI_WORD_OFFSET));
+  stw(src, MemOperand(sp, LO_WORD_OFFSET));
 #endif
+
   if (src_is_unsigned) {
     // load 0x4330000000000000 into double_scratch
     lis(scratch, Operand(0x4330));
@@ -741,7 +756,7 @@ void TurboAssembler::ConvertIntToFloatingPointNoPPC64(Register src,
     stw(scratch, MemOperand(sp, LO_WORD_OFFSET));
     lfd(double_scratch, MemOperand(sp, 0));
 
-  // load into FPR
+    // load into FPR
     // load 0x1.00000dddddddd x10^D into double_dst
     lis(scratch, Operand(0x4330));
     stw(scratch, MemOperand(sp, HI_WORD_OFFSET));
@@ -753,7 +768,7 @@ void TurboAssembler::ConvertIntToFloatingPointNoPPC64(Register src,
   lfd(double_dst, MemOperand(sp, 0));
   fsub(double_dst, double_dst, double_scratch);
 
-  addi(sp, sp, Operand(8));  // restore stack
+  addi(sp, sp, Operand(kDoubleSize));  // restore stack
 
   if (result_is_a_float) {
     // Round to single word FP
@@ -840,6 +855,14 @@ void TurboAssembler::ConvertDoubleToInt64(const DoubleRegister double_input,
     fctid(double_dst, double_input);
     ResetRoundingMode();
   }
+else
+  if (rounding_mode == kRoundToZero) {
+    fctiwz(double_dst, double_input);
+  } else {
+    SetRoundingMode(rounding_mode);
+    fctiw(double_dst, double_input);
+    ResetRoundingMode();
+  }
 #endif
 
   MovDoubleToInt64(
@@ -1690,22 +1713,14 @@ void TurboAssembler::TruncateDoubleToI(Isolate* isolate, Zone* zone,
 void TurboAssembler::TryInlineTruncateDoubleToI(Register result,
                                                 DoubleRegister double_input,
                                                 Label* done) {
-  DoubleRegister double_scratch = kScratchDoubleReg;
 #if !V8_TARGET_ARCH_PPC64
-  Register scratch = ip;
-#endif
-
-  ConvertDoubleToInt64(double_input,
-#if !V8_TARGET_ARCH_PPC64
-                       scratch,
-#endif
-                       result, double_scratch);
-
-// Test for overflow
-#if V8_TARGET_ARCH_PPC64
-  TestIfInt32(result, r0);
-#else
+  Register scratch = r11;
+  ConvertDoubleToInt32NoPPC64(double_input, result, scratch);
   TestIfInt32(scratch, result, r0);
+#else
+  DoubleRegister double_scratch = kScratchDoubleReg;
+  ConvertDoubleToInt64(double_input, result, double_scratch);
+  TestIfInt32(result, r0);
 #endif
   beq(done);
 }
@@ -2525,7 +2540,7 @@ void MacroAssembler::AddSmiLiteral(Register dst, Register src, Smi smi,
   LoadSmiLiteral(scratch, smi);
   add(dst, src, scratch);
 #else
-  Add(dst, src, reinterpret_cast<uintptr_t>(smi.ptr()), scratch);
+  Add(dst, src, smi.value(), scratch);
 #endif
 }
 
@@ -2535,7 +2550,7 @@ void MacroAssembler::SubSmiLiteral(Register dst, Register src, Smi smi,
   LoadSmiLiteral(scratch, smi);
   sub(dst, src, scratch);
 #else
-  Add(dst, src, -(reinterpret_cast<uintptr_t>(smi.ptr())), scratch);
+  Add(dst, src, -smi.value(), scratch);
 #endif
 }
 
diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
index d7b68793..e4edd19e 100644
--- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
+++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
@@ -74,6 +74,10 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
     DoubleRegister double_dst,
     bool result_is_a_float,
     bool src_is_unsigned);
+  void ConvertDoubleToInt32NoPPC64(DoubleRegister src,
+                                Register dest,
+                                Register dest_hi,
+                                FPRoundingMode rounding_mode = kRoundToZero);
   #endif
 
   // Converts the integer (untagged smi) in |src| to a double, storing
diff --git a/deps/v8/src/compiler/backend/instruction-selector.cc b/deps/v8/src/compiler/backend/instruction-selector.cc
index bec33aa9..8a7f53ca 100644
--- a/deps/v8/src/compiler/backend/instruction-selector.cc
+++ b/deps/v8/src/compiler/backend/instruction-selector.cc
@@ -2376,8 +2376,6 @@ void InstructionSelector::VisitWord64ReverseBits(Node* node) {
 
 void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
 
-void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
-
 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
 
 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
@@ -2394,22 +2392,10 @@ void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
 
 void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
 
-void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
-
-void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
-  UNIMPLEMENTED();
-}
-
 void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
 
 void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
 
-void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
-
-void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
-  UNIMPLEMENTED();
-}
-
 void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
 
 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
diff --git a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
index 62ac4fc7..b5d4fbca 100644
--- a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
+++ b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
@@ -1178,11 +1178,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
       __ cmpl(sp, i.InputRegister(kValueIndex), cr0);
       break;
     }
-    case kArchTruncateDoubleToI:
+    case kArchTruncateDoubleToI: {
       __ TruncateDoubleToI(isolate(), zone(), i.OutputRegister(),
                            i.InputDoubleRegister(0), DetermineStubCallMode());
       DCHECK_EQ(LeaveRC, i.OutputRCBit());
       break;
+    }
     case kArchStoreWithWriteBarrier: {
       RecordWriteMode mode =
           static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
@@ -1713,11 +1714,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
     case kPPC_Cmp32:
       ASSEMBLE_COMPARE(cmpw, cmplw);
       break;
-#if V8_TARGET_ARCH_PPC64
     case kPPC_Cmp64:
       ASSEMBLE_COMPARE(cmp, cmpl);
       break;
-#endif
     case kPPC_CmpDouble:
       ASSEMBLE_FLOAT_COMPARE(fcmpu);
       break;
@@ -1866,8 +1865,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
     case kPPC_DoubleToInt32:
     case kPPC_DoubleToUint32:
 #if !V8_TARGET_ARCH_PPC64
-      __ ConvertDoubleToInt32NoPPC64(i.InputDoubleRegister(0), i.OutputRegister());
-    break;
+    {
+      Register scratch = kScratchReg;
+      __ ConvertDoubleToInt32NoPPC64(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
+      __ TestIfInt32(scratch,  i.OutputRegister(), r0);
+      break;
+    }
 #endif
     case kPPC_DoubleToInt64: {
 #if V8_TARGET_ARCH_PPC64
diff --git a/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc b/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
index 2aa1c398..eac9794d 100644
--- a/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
+++ b/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
@@ -317,6 +317,7 @@ void InstructionSelector::VisitStore(Node* node) {
       case MachineRepresentation::kTaggedSigned:   // Fall through.
       case MachineRepresentation::kTaggedPointer:  // Fall through.
       case MachineRepresentation::kTagged:         // Fall through.
+        mode = kInt16Imm_4ByteAligned;
 #endif
       case MachineRepresentation::kWord32:
         opcode = kPPC_StoreWord32;
@@ -1483,13 +1484,11 @@ void VisitWord32Compare(InstructionSelector* selector, Node* node,
   VisitWordCompare(selector, node, kPPC_Cmp32, cont, false, mode);
 }
 
-#if V8_TARGET_ARCH_PPC64
 void VisitWord64Compare(InstructionSelector* selector, Node* node,
                         FlagsContinuation* cont) {
   ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm);
   VisitWordCompare(selector, node, kPPC_Cmp64, cont, false, mode);
 }
-#endif
 
 // Shared routine for multiple float32 compare operations.
 void VisitFloat32Compare(InstructionSelector* selector, Node* node,
@@ -1543,7 +1542,6 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
       case IrOpcode::kUint32LessThanOrEqual:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitWord32Compare(this, value, cont);
-#if V8_TARGET_ARCH_PPC64
       case IrOpcode::kWord64Equal:
         cont->OverwriteAndNegateIfEqual(kEqual);
         return VisitWord64Compare(this, value, cont);
@@ -1559,7 +1557,6 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
       case IrOpcode::kUint64LessThanOrEqual:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitWord64Compare(this, value, cont);
-#endif
       case IrOpcode::kFloat32Equal:
         cont->OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat32Compare(this, value, cont);
@@ -1569,7 +1566,6 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
       case IrOpcode::kFloat32LessThanOrEqual:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitFloat32Compare(this, value, cont);
-#if V8_TARGET_ARCH_PPC64
       case IrOpcode::kFloat64Equal:
         cont->OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat64Compare(this, value, cont);
@@ -1579,7 +1575,6 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
       case IrOpcode::kFloat64LessThanOrEqual:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitFloat64Compare(this, value, cont);
-#endif
       case IrOpcode::kProjection:
         // Check if this is the overflow output projection of an
         // <Operation>WithOverflow node.
@@ -1634,7 +1629,6 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
 // case IrOpcode::kWord32Shl:
 // case IrOpcode::kWord32Shr:
 // case IrOpcode::kWord32Ror:
-#if V8_TARGET_ARCH_PPC64
       case IrOpcode::kInt64Sub:
         return VisitWord64Compare(this, value, cont);
       case IrOpcode::kWord64And:
@@ -1649,7 +1643,6 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
 // case IrOpcode::kWord64Shl:
 // case IrOpcode::kWord64Shr:
 // case IrOpcode::kWord64Ror:
-#endif
       case IrOpcode::kStackPointerGreaterThan:
         cont->OverwriteAndNegateIfEqual(kStackPointerGreaterThanCondition);
         return VisitStackPointerGreaterThan(value, cont);
@@ -1722,7 +1715,6 @@ void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
   VisitWord32Compare(this, node, &cont);
 }
 
-#if V8_TARGET_ARCH_PPC64
 void InstructionSelector::VisitWord64Equal(Node* const node) {
   FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
   VisitWord64Compare(this, node, &cont);
@@ -1749,7 +1741,6 @@ void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
       FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
   VisitWord64Compare(this, node, &cont);
 }
-#endif
 
 void InstructionSelector::VisitInt32MulWithOverflow(Node* node) {
   if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
-- 
2.20.1

