Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Unified Diff: src/compiler/s390/code-generator-s390.cc

Issue 1762743002: S390: Initial impl of turbofan compiler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/instruction-codes.h ('k') | src/compiler/s390/instruction-codes-s390.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/s390/code-generator-s390.cc
diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/s390/code-generator-s390.cc
similarity index 55%
copy from src/compiler/ppc/code-generator-ppc.cc
copy to src/compiler/s390/code-generator-s390.cc
index 6bf0a7e80a75a59c7f1e0a0d618c6411a707c7d7..0b687210707cc3ca68d8d7d74eff6001831059ad 100644
--- a/src/compiler/ppc/code-generator-ppc.cc
+++ b/src/compiler/s390/code-generator-s390.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
+// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,7 +9,7 @@
#include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h"
-#include "src/ppc/macro-assembler-ppc.h"
+#include "src/s390/macro-assembler-s390.h"
namespace v8 {
namespace internal {
@@ -17,31 +17,16 @@ namespace compiler {
#define __ masm()->
+#define kScratchReg ip
-#define kScratchReg r11
-
-
-// Adds PPC-specific methods to convert InstructionOperands.
-class PPCOperandConverter final : public InstructionOperandConverter {
+// Adds S390-specific methods to convert InstructionOperands.
+class S390OperandConverter final : public InstructionOperandConverter {
public:
- PPCOperandConverter(CodeGenerator* gen, Instruction* instr)
+ S390OperandConverter(CodeGenerator* gen, Instruction* instr)
: InstructionOperandConverter(gen, instr) {}
size_t OutputCount() { return instr_->OutputCount(); }
- RCBit OutputRCBit() const {
- switch (instr_->flags_mode()) {
- case kFlags_branch:
- case kFlags_deoptimize:
- case kFlags_set:
- return SetRC;
- case kFlags_none:
- return LeaveRC;
- }
- UNREACHABLE();
- return LeaveRC;
- }
-
bool CompareLogical() const {
switch (instr_->flags_condition()) {
case kUnsignedLessThan:
@@ -68,7 +53,7 @@ class PPCOperandConverter final : public InstructionOperandConverter {
return Operand(
isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
case Constant::kInt64:
-#if V8_TARGET_ARCH_PPC64
+#if V8_TARGET_ARCH_S390X
return Operand(constant.ToInt64());
#endif
case Constant::kExternalReference:
@@ -110,12 +95,10 @@ class PPCOperandConverter final : public InstructionOperandConverter {
}
};
-
-static inline bool HasRegisterInput(Instruction* instr, size_t index) {
+static inline bool HasRegisterInput(Instruction* instr, int index) {
return instr->InputAt(index)->IsRegister();
}
-
namespace {
class OutOfLineLoadNAN32 final : public OutOfLineCode {
@@ -132,7 +115,6 @@ class OutOfLineLoadNAN32 final : public OutOfLineCode {
DoubleRegister const result_;
};
-
class OutOfLineLoadNAN64 final : public OutOfLineCode {
public:
OutOfLineLoadNAN64(CodeGenerator* gen, DoubleRegister result)
@@ -147,19 +129,17 @@ class OutOfLineLoadNAN64 final : public OutOfLineCode {
DoubleRegister const result_;
};
-
class OutOfLineLoadZero final : public OutOfLineCode {
public:
OutOfLineLoadZero(CodeGenerator* gen, Register result)
: OutOfLineCode(gen), result_(result) {}
- void Generate() final { __ li(result_, Operand::Zero()); }
+ void Generate() final { __ LoadImmP(result_, Operand::Zero()); }
private:
Register const result_;
};
-
class OutOfLineRecordWrite final : public OutOfLineCode {
public:
OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset,
@@ -199,23 +179,21 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
SaveFPRegsMode const save_fp_mode =
frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
if (!frame()->needs_frame()) {
- // We need to save and restore lr if the frame was elided.
- __ mflr(scratch1_);
- __ Push(scratch1_);
+ // We need to save and restore r14 if the frame was elided.
+ __ Push(r14);
}
RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
remembered_set_action, save_fp_mode);
if (offset_.is(no_reg)) {
- __ addi(scratch1_, object_, Operand(offset_immediate_));
+ __ AddP(scratch1_, object_, Operand(offset_immediate_));
} else {
DCHECK_EQ(0, offset_immediate_);
- __ add(scratch1_, object_, offset_);
+ __ AddP(scratch1_, object_, offset_);
}
__ CallStub(&stub);
if (!frame()->needs_frame()) {
- // We need to save and restore lr if the frame was elided.
- __ Pop(scratch1_);
- __ mtlr(scratch1_);
+ // We need to save and restore r14 if the frame was elided.
+ __ Pop(r14);
}
}
@@ -229,7 +207,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
RecordWriteMode const mode_;
};
-
Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
switch (condition) {
case kEqual:
@@ -249,16 +226,16 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
case kUnsignedGreaterThan:
return gt;
case kOverflow:
- // Overflow checked for add/sub only.
+ // Overflow checked for AddP/SubP only.
switch (op) {
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Add:
- case kPPC_Sub:
+#if V8_TARGET_ARCH_S390X
+ case kS390_Add:
+ case kS390_Sub:
return lt;
#endif
- case kPPC_AddWithOverflow32:
- case kPPC_SubWithOverflow32:
-#if V8_TARGET_ARCH_PPC64
+ case kS390_AddWithOverflow32:
+ case kS390_SubWithOverflow32:
+#if V8_TARGET_ARCH_S390X
return ne;
#else
return lt;
@@ -269,14 +246,14 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
break;
case kNotOverflow:
switch (op) {
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Add:
- case kPPC_Sub:
+#if V8_TARGET_ARCH_S390X
+ case kS390_Add:
+ case kS390_Sub:
return ge;
#endif
- case kPPC_AddWithOverflow32:
- case kPPC_SubWithOverflow32:
-#if V8_TARGET_ARCH_PPC64
+ case kS390_AddWithOverflow32:
+ case kS390_SubWithOverflow32:
+#if V8_TARGET_ARCH_S390X
return eq;
#else
return ge;
@@ -294,20 +271,17 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
} // namespace
-#define ASSEMBLE_FLOAT_UNOP_RC(asm_instr) \
- do { \
- __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
- i.OutputRCBit()); \
+#define ASSEMBLE_FLOAT_UNOP(asm_instr) \
+ do { \
+ __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
} while (0)
-
-#define ASSEMBLE_FLOAT_BINOP_RC(asm_instr) \
+#define ASSEMBLE_FLOAT_BINOP(asm_instr) \
do { \
__ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
- i.InputDoubleRegister(1), i.OutputRCBit()); \
+ i.InputDoubleRegister(1)); \
} while (0)
-
#define ASSEMBLE_BINOP(asm_instr_reg, asm_instr_imm) \
do { \
if (HasRegisterInput(instr, 1)) { \
@@ -319,31 +293,17 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
} \
} while (0)
-
-#define ASSEMBLE_BINOP_RC(asm_instr_reg, asm_instr_imm) \
+#define ASSEMBLE_BINOP_INT(asm_instr_reg, asm_instr_imm) \
do { \
if (HasRegisterInput(instr, 1)) { \
__ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \
- i.InputRegister(1), i.OutputRCBit()); \
- } else { \
- __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \
- i.InputImmediate(1), i.OutputRCBit()); \
- } \
- } while (0)
-
-
-#define ASSEMBLE_BINOP_INT_RC(asm_instr_reg, asm_instr_imm) \
- do { \
- if (HasRegisterInput(instr, 1)) { \
- __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \
- i.InputRegister(1), i.OutputRCBit()); \
+ i.InputRegister(1)); \
} else { \
__ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \
- i.InputInt32(1), i.OutputRCBit()); \
+ i.InputInt32(1)); \
} \
} while (0)
-
#define ASSEMBLE_ADD_WITH_OVERFLOW() \
do { \
if (HasRegisterInput(instr, 1)) { \
@@ -355,7 +315,6 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
} \
} while (0)
-
#define ASSEMBLE_SUB_WITH_OVERFLOW() \
do { \
if (HasRegisterInput(instr, 1)) { \
@@ -367,63 +326,56 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
} \
} while (0)
-
-#if V8_TARGET_ARCH_PPC64
-#define ASSEMBLE_ADD_WITH_OVERFLOW32() \
- do { \
- ASSEMBLE_BINOP(add, addi); \
- __ TestIfInt32(i.OutputRegister(), r0, cr0); \
+#if V8_TARGET_ARCH_S390X
+#define ASSEMBLE_ADD_WITH_OVERFLOW32() \
+ do { \
+ ASSEMBLE_BINOP(AddP, AddP); \
+ __ TestIfInt32(i.OutputRegister(), r0); \
} while (0)
-
-#define ASSEMBLE_SUB_WITH_OVERFLOW32() \
- do { \
- ASSEMBLE_BINOP(sub, subi); \
- __ TestIfInt32(i.OutputRegister(), r0, cr0); \
+#define ASSEMBLE_SUB_WITH_OVERFLOW32() \
+ do { \
+ ASSEMBLE_BINOP(SubP, SubP); \
+ __ TestIfInt32(i.OutputRegister(), r0); \
} while (0)
#else
#define ASSEMBLE_ADD_WITH_OVERFLOW32 ASSEMBLE_ADD_WITH_OVERFLOW
#define ASSEMBLE_SUB_WITH_OVERFLOW32 ASSEMBLE_SUB_WITH_OVERFLOW
#endif
-
-#define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \
- do { \
- const CRegister cr = cr0; \
- if (HasRegisterInput(instr, 1)) { \
- if (i.CompareLogical()) { \
- __ cmpl_instr(i.InputRegister(0), i.InputRegister(1), cr); \
- } else { \
- __ cmp_instr(i.InputRegister(0), i.InputRegister(1), cr); \
- } \
- } else { \
- if (i.CompareLogical()) { \
- __ cmpl_instr##i(i.InputRegister(0), i.InputImmediate(1), cr); \
- } else { \
- __ cmp_instr##i(i.InputRegister(0), i.InputImmediate(1), cr); \
- } \
- } \
- DCHECK_EQ(SetRC, i.OutputRCBit()); \
+#define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \
+ do { \
+ if (HasRegisterInput(instr, 1)) { \
+ if (i.CompareLogical()) { \
+ __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \
+ } else { \
+ __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \
+ } \
+ } else { \
+ if (i.CompareLogical()) { \
+ __ cmpl_instr(i.InputRegister(0), i.InputImmediate(1)); \
+ } else { \
+ __ cmp_instr(i.InputRegister(0), i.InputImmediate(1)); \
+ } \
+ } \
} while (0)
-
-#define ASSEMBLE_FLOAT_COMPARE(cmp_instr) \
- do { \
- const CRegister cr = cr0; \
- __ cmp_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1), cr); \
- DCHECK_EQ(SetRC, i.OutputRCBit()); \
- } while (0)
-
-
-#define ASSEMBLE_MODULO(div_instr, mul_instr) \
+#define ASSEMBLE_FLOAT_COMPARE(cmp_instr) \
do { \
- const Register scratch = kScratchReg; \
- __ div_instr(scratch, i.InputRegister(0), i.InputRegister(1)); \
- __ mul_instr(scratch, scratch, i.InputRegister(1)); \
- __ sub(i.OutputRegister(), i.InputRegister(0), scratch, LeaveOE, \
- i.OutputRCBit()); \
+ __ cmp_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1); \
} while (0)
+// Divide instruction dr will implicity use register pair
+// r0 & r1 below.
+// R0:R1 = R1 / divisor - R0 remainder
+// Copy remainder to output reg
+#define ASSEMBLE_MODULO(div_instr, shift_instr) \
+ do { \
+ __ LoadRR(r0, i.InputRegister(0)); \
+ __ shift_instr(r0, Operand(32)); \
+ __ div_instr(r0, i.InputRegister(1)); \
+ __ ltr(i.OutputRegister(), r0); \
+ } while (0)
#define ASSEMBLE_FLOAT_MODULO() \
do { \
@@ -434,154 +386,116 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
__ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), \
0, 2); \
__ MovFromFloatResult(i.OutputDoubleRegister()); \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
} while (0)
-
-#define ASSEMBLE_FLOAT_MAX(scratch_reg) \
- do { \
- __ fsub(scratch_reg, i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
- __ fsel(i.OutputDoubleRegister(), scratch_reg, i.InputDoubleRegister(0), \
- i.InputDoubleRegister(1)); \
+#define ASSEMBLE_FLOAT_MAX(double_scratch_reg, general_scratch_reg) \
+ do { \
+ Label ge, done; \
+ __ cdbr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
+ __ bge(&ge, Label::kNear); \
+ __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); \
+ __ b(&done, Label::kNear); \
+ __ bind(&ge); \
+ __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
+ __ bind(&done); \
} while (0)
-
-#define ASSEMBLE_FLOAT_MIN(scratch_reg) \
- do { \
- __ fsub(scratch_reg, i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
- __ fsel(i.OutputDoubleRegister(), scratch_reg, i.InputDoubleRegister(1), \
- i.InputDoubleRegister(0)); \
+#define ASSEMBLE_FLOAT_MIN(double_scratch_reg, general_scratch_reg) \
+ do { \
+ Label ge, done; \
+ __ cdbr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
+ __ bge(&ge, Label::kNear); \
+ __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
+ __ b(&done, Label::kNear); \
+ __ bind(&ge); \
+ __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); \
+ __ bind(&done); \
} while (0)
-
-#define ASSEMBLE_LOAD_FLOAT(asm_instr, asm_instrx) \
+// Only MRI mode for these instructions available
+#define ASSEMBLE_LOAD_FLOAT(asm_instr) \
do { \
DoubleRegister result = i.OutputDoubleRegister(); \
AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode); \
- if (mode == kMode_MRI) { \
- __ asm_instr(result, operand); \
- } else { \
- __ asm_instrx(result, operand); \
- } \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
+ __ asm_instr(result, operand); \
} while (0)
-
-#define ASSEMBLE_LOAD_INTEGER(asm_instr, asm_instrx) \
- do { \
- Register result = i.OutputRegister(); \
- AddressingMode mode = kMode_None; \
- MemOperand operand = i.MemoryOperand(&mode); \
- if (mode == kMode_MRI) { \
- __ asm_instr(result, operand); \
- } else { \
- __ asm_instrx(result, operand); \
- } \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
+#define ASSEMBLE_LOAD_INTEGER(asm_instr) \
+ do { \
+ Register result = i.OutputRegister(); \
+ AddressingMode mode = kMode_None; \
+ MemOperand operand = i.MemoryOperand(&mode); \
+ __ asm_instr(result, operand); \
} while (0)
-
#define ASSEMBLE_STORE_FLOAT32() \
do { \
size_t index = 0; \
AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode, &index); \
DoubleRegister value = i.InputDoubleRegister(index); \
- __ frsp(kScratchDoubleReg, value); \
- if (mode == kMode_MRI) { \
- __ stfs(kScratchDoubleReg, operand); \
- } else { \
- __ stfsx(kScratchDoubleReg, operand); \
- } \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
+ __ StoreFloat32(value, operand); \
} while (0)
-
#define ASSEMBLE_STORE_DOUBLE() \
do { \
size_t index = 0; \
AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode, &index); \
DoubleRegister value = i.InputDoubleRegister(index); \
- if (mode == kMode_MRI) { \
- __ stfd(value, operand); \
- } else { \
- __ stfdx(value, operand); \
- } \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
+ __ StoreDouble(value, operand); \
} while (0)
-
-#define ASSEMBLE_STORE_INTEGER(asm_instr, asm_instrx) \
+#define ASSEMBLE_STORE_INTEGER(asm_instr) \
do { \
size_t index = 0; \
AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode, &index); \
Register value = i.InputRegister(index); \
- if (mode == kMode_MRI) { \
- __ asm_instr(value, operand); \
- } else { \
- __ asm_instrx(value, operand); \
- } \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
+ __ asm_instr(value, operand); \
} while (0)
-
// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
-#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, asm_instrx, width) \
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, width) \
do { \
DoubleRegister result = i.OutputDoubleRegister(); \
size_t index = 0; \
AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode, index); \
- DCHECK_EQ(kMode_MRR, mode); \
Register offset = operand.rb(); \
- __ extsw(offset, offset); \
+ __ lgfr(offset, offset); \
if (HasRegisterInput(instr, 2)) { \
- __ cmplw(offset, i.InputRegister(2)); \
+ __ CmpLogical32(offset, i.InputRegister(2)); \
} else { \
- __ cmplwi(offset, i.InputImmediate(2)); \
+ __ CmpLogical32(offset, i.InputImmediate(2)); \
} \
auto ool = new (zone()) OutOfLineLoadNAN##width(this, result); \
__ bge(ool->entry()); \
- if (mode == kMode_MRI) { \
- __ asm_instr(result, operand); \
- } else { \
- __ asm_instrx(result, operand); \
- } \
+ __ asm_instr(result, operand); \
__ bind(ool->exit()); \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
} while (0)
-
// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
-#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr, asm_instrx) \
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
do { \
Register result = i.OutputRegister(); \
size_t index = 0; \
AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode, index); \
- DCHECK_EQ(kMode_MRR, mode); \
Register offset = operand.rb(); \
- __ extsw(offset, offset); \
+ __ lgfr(offset, offset); \
if (HasRegisterInput(instr, 2)) { \
- __ cmplw(offset, i.InputRegister(2)); \
+ __ CmpLogical32(offset, i.InputRegister(2)); \
} else { \
- __ cmplwi(offset, i.InputImmediate(2)); \
+ __ CmpLogical32(offset, i.InputImmediate(2)); \
} \
auto ool = new (zone()) OutOfLineLoadZero(this, result); \
__ bge(ool->entry()); \
- if (mode == kMode_MRI) { \
- __ asm_instr(result, operand); \
- } else { \
- __ asm_instrx(result, operand); \
- } \
+ __ asm_instr(result, operand); \
__ bind(ool->exit()); \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
} while (0)
-
// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
#define ASSEMBLE_CHECKED_STORE_FLOAT32() \
do { \
@@ -589,27 +503,19 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
size_t index = 0; \
AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode, index); \
- DCHECK_EQ(kMode_MRR, mode); \
Register offset = operand.rb(); \
- __ extsw(offset, offset); \
+ __ lgfr(offset, offset); \
if (HasRegisterInput(instr, 2)) { \
- __ cmplw(offset, i.InputRegister(2)); \
+ __ CmpLogical32(offset, i.InputRegister(2)); \
} else { \
- __ cmplwi(offset, i.InputImmediate(2)); \
+ __ CmpLogical32(offset, i.InputImmediate(2)); \
} \
__ bge(&done); \
DoubleRegister value = i.InputDoubleRegister(3); \
- __ frsp(kScratchDoubleReg, value); \
- if (mode == kMode_MRI) { \
- __ stfs(kScratchDoubleReg, operand); \
- } else { \
- __ stfsx(kScratchDoubleReg, operand); \
- } \
+ __ StoreFloat32(value, operand); \
__ bind(&done); \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
} while (0)
-
// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
#define ASSEMBLE_CHECKED_STORE_DOUBLE() \
do { \
@@ -619,64 +525,50 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
MemOperand operand = i.MemoryOperand(&mode, index); \
DCHECK_EQ(kMode_MRR, mode); \
Register offset = operand.rb(); \
- __ extsw(offset, offset); \
+ __ lgfr(offset, offset); \
if (HasRegisterInput(instr, 2)) { \
- __ cmplw(offset, i.InputRegister(2)); \
+ __ CmpLogical32(offset, i.InputRegister(2)); \
} else { \
- __ cmplwi(offset, i.InputImmediate(2)); \
+ __ CmpLogical32(offset, i.InputImmediate(2)); \
} \
__ bge(&done); \
DoubleRegister value = i.InputDoubleRegister(3); \
- if (mode == kMode_MRI) { \
- __ stfd(value, operand); \
- } else { \
- __ stfdx(value, operand); \
- } \
+ __ StoreDouble(value, operand); \
__ bind(&done); \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
} while (0)
-
// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
-#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr, asm_instrx) \
- do { \
- Label done; \
- size_t index = 0; \
- AddressingMode mode = kMode_None; \
- MemOperand operand = i.MemoryOperand(&mode, index); \
- DCHECK_EQ(kMode_MRR, mode); \
- Register offset = operand.rb(); \
- __ extsw(offset, offset); \
- if (HasRegisterInput(instr, 2)) { \
- __ cmplw(offset, i.InputRegister(2)); \
- } else { \
- __ cmplwi(offset, i.InputImmediate(2)); \
- } \
- __ bge(&done); \
- Register value = i.InputRegister(3); \
- if (mode == kMode_MRI) { \
- __ asm_instr(value, operand); \
- } else { \
- __ asm_instrx(value, operand); \
- } \
- __ bind(&done); \
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
+ do { \
+ Label done; \
+ size_t index = 0; \
+ AddressingMode mode = kMode_None; \
+ MemOperand operand = i.MemoryOperand(&mode, index); \
+ Register offset = operand.rb(); \
+ __ lgfr(offset, offset); \
+ if (HasRegisterInput(instr, 2)) { \
+ __ CmpLogical32(offset, i.InputRegister(2)); \
+ } else { \
+ __ CmpLogical32(offset, i.InputImmediate(2)); \
+ } \
+ __ bge(&done); \
+ Register value = i.InputRegister(3); \
+ __ asm_instr(value, operand); \
+ __ bind(&done); \
} while (0)
-
void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
if (sp_slot_delta > 0) {
- __ Add(sp, sp, sp_slot_delta * kPointerSize, r0);
+ __ AddP(sp, sp, Operand(sp_slot_delta * kPointerSize));
}
frame_access_state()->SetFrameAccessToDefault();
}
-
void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
if (sp_slot_delta < 0) {
- __ Add(sp, sp, sp_slot_delta * kPointerSize, r0);
+ __ AddP(sp, sp, Operand(sp_slot_delta * kPointerSize));
frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
}
if (frame()->needs_frame()) {
@@ -685,19 +577,16 @@ void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
frame_access_state()->SetFrameAccessToSP();
}
-
// Assembles an instruction after register allocation, producing machine code.
void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
- PPCOperandConverter i(this, instr);
+ S390OperandConverter i(this, instr);
ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode());
switch (opcode) {
case kArchCallCodeObject: {
- v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
- masm());
EnsureSpaceForLazyDeopt();
if (HasRegisterInput(instr, 0)) {
- __ addi(ip, i.InputRegister(0),
+ __ AddP(ip, i.InputRegister(0),
Operand(Code::kHeaderSize - kHeapObjectTag));
__ Call(ip);
} else {
@@ -705,7 +594,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
RelocInfo::CODE_TARGET);
}
RecordCallPosition(instr);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
frame_access_state()->ClearSPDelta();
break;
}
@@ -713,7 +601,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
AssembleDeconstructActivationRecord(stack_param_delta);
if (HasRegisterInput(instr, 0)) {
- __ addi(ip, i.InputRegister(0),
+ __ AddP(ip, i.InputRegister(0),
Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(ip);
} else {
@@ -723,26 +611,22 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
RelocInfo::CODE_TARGET);
}
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
frame_access_state()->ClearSPDelta();
break;
}
case kArchCallJSFunction: {
- v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
- masm());
EnsureSpaceForLazyDeopt();
Register func = i.InputRegister(0);
if (FLAG_debug_code) {
// Check the function's context matches the context argument.
__ LoadP(kScratchReg,
FieldMemOperand(func, JSFunction::kContextOffset));
- __ cmp(cp, kScratchReg);
+ __ CmpP(cp, kScratchReg);
__ Assert(eq, kWrongFunctionContext);
}
__ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
__ Call(ip);
RecordCallPosition(instr);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
frame_access_state()->ClearSPDelta();
break;
}
@@ -752,14 +636,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
// Check the function's context matches the context argument.
__ LoadP(kScratchReg,
FieldMemOperand(func, JSFunction::kContextOffset));
- __ cmp(cp, kScratchReg);
+ __ CmpP(cp, kScratchReg);
__ Assert(eq, kWrongFunctionContext);
}
int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
AssembleDeconstructActivationRecord(stack_param_delta);
__ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
__ Jump(ip);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
frame_access_state()->ClearSPDelta();
break;
}
@@ -788,20 +671,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
case kArchJmp:
AssembleArchJump(i.InputRpo(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kArchLookupSwitch:
AssembleArchLookupSwitch(instr);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kArchTableSwitch:
AssembleArchTableSwitch(instr);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kArchNop:
case kArchThrowTerminator:
// don't emit code for nops.
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kArchDeoptimize: {
int deopt_state_id =
@@ -813,27 +692,23 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
case kArchRet:
AssembleReturn();
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kArchStackPointer:
- __ mr(i.OutputRegister(), sp);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ __ LoadRR(i.OutputRegister(), sp);
break;
case kArchFramePointer:
- __ mr(i.OutputRegister(), fp);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ __ LoadRR(i.OutputRegister(), fp);
break;
case kArchParentFramePointer:
if (frame_access_state()->frame()->needs_frame()) {
__ LoadP(i.OutputRegister(), MemOperand(fp, 0));
} else {
- __ mr(i.OutputRegister(), fp);
+ __ LoadRR(i.OutputRegister(), fp);
}
break;
case kArchTruncateDoubleToI:
// TODO(mbrandy): move slow call to stub out of line.
__ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kArchStoreWithWriteBarrier: {
RecordWriteMode mode =
@@ -856,7 +731,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
Register offset(i.InputRegister(1));
ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
- __ StorePX(value, MemOperand(object, offset));
+ __ StoreP(value, MemOperand(object, offset));
}
__ CheckPageFlag(object, scratch0,
MemoryChunk::kPointersFromHereAreInterestingMask, ne,
@@ -867,591 +742,768 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kArchStackSlot: {
FrameOffset offset =
frame_access_state()->GetFrameOffset(i.InputInt32(0));
- __ addi(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp,
+ __ AddP(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp,
Operand(offset.offset()));
break;
}
- case kPPC_And:
- if (HasRegisterInput(instr, 1)) {
- __ and_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- i.OutputRCBit());
- } else {
- __ andi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
- }
+ case kS390_And:
+ ASSEMBLE_BINOP(AndP, AndP);
+ break;
+ case kS390_AndComplement:
+ __ NotP(i.InputRegister(1));
+ __ AndP(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+ break;
+ case kS390_Or:
+ ASSEMBLE_BINOP(OrP, OrP);
+ break;
+ case kS390_OrComplement:
+ __ NotP(i.InputRegister(1));
+ __ OrP(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
break;
- case kPPC_AndComplement:
- __ andc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- i.OutputRCBit());
+ case kS390_Xor:
+ ASSEMBLE_BINOP(XorP, XorP);
break;
- case kPPC_Or:
+ case kS390_ShiftLeft32:
if (HasRegisterInput(instr, 1)) {
- __ orx(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- i.OutputRCBit());
+ if (i.OutputRegister().is(i.InputRegister(1))) {
+ __ LoadRR(kScratchReg, i.InputRegister(1));
+ __ ShiftLeft(i.OutputRegister(), i.InputRegister(0), kScratchReg);
+ } else {
+ ASSEMBLE_BINOP(ShiftLeft, ShiftLeft);
+ }
} else {
- __ ori(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ ASSEMBLE_BINOP(ShiftLeft, ShiftLeft);
}
+#if V8_TARGET_ARCH_S390X
+ __ lgfr(i.OutputRegister(0), i.OutputRegister(0));
+#endif
break;
- case kPPC_OrComplement:
- __ orc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- i.OutputRCBit());
+#if V8_TARGET_ARCH_S390X
+ case kS390_ShiftLeft64:
+ ASSEMBLE_BINOP(sllg, sllg);
break;
- case kPPC_Xor:
+#endif
+ case kS390_ShiftRight32:
if (HasRegisterInput(instr, 1)) {
- __ xor_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- i.OutputRCBit());
+ if (i.OutputRegister().is(i.InputRegister(1))) {
+ __ LoadRR(kScratchReg, i.InputRegister(1));
+ __ ShiftRight(i.OutputRegister(), i.InputRegister(0), kScratchReg);
+ } else {
+ ASSEMBLE_BINOP(ShiftRight, ShiftRight);
+ }
} else {
- __ xori(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ ASSEMBLE_BINOP(ShiftRight, ShiftRight);
}
- break;
- case kPPC_ShiftLeft32:
- ASSEMBLE_BINOP_RC(slw, slwi);
- break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_ShiftLeft64:
- ASSEMBLE_BINOP_RC(sld, sldi);
- break;
+#if V8_TARGET_ARCH_S390X
+ __ lgfr(i.OutputRegister(0), i.OutputRegister(0));
#endif
- case kPPC_ShiftRight32:
- ASSEMBLE_BINOP_RC(srw, srwi);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_ShiftRight64:
- ASSEMBLE_BINOP_RC(srd, srdi);
+#if V8_TARGET_ARCH_S390X
+ case kS390_ShiftRight64:
+ ASSEMBLE_BINOP(srlg, srlg);
break;
#endif
- case kPPC_ShiftRightAlg32:
- ASSEMBLE_BINOP_INT_RC(sraw, srawi);
+ case kS390_ShiftRightAlg32:
+ if (HasRegisterInput(instr, 1)) {
+ if (i.OutputRegister().is(i.InputRegister(1))) {
+ __ LoadRR(kScratchReg, i.InputRegister(1));
+ __ ShiftRightArith(i.OutputRegister(), i.InputRegister(0),
+ kScratchReg);
+ } else {
+ ASSEMBLE_BINOP(ShiftRightArith, ShiftRightArith);
+ }
+ } else {
+ ASSEMBLE_BINOP(ShiftRightArith, ShiftRightArith);
+ }
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_ShiftRightAlg64:
- ASSEMBLE_BINOP_INT_RC(srad, sradi);
+#if V8_TARGET_ARCH_S390X
+ case kS390_ShiftRightAlg64:
+ ASSEMBLE_BINOP(srag, srag);
break;
#endif
- case kPPC_RotRight32:
+ case kS390_RotRight32:
if (HasRegisterInput(instr, 1)) {
- __ subfic(kScratchReg, i.InputRegister(1), Operand(32));
- __ rotlw(i.OutputRegister(), i.InputRegister(0), kScratchReg,
- i.OutputRCBit());
+ __ LoadComplementRR(kScratchReg, i.InputRegister(1));
+ __ rll(i.OutputRegister(), i.InputRegister(0), kScratchReg);
} else {
- int sh = i.InputInt32(1);
- __ rotrwi(i.OutputRegister(), i.InputRegister(0), sh, i.OutputRCBit());
+ __ rll(i.OutputRegister(), i.InputRegister(0),
+ Operand(32 - i.InputInt32(1)));
}
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_RotRight64:
+#if V8_TARGET_ARCH_S390X
+ case kS390_RotRight64:
if (HasRegisterInput(instr, 1)) {
- __ subfic(kScratchReg, i.InputRegister(1), Operand(64));
- __ rotld(i.OutputRegister(), i.InputRegister(0), kScratchReg,
- i.OutputRCBit());
+ __ LoadComplementRR(kScratchReg, i.InputRegister(1));
+ __ rll(i.OutputRegister(), i.InputRegister(0), kScratchReg,
+ Operand(32));
+ __ lgfr(i.OutputRegister(), i.OutputRegister());
} else {
- int sh = i.InputInt32(1);
- __ rotrdi(i.OutputRegister(), i.InputRegister(0), sh, i.OutputRCBit());
+ UNIMPLEMENTED(); // Not implemented for now
}
break;
#endif
- case kPPC_Not:
- __ notx(i.OutputRegister(), i.InputRegister(0), i.OutputRCBit());
- break;
- case kPPC_RotLeftAndMask32:
- __ rlwinm(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
- 31 - i.InputInt32(2), 31 - i.InputInt32(3), i.OutputRCBit());
- break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_RotLeftAndClear64:
- __ rldic(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
- 63 - i.InputInt32(2), i.OutputRCBit());
+ case kS390_Not:
+ __ LoadRR(i.OutputRegister(), i.InputRegister(0));
+ __ NotP(i.OutputRegister());
+ break;
+ case kS390_RotLeftAndMask32:
+ if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) {
+ int shiftAmount = i.InputInt32(1);
+ int endBit = 63 - i.InputInt32(3);
+ int startBit = 63 - i.InputInt32(2);
+ __ rll(i.OutputRegister(), i.InputRegister(0), Operand(shiftAmount));
+ __ risbg(i.OutputRegister(), i.OutputRegister(), Operand(startBit),
+ Operand(endBit), Operand::Zero(), true);
+ } else {
+ UNIMPLEMENTED();
+ }
break;
- case kPPC_RotLeftAndClearLeft64:
- __ rldicl(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
- 63 - i.InputInt32(2), i.OutputRCBit());
+#if V8_TARGET_ARCH_S390X
+ case kS390_RotLeftAndClear64:
+ UNIMPLEMENTED(); // Find correct instruction
+ break;
+ case kS390_RotLeftAndClearLeft64:
+ if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) {
+ int shiftAmount = i.InputInt32(1);
+ int endBit = 63;
+ int startBit = 63 - i.InputInt32(2);
+ __ risbg(i.OutputRegister(), i.InputRegister(0), Operand(startBit),
+ Operand(endBit), Operand(shiftAmount), true);
+ } else {
+ UNIMPLEMENTED();
+ }
break;
- case kPPC_RotLeftAndClearRight64:
- __ rldicr(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
- 63 - i.InputInt32(2), i.OutputRCBit());
+ case kS390_RotLeftAndClearRight64:
+ if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) {
+ int shiftAmount = i.InputInt32(1);
+ int endBit = 63 - i.InputInt32(2);
+ int startBit = 0;
+ __ risbg(i.OutputRegister(), i.InputRegister(0), Operand(startBit),
+ Operand(endBit), Operand(shiftAmount), true);
+ } else {
+ UNIMPLEMENTED();
+ }
break;
#endif
- case kPPC_Add:
-#if V8_TARGET_ARCH_PPC64
+ case kS390_Add:
+#if V8_TARGET_ARCH_S390X
if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
ASSEMBLE_ADD_WITH_OVERFLOW();
} else {
#endif
- if (HasRegisterInput(instr, 1)) {
- __ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- LeaveOE, i.OutputRCBit());
- } else {
- __ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
- }
-#if V8_TARGET_ARCH_PPC64
+ ASSEMBLE_BINOP(AddP, AddP);
+#if V8_TARGET_ARCH_S390X
}
#endif
break;
- case kPPC_AddWithOverflow32:
+ case kS390_AddWithOverflow32:
ASSEMBLE_ADD_WITH_OVERFLOW32();
break;
- case kPPC_AddDouble:
- ASSEMBLE_FLOAT_BINOP_RC(fadd);
+ case kS390_AddFloat:
+ // Ensure we don't clobber right/InputReg(1)
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ ASSEMBLE_FLOAT_UNOP(aebr);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0)))
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ aebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
+ break;
+ case kS390_AddDouble:
+ // Ensure we don't clobber right/InputReg(1)
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ ASSEMBLE_FLOAT_UNOP(adbr);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0)))
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ adbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
break;
- case kPPC_Sub:
-#if V8_TARGET_ARCH_PPC64
+ case kS390_Sub:
+#if V8_TARGET_ARCH_S390X
if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
ASSEMBLE_SUB_WITH_OVERFLOW();
} else {
#endif
- if (HasRegisterInput(instr, 1)) {
- __ sub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- LeaveOE, i.OutputRCBit());
- } else {
- __ subi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
- }
-#if V8_TARGET_ARCH_PPC64
+ ASSEMBLE_BINOP(SubP, SubP);
+#if V8_TARGET_ARCH_S390X
}
#endif
break;
- case kPPC_SubWithOverflow32:
+ case kS390_SubWithOverflow32:
ASSEMBLE_SUB_WITH_OVERFLOW32();
break;
- case kPPC_SubDouble:
- ASSEMBLE_FLOAT_BINOP_RC(fsub);
+ case kS390_SubFloat:
+ // OutputDoubleReg() = i.InputDoubleRegister(0) - i.InputDoubleRegister(1)
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ __ ldr(kScratchDoubleReg, i.InputDoubleRegister(1));
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ sebr(i.OutputDoubleRegister(), kScratchDoubleReg);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) {
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ }
+ __ sebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
break;
- case kPPC_Mul32:
- __ mullw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- LeaveOE, i.OutputRCBit());
+ case kS390_SubDouble:
+ // OutputDoubleReg() = i.InputDoubleRegister(0) - i.InputDoubleRegister(1)
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ __ ldr(kScratchDoubleReg, i.InputDoubleRegister(1));
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ sdbr(i.OutputDoubleRegister(), kScratchDoubleReg);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) {
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ }
+ __ sdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Mul64:
- __ mulld(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- LeaveOE, i.OutputRCBit());
+ case kS390_Mul32:
+#if V8_TARGET_ARCH_S390X
+ case kS390_Mul64:
+#endif
+ __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+ break;
+ case kS390_MulHigh32:
+ __ LoadRR(r1, i.InputRegister(0));
+ __ mr_z(r0, i.InputRegister(1));
+ __ LoadRR(i.OutputRegister(), r0);
+ break;
+ case kS390_MulHighU32:
+ __ LoadRR(r1, i.InputRegister(0));
+ __ mlr(r0, i.InputRegister(1));
+ __ LoadRR(i.OutputRegister(), r0);
+ break;
+ case kS390_MulFloat:
+ // Ensure we don't clobber right
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ ASSEMBLE_FLOAT_UNOP(meebr);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0)))
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ meebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
+ break;
+ case kS390_MulDouble:
+ // Ensure we don't clobber right
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ ASSEMBLE_FLOAT_UNOP(mdbr);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0)))
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ mdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
break;
+#if V8_TARGET_ARCH_S390X
+ case kS390_Div64:
#endif
- case kPPC_MulHigh32:
- __ mulhw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- i.OutputRCBit());
+ case kS390_Div32:
+ __ LoadRR(r0, i.InputRegister(0));
+ __ srda(r0, Operand(32));
+ __ dr(r0, i.InputRegister(1));
+ __ ltr(i.OutputRegister(), r1);
+ break;
+#if V8_TARGET_ARCH_S390X
+ case kS390_DivU64:
+ __ LoadRR(r1, i.InputRegister(0));
+ __ LoadImmP(r0, Operand::Zero());
+ __ dlgr(r0, i.InputRegister(1)); // R0:R1 = R1 / divisor -
+ __ ltgr(i.OutputRegister(), r1); // Copy remainder to output reg
break;
- case kPPC_MulHighU32:
- __ mulhwu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
- i.OutputRCBit());
+#endif
+ case kS390_DivU32:
+ __ LoadRR(r0, i.InputRegister(0));
+ __ srdl(r0, Operand(32));
+ __ dlr(r0, i.InputRegister(1)); // R0:R1 = R1 / divisor -
+ __ ltr(i.OutputRegister(), r1); // Copy remainder to output reg
+ break;
+
+ case kS390_DivFloat:
+ // InputDoubleRegister(1)=InputDoubleRegister(0)/InputDoubleRegister(1)
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ __ ldr(kScratchDoubleReg, i.InputDoubleRegister(1));
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ debr(i.OutputDoubleRegister(), kScratchDoubleReg);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0)))
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ debr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
break;
- case kPPC_MulDouble:
- ASSEMBLE_FLOAT_BINOP_RC(fmul);
+ case kS390_DivDouble:
+ // InputDoubleRegister(1)=InputDoubleRegister(0)/InputDoubleRegister(1)
+ if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
+ __ ldr(kScratchDoubleReg, i.InputDoubleRegister(1));
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ ddbr(i.OutputDoubleRegister(), kScratchDoubleReg);
+ } else {
+ if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0)))
+ __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ ddbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+ }
break;
- case kPPC_Div32:
- __ divw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_Mod32:
+ ASSEMBLE_MODULO(dr, srda);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Div64:
- __ divd(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_ModU32:
+ ASSEMBLE_MODULO(dlr, srdl);
break;
-#endif
- case kPPC_DivU32:
- __ divwu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+#if V8_TARGET_ARCH_S390X
+ case kS390_Mod64:
+ ASSEMBLE_MODULO(dr, srda);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_DivU64:
- __ divdu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_ModU64:
+ ASSEMBLE_MODULO(dlr, srdl);
break;
#endif
- case kPPC_DivDouble:
- ASSEMBLE_FLOAT_BINOP_RC(fdiv);
+ case kS390_AbsFloat:
+ __ lpebr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
- case kPPC_Mod32:
- ASSEMBLE_MODULO(divw, mullw);
+ case kS390_SqrtFloat:
+ ASSEMBLE_FLOAT_UNOP(sqebr);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Mod64:
- ASSEMBLE_MODULO(divd, mulld);
+ case kS390_FloorFloat:
+ // ASSEMBLE_FLOAT_UNOP_RC(frim);
+ __ FloatFloor32(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+ kScratchReg);
break;
-#endif
- case kPPC_ModU32:
- ASSEMBLE_MODULO(divwu, mullw);
+ case kS390_CeilFloat:
+ __ FloatCeiling32(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+ kScratchReg, kScratchDoubleReg);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_ModU64:
- ASSEMBLE_MODULO(divdu, mulld);
+ case kS390_TruncateFloat:
+ __ fiebra(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+ v8::internal::Assembler::FIDBRA_ROUND_TOWARD_0);
break;
-#endif
- case kPPC_ModDouble:
- // TODO(bmeurer): We should really get rid of this special instruction,
- // and generate a CallAddress instruction instead.
+ // Double operations
+ case kS390_ModDouble:
ASSEMBLE_FLOAT_MODULO();
break;
- case kPPC_Neg:
- __ neg(i.OutputRegister(), i.InputRegister(0), LeaveOE, i.OutputRCBit());
- break;
- case kPPC_MaxDouble:
- ASSEMBLE_FLOAT_MAX(kScratchDoubleReg);
- break;
- case kPPC_MinDouble:
- ASSEMBLE_FLOAT_MIN(kScratchDoubleReg);
+ case kS390_Neg:
+ __ LoadComplementRR(i.OutputRegister(), i.InputRegister(0));
break;
- case kPPC_AbsDouble:
- ASSEMBLE_FLOAT_UNOP_RC(fabs);
+ case kS390_MaxDouble:
+ ASSEMBLE_FLOAT_MAX(kScratchDoubleReg, kScratchReg);
break;
- case kPPC_SqrtDouble:
- ASSEMBLE_FLOAT_UNOP_RC(fsqrt);
+ case kS390_MinDouble:
+ ASSEMBLE_FLOAT_MIN(kScratchDoubleReg, kScratchReg);
break;
- case kPPC_FloorDouble:
- ASSEMBLE_FLOAT_UNOP_RC(frim);
+ case kS390_AbsDouble:
+ __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
- case kPPC_CeilDouble:
- ASSEMBLE_FLOAT_UNOP_RC(frip);
+ case kS390_SqrtDouble:
+ ASSEMBLE_FLOAT_UNOP(sqdbr);
break;
- case kPPC_TruncateDouble:
- ASSEMBLE_FLOAT_UNOP_RC(friz);
+ case kS390_FloorDouble:
+ __ FloatFloor64(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+ kScratchReg);
break;
- case kPPC_RoundDouble:
- ASSEMBLE_FLOAT_UNOP_RC(frin);
+ case kS390_CeilDouble:
+ __ FloatCeiling64(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+ kScratchReg, kScratchDoubleReg);
break;
- case kPPC_NegDouble:
- ASSEMBLE_FLOAT_UNOP_RC(fneg);
+ case kS390_TruncateDouble:
+ __ fidbra(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+ v8::internal::Assembler::FIDBRA_ROUND_TOWARD_0);
break;
- case kPPC_Cntlz32:
- __ cntlzw_(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_RoundDouble:
+ __ fidbra(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+ v8::internal::Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Cntlz64:
- __ cntlzd_(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_NegDouble:
+ ASSEMBLE_FLOAT_UNOP(lcdbr);
break;
+ case kS390_Cntlz32: {
+ __ llgfr(i.OutputRegister(), i.InputRegister(0));
+ __ flogr(r0, i.OutputRegister());
+ __ LoadRR(i.OutputRegister(), r0);
+ __ SubP(i.OutputRegister(), Operand(32));
+ } break;
+#if V8_TARGET_ARCH_S390X
+ case kS390_Cntlz64: {
+ __ flogr(r0, i.InputRegister(0));
+ __ LoadRR(i.OutputRegister(), r0);
+ } break;
#endif
- case kPPC_Popcnt32:
- __ popcntw(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_Popcnt32:
+ __ Popcnt32(i.OutputRegister(), i.InputRegister(0));
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Popcnt64:
- __ popcntd(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+#if V8_TARGET_ARCH_S390X
+ case kS390_Popcnt64:
+ __ Popcnt64(i.OutputRegister(), i.InputRegister(0));
break;
#endif
- case kPPC_Cmp32:
- ASSEMBLE_COMPARE(cmpw, cmplw);
+ case kS390_Cmp32:
+ ASSEMBLE_COMPARE(Cmp32, CmpLogical32);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Cmp64:
- ASSEMBLE_COMPARE(cmp, cmpl);
+#if V8_TARGET_ARCH_S390X
+ case kS390_Cmp64:
+ ASSEMBLE_COMPARE(CmpP, CmpLogicalP);
break;
#endif
- case kPPC_CmpDouble:
- ASSEMBLE_FLOAT_COMPARE(fcmpu);
+ case kS390_CmpFloat:
+ __ cebr(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
break;
- case kPPC_Tst32:
+ case kS390_CmpDouble:
+ __ cdbr(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+ break;
+ case kS390_Tst32:
if (HasRegisterInput(instr, 1)) {
- __ and_(r0, i.InputRegister(0), i.InputRegister(1), i.OutputRCBit());
+ __ AndP(r0, i.InputRegister(0), i.InputRegister(1));
} else {
- __ andi(r0, i.InputRegister(0), i.InputImmediate(1));
+ __ AndP(r0, i.InputRegister(0), i.InputImmediate(1));
}
-#if V8_TARGET_ARCH_PPC64
- __ extsw(r0, r0, i.OutputRCBit());
+#if V8_TARGET_ARCH_S390X
+ // TODO(john.yan): use ltgfr here.
+ __ lgfr(r0, r0);
+ __ LoadAndTestP(r0, r0);
#endif
- DCHECK_EQ(SetRC, i.OutputRCBit());
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_Tst64:
+#if V8_TARGET_ARCH_S390X
+ case kS390_Tst64:
if (HasRegisterInput(instr, 1)) {
- __ and_(r0, i.InputRegister(0), i.InputRegister(1), i.OutputRCBit());
+ __ AndP(r0, i.InputRegister(0), i.InputRegister(1));
} else {
- __ andi(r0, i.InputRegister(0), i.InputImmediate(1));
+ __ AndP(r0, i.InputRegister(0), i.InputImmediate(1));
}
- DCHECK_EQ(SetRC, i.OutputRCBit());
break;
#endif
- case kPPC_Push:
+ case kS390_Push:
if (instr->InputAt(0)->IsDoubleRegister()) {
- __ stfdu(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
+ __ StoreDouble(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
+ __ lay(sp, MemOperand(sp, -kDoubleSize));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
} else {
__ Push(i.InputRegister(0));
frame_access_state()->IncreaseSPDelta(1);
}
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_PushFrame: {
+ case kS390_PushFrame: {
int num_slots = i.InputInt32(1);
if (instr->InputAt(0)->IsDoubleRegister()) {
- __ stfdu(i.InputDoubleRegister(0),
- MemOperand(sp, -num_slots * kPointerSize));
+ __ StoreDouble(i.InputDoubleRegister(0),
+ MemOperand(sp, -num_slots * kPointerSize));
} else {
- __ StorePU(i.InputRegister(0),
- MemOperand(sp, -num_slots * kPointerSize));
+ __ StoreP(i.InputRegister(0),
+ MemOperand(sp, -num_slots * kPointerSize));
}
+ __ lay(sp, MemOperand(sp, -num_slots * kPointerSize));
break;
}
- case kPPC_StoreToStackSlot: {
+ case kS390_StoreToStackSlot: {
int slot = i.InputInt32(1);
if (instr->InputAt(0)->IsDoubleRegister()) {
- __ stfd(i.InputDoubleRegister(0), MemOperand(sp, slot * kPointerSize));
+ __ StoreDouble(i.InputDoubleRegister(0),
+ MemOperand(sp, slot * kPointerSize));
} else {
__ StoreP(i.InputRegister(0), MemOperand(sp, slot * kPointerSize));
}
break;
}
- case kPPC_ExtendSignWord8:
- __ extsb(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_ExtendSignWord8:
+#if V8_TARGET_ARCH_S390X
+ __ lgbr(i.OutputRegister(), i.InputRegister(0));
+#else
+ __ lbr(i.OutputRegister(), i.InputRegister(0));
+#endif
break;
- case kPPC_ExtendSignWord16:
- __ extsh(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_ExtendSignWord16:
+#if V8_TARGET_ARCH_S390X
+ __ lghr(i.OutputRegister(), i.InputRegister(0));
+#else
+ __ lhr(i.OutputRegister(), i.InputRegister(0));
+#endif
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_ExtendSignWord32:
- __ extsw(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+#if V8_TARGET_ARCH_S390X
+ case kS390_ExtendSignWord32:
+ __ lgfr(i.OutputRegister(), i.InputRegister(0));
break;
- case kPPC_Uint32ToUint64:
+ case kS390_Uint32ToUint64:
// Zero extend
- __ clrldi(i.OutputRegister(), i.InputRegister(0), Operand(32));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ __ llgfr(i.OutputRegister(), i.InputRegister(0));
break;
- case kPPC_Int64ToInt32:
- __ extsw(i.OutputRegister(), i.InputRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
+ case kS390_Int64ToInt32:
+ // sign extend
+ __ lgfr(i.OutputRegister(), i.InputRegister(0));
break;
- case kPPC_Int64ToFloat32:
+ case kS390_Int64ToFloat32:
__ ConvertInt64ToFloat(i.InputRegister(0), i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_Int64ToDouble:
+ case kS390_Int64ToDouble:
__ ConvertInt64ToDouble(i.InputRegister(0), i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_Uint64ToFloat32:
+ case kS390_Uint64ToFloat32:
__ ConvertUnsignedInt64ToFloat(i.InputRegister(0),
i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_Uint64ToDouble:
+ case kS390_Uint64ToDouble:
__ ConvertUnsignedInt64ToDouble(i.InputRegister(0),
i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
#endif
- case kPPC_Int32ToFloat32:
+ case kS390_Int32ToFloat32:
__ ConvertIntToFloat(i.InputRegister(0), i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_Int32ToDouble:
+ case kS390_Int32ToDouble:
__ ConvertIntToDouble(i.InputRegister(0), i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_Uint32ToFloat32:
+ case kS390_Uint32ToFloat32:
__ ConvertUnsignedIntToFloat(i.InputRegister(0),
i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_Uint32ToDouble:
+ case kS390_Uint32ToDouble:
__ ConvertUnsignedIntToDouble(i.InputRegister(0),
i.OutputDoubleRegister());
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_DoubleToInt32:
- case kPPC_DoubleToUint32:
- case kPPC_DoubleToInt64: {
-#if V8_TARGET_ARCH_PPC64
+ case kS390_DoubleToInt32:
+ case kS390_DoubleToUint32:
+ case kS390_DoubleToInt64: {
+#if V8_TARGET_ARCH_S390X
bool check_conversion =
- (opcode == kPPC_DoubleToInt64 && i.OutputCount() > 1);
- if (check_conversion) {
- __ mtfsb0(VXCVI); // clear FPSCR:VXCVI bit
- }
+ (opcode == kS390_DoubleToInt64 && i.OutputCount() > 1);
#endif
__ ConvertDoubleToInt64(i.InputDoubleRegister(0),
-#if !V8_TARGET_ARCH_PPC64
+#if !V8_TARGET_ARCH_S390X
kScratchReg,
#endif
i.OutputRegister(0), kScratchDoubleReg);
-#if V8_TARGET_ARCH_PPC64
+#if V8_TARGET_ARCH_S390X
if (check_conversion) {
- // Set 2nd output to zero if conversion fails.
- 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
- if (CpuFeatures::IsSupported(ISELECT)) {
- __ li(i.OutputRegister(1), Operand(1));
- __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit);
- } else {
- __ li(i.OutputRegister(1), Operand::Zero());
- __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit);
- __ li(i.OutputRegister(1), Operand(1));
- }
+ Label conversion_done;
+ __ LoadImmP(i.OutputRegister(1), Operand::Zero());
+ __ b(Condition(1), &conversion_done); // special case
+ __ LoadImmP(i.OutputRegister(1), Operand(1));
+ __ bind(&conversion_done);
}
#endif
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
}
-#if V8_TARGET_ARCH_PPC64
- case kPPC_DoubleToUint64: {
+ case kS390_Float32ToInt32: {
bool check_conversion = (i.OutputCount() > 1);
+ __ ConvertFloat32ToInt32(i.InputDoubleRegister(0), i.OutputRegister(0),
+ kScratchDoubleReg);
if (check_conversion) {
- __ mtfsb0(VXCVI); // clear FPSCR:VXCVI bit
+ Label conversion_done;
+ __ LoadImmP(i.OutputRegister(1), Operand::Zero());
+ __ b(Condition(1), &conversion_done); // special case
+ __ LoadImmP(i.OutputRegister(1), Operand(1));
+ __ bind(&conversion_done);
}
+ break;
+ }
+ case kS390_Float32ToUint32: {
+ bool check_conversion = (i.OutputCount() > 1);
+ __ ConvertFloat32ToUnsignedInt32(i.InputDoubleRegister(0),
+ i.OutputRegister(0), kScratchDoubleReg);
+ if (check_conversion) {
+ Label conversion_done;
+ __ LoadImmP(i.OutputRegister(1), Operand::Zero());
+ __ b(Condition(1), &conversion_done); // special case
+ __ LoadImmP(i.OutputRegister(1), Operand(1));
+ __ bind(&conversion_done);
+ }
+ break;
+ }
+#if V8_TARGET_ARCH_S390X
+ case kS390_Float32ToUint64: {
+ bool check_conversion = (i.OutputCount() > 1);
+ __ ConvertFloat32ToUnsignedInt64(i.InputDoubleRegister(0),
+ i.OutputRegister(0), kScratchDoubleReg);
+ if (check_conversion) {
+ Label conversion_done;
+ __ LoadImmP(i.OutputRegister(1), Operand::Zero());
+ __ b(Condition(1), &conversion_done); // special case
+ __ LoadImmP(i.OutputRegister(1), Operand(1));
+ __ bind(&conversion_done);
+ }
+ break;
+ }
+#endif
+ case kS390_Float32ToInt64: {
+#if V8_TARGET_ARCH_S390X
+ bool check_conversion =
+ (opcode == kS390_Float32ToInt64 && i.OutputCount() > 1);
+#endif
+ __ ConvertFloat32ToInt64(i.InputDoubleRegister(0),
+#if !V8_TARGET_ARCH_S390X
+ kScratchReg,
+#endif
+ i.OutputRegister(0), kScratchDoubleReg);
+#if V8_TARGET_ARCH_S390X
+ if (check_conversion) {
+ Label conversion_done;
+ __ LoadImmP(i.OutputRegister(1), Operand::Zero());
+ __ b(Condition(1), &conversion_done); // special case
+ __ LoadImmP(i.OutputRegister(1), Operand(1));
+ __ bind(&conversion_done);
+ }
+#endif
+ break;
+ }
+#if V8_TARGET_ARCH_S390X
+ case kS390_DoubleToUint64: {
+ bool check_conversion = (i.OutputCount() > 1);
__ ConvertDoubleToUnsignedInt64(i.InputDoubleRegister(0),
i.OutputRegister(0), kScratchDoubleReg);
if (check_conversion) {
- // Set 2nd output to zero if conversion fails.
- 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
- if (CpuFeatures::IsSupported(ISELECT)) {
- __ li(i.OutputRegister(1), Operand(1));
- __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit);
- } else {
- __ li(i.OutputRegister(1), Operand::Zero());
- __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit);
- __ li(i.OutputRegister(1), Operand(1));
- }
+ Label conversion_done;
+ __ LoadImmP(i.OutputRegister(1), Operand::Zero());
+ __ b(Condition(1), &conversion_done); // special case
+ __ LoadImmP(i.OutputRegister(1), Operand(1));
+ __ bind(&conversion_done);
}
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
}
#endif
- case kPPC_DoubleToFloat32:
- ASSEMBLE_FLOAT_UNOP_RC(frsp);
- break;
- case kPPC_Float32ToDouble:
- // Nothing to do.
- __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
- break;
- case kPPC_DoubleExtractLowWord32:
- __ MovDoubleLowToInt(i.OutputRegister(), i.InputDoubleRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
- break;
- case kPPC_DoubleExtractHighWord32:
- __ MovDoubleHighToInt(i.OutputRegister(), i.InputDoubleRegister(0));
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
- break;
- case kPPC_DoubleInsertLowWord32:
- __ InsertDoubleLow(i.OutputDoubleRegister(), i.InputRegister(1), r0);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
- break;
- case kPPC_DoubleInsertHighWord32:
- __ InsertDoubleHigh(i.OutputDoubleRegister(), i.InputRegister(1), r0);
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
- break;
- case kPPC_DoubleConstruct:
-#if V8_TARGET_ARCH_PPC64
- __ MovInt64ComponentsToDouble(i.OutputDoubleRegister(),
- i.InputRegister(0), i.InputRegister(1), r0);
+ case kS390_DoubleToFloat32:
+ __ ledbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ break;
+ case kS390_Float32ToDouble:
+ __ ldebr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ break;
+ case kS390_DoubleExtractLowWord32:
+ // TODO(john.yan): this can cause problem when interrupting,
+ // use freg->greg instruction
+ __ stdy(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
+ __ LoadlW(i.OutputRegister(),
+ MemOperand(sp, -kDoubleSize + Register::kMantissaOffset));
+ break;
+ case kS390_DoubleExtractHighWord32:
+ // TODO(john.yan): this can cause problem when interrupting,
+ // use freg->greg instruction
+ __ stdy(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
+ __ LoadlW(i.OutputRegister(),
+ MemOperand(sp, -kDoubleSize + Register::kExponentOffset));
+ break;
+ case kS390_DoubleInsertLowWord32:
+ __ InsertDoubleLow(i.OutputDoubleRegister(), i.InputRegister(1));
+ break;
+ case kS390_DoubleInsertHighWord32:
+ __ InsertDoubleHigh(i.OutputDoubleRegister(), i.InputRegister(1));
+ break;
+ case kS390_DoubleConstruct:
+// TODO(john.yan): this can cause problem when interrupting,
+// use greg->freg instruction
+#if V8_TARGET_LITTLE_ENDIAN
+ __ StoreW(i.InputRegister(0), MemOperand(sp, -kDoubleSize / 2));
+ __ StoreW(i.InputRegister(1), MemOperand(sp, -kDoubleSize));
+#else
+ __ StoreW(i.InputRegister(1), MemOperand(sp, -kDoubleSize / 2));
+ __ StoreW(i.InputRegister(0), MemOperand(sp, -kDoubleSize));
+#endif
+ __ ldy(i.OutputDoubleRegister(), MemOperand(sp, -kDoubleSize));
+ break;
+ case kS390_LoadWordS8:
+ ASSEMBLE_LOAD_INTEGER(LoadlB);
+#if V8_TARGET_ARCH_S390X
+ __ lgbr(i.OutputRegister(), i.OutputRegister());
#else
- __ MovInt64ToDouble(i.OutputDoubleRegister(), i.InputRegister(0),
- i.InputRegister(1));
+ __ lbr(i.OutputRegister(), i.OutputRegister());
#endif
- DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
- case kPPC_BitcastFloat32ToInt32:
+ case kS390_BitcastFloat32ToInt32:
__ MovFloatToInt(i.OutputRegister(), i.InputDoubleRegister(0));
break;
- case kPPC_BitcastInt32ToFloat32:
+ case kS390_BitcastInt32ToFloat32:
__ MovIntToFloat(i.OutputDoubleRegister(), i.InputRegister(0));
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_BitcastDoubleToInt64:
+#if V8_TARGET_ARCH_S390X
+ case kS390_BitcastDoubleToInt64:
__ MovDoubleToInt64(i.OutputRegister(), i.InputDoubleRegister(0));
break;
- case kPPC_BitcastInt64ToDouble:
+ case kS390_BitcastInt64ToDouble:
__ MovInt64ToDouble(i.OutputDoubleRegister(), i.InputRegister(0));
break;
#endif
- case kPPC_LoadWordU8:
- ASSEMBLE_LOAD_INTEGER(lbz, lbzx);
- break;
- case kPPC_LoadWordS8:
- ASSEMBLE_LOAD_INTEGER(lbz, lbzx);
- __ extsb(i.OutputRegister(), i.OutputRegister());
+ case kS390_LoadWordU8:
+ ASSEMBLE_LOAD_INTEGER(LoadlB);
break;
- case kPPC_LoadWordU16:
- ASSEMBLE_LOAD_INTEGER(lhz, lhzx);
+ case kS390_LoadWordU16:
+ ASSEMBLE_LOAD_INTEGER(LoadLogicalHalfWordP);
break;
- case kPPC_LoadWordS16:
- ASSEMBLE_LOAD_INTEGER(lha, lhax);
+ case kS390_LoadWordS16:
+ ASSEMBLE_LOAD_INTEGER(LoadHalfWordP);
break;
- case kPPC_LoadWordS32:
- ASSEMBLE_LOAD_INTEGER(lwa, lwax);
+ case kS390_LoadWordS32:
+ ASSEMBLE_LOAD_INTEGER(LoadW);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_LoadWord64:
- ASSEMBLE_LOAD_INTEGER(ld, ldx);
+#if V8_TARGET_ARCH_S390X
+ case kS390_LoadWord64:
+ ASSEMBLE_LOAD_INTEGER(lg);
break;
#endif
- case kPPC_LoadFloat32:
- ASSEMBLE_LOAD_FLOAT(lfs, lfsx);
+ case kS390_LoadFloat32:
+ ASSEMBLE_LOAD_FLOAT(LoadFloat32);
break;
- case kPPC_LoadDouble:
- ASSEMBLE_LOAD_FLOAT(lfd, lfdx);
+ case kS390_LoadDouble:
+ ASSEMBLE_LOAD_FLOAT(LoadDouble);
break;
- case kPPC_StoreWord8:
- ASSEMBLE_STORE_INTEGER(stb, stbx);
+ case kS390_StoreWord8:
+ ASSEMBLE_STORE_INTEGER(StoreByte);
break;
- case kPPC_StoreWord16:
- ASSEMBLE_STORE_INTEGER(sth, sthx);
+ case kS390_StoreWord16:
+ ASSEMBLE_STORE_INTEGER(StoreHalfWord);
break;
- case kPPC_StoreWord32:
- ASSEMBLE_STORE_INTEGER(stw, stwx);
+ case kS390_StoreWord32:
+ ASSEMBLE_STORE_INTEGER(StoreW);
break;
-#if V8_TARGET_ARCH_PPC64
- case kPPC_StoreWord64:
- ASSEMBLE_STORE_INTEGER(std, stdx);
+#if V8_TARGET_ARCH_S390X
+ case kS390_StoreWord64:
+ ASSEMBLE_STORE_INTEGER(StoreP);
break;
#endif
- case kPPC_StoreFloat32:
+ case kS390_StoreFloat32:
ASSEMBLE_STORE_FLOAT32();
break;
- case kPPC_StoreDouble:
+ case kS390_StoreDouble:
ASSEMBLE_STORE_DOUBLE();
break;
case kCheckedLoadInt8:
- ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx);
- __ extsb(i.OutputRegister(), i.OutputRegister());
+ ASSEMBLE_CHECKED_LOAD_INTEGER(LoadlB);
+#if V8_TARGET_ARCH_S390X
+ __ lgbr(i.OutputRegister(), i.OutputRegister());
+#else
+ __ lbr(i.OutputRegister(), i.OutputRegister());
+#endif
break;
case kCheckedLoadUint8:
- ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx);
+ ASSEMBLE_CHECKED_LOAD_INTEGER(LoadlB);
break;
case kCheckedLoadInt16:
- ASSEMBLE_CHECKED_LOAD_INTEGER(lha, lhax);
+ ASSEMBLE_CHECKED_LOAD_INTEGER(LoadHalfWordP);
break;
case kCheckedLoadUint16:
- ASSEMBLE_CHECKED_LOAD_INTEGER(lhz, lhzx);
+ ASSEMBLE_CHECKED_LOAD_INTEGER(LoadLogicalHalfWordP);
break;
case kCheckedLoadWord32:
- ASSEMBLE_CHECKED_LOAD_INTEGER(lwa, lwax);
+ ASSEMBLE_CHECKED_LOAD_INTEGER(LoadW);
break;
case kCheckedLoadWord64:
-#if V8_TARGET_ARCH_PPC64
- ASSEMBLE_CHECKED_LOAD_INTEGER(ld, ldx);
+#if V8_TARGET_ARCH_S390X
+ ASSEMBLE_CHECKED_LOAD_INTEGER(LoadP);
#else
UNREACHABLE();
#endif
break;
case kCheckedLoadFloat32:
- ASSEMBLE_CHECKED_LOAD_FLOAT(lfs, lfsx, 32);
+ ASSEMBLE_CHECKED_LOAD_FLOAT(LoadFloat32, 32);
break;
case kCheckedLoadFloat64:
- ASSEMBLE_CHECKED_LOAD_FLOAT(lfd, lfdx, 64);
+ ASSEMBLE_CHECKED_LOAD_FLOAT(LoadDouble, 64);
break;
case kCheckedStoreWord8:
- ASSEMBLE_CHECKED_STORE_INTEGER(stb, stbx);
+ ASSEMBLE_CHECKED_STORE_INTEGER(StoreByte);
break;
case kCheckedStoreWord16:
- ASSEMBLE_CHECKED_STORE_INTEGER(sth, sthx);
+ ASSEMBLE_CHECKED_STORE_INTEGER(StoreHalfWord);
break;
case kCheckedStoreWord32:
- ASSEMBLE_CHECKED_STORE_INTEGER(stw, stwx);
+ ASSEMBLE_CHECKED_STORE_INTEGER(StoreW);
break;
case kCheckedStoreWord64:
-#if V8_TARGET_ARCH_PPC64
- ASSEMBLE_CHECKED_STORE_INTEGER(std, stdx);
+#if V8_TARGET_ARCH_S390X
+ ASSEMBLE_CHECKED_STORE_INTEGER(StoreP);
#else
UNREACHABLE();
#endif
@@ -1468,108 +1520,107 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
} // NOLINT(readability/fn_size)
-
// Assembles branches after an instruction.
void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
- PPCOperandConverter i(this, instr);
+ S390OperandConverter i(this, instr);
Label* tlabel = branch->true_label;
Label* flabel = branch->false_label;
ArchOpcode op = instr->arch_opcode();
FlagsCondition condition = branch->condition;
- CRegister cr = cr0;
Condition cond = FlagsConditionToCondition(condition, op);
- if (op == kPPC_CmpDouble) {
+ if (op == kS390_CmpDouble) {
// check for unordered if necessary
- if (cond == le) {
- __ bunordered(flabel, cr);
- // Unnecessary for eq/lt since only FU bit will be set.
- } else if (cond == gt) {
- __ bunordered(tlabel, cr);
- // Unnecessary for ne/ge since only FU bit will be set.
+ // Branching to flabel/tlabel according to what's expected by tests
+ if (cond == le || cond == eq || cond == lt) {
+ __ bunordered(flabel);
+ } else if (cond == gt || cond == ne || cond == ge) {
+ __ bunordered(tlabel);
}
}
- __ b(cond, tlabel, cr);
+ __ b(cond, tlabel);
if (!branch->fallthru) __ b(flabel); // no fallthru to flabel.
}
-
void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
}
-
// Assembles boolean materializations after an instruction.
void CodeGenerator::AssembleArchBoolean(Instruction* instr,
FlagsCondition condition) {
- PPCOperandConverter i(this, instr);
+ S390OperandConverter i(this, instr);
Label done;
ArchOpcode op = instr->arch_opcode();
- CRegister cr = cr0;
- int reg_value = -1;
+ bool check_unordered = (op == kS390_CmpDouble || kS390_CmpFloat);
+
+ // Overflow checked for add/sub only.
+ DCHECK((condition != kOverflow && condition != kNotOverflow) ||
+ (op == kS390_AddWithOverflow32 || op == kS390_SubWithOverflow32));
// Materialize a full 32-bit 1 or 0 value. The result register is always the
// last output of the instruction.
DCHECK_NE(0u, instr->OutputCount());
Register reg = i.OutputRegister(instr->OutputCount() - 1);
-
Condition cond = FlagsConditionToCondition(condition, op);
- if (op == kPPC_CmpDouble) {
- // check for unordered if necessary
- if (cond == le) {
- reg_value = 0;
- __ li(reg, Operand::Zero());
- __ bunordered(&done, cr);
- } else if (cond == gt) {
- reg_value = 1;
- __ li(reg, Operand(1));
- __ bunordered(&done, cr);
- }
- // Unnecessary for eq/lt & ne/ge since only FU bit will be set.
- }
-
- if (CpuFeatures::IsSupported(ISELECT)) {
- switch (cond) {
- case eq:
- case lt:
- case gt:
- if (reg_value != 1) __ li(reg, Operand(1));
- __ li(kScratchReg, Operand::Zero());
- __ isel(cond, reg, reg, kScratchReg, cr);
- break;
- case ne:
- case ge:
- case le:
- if (reg_value != 1) __ li(reg, Operand(1));
- // r0 implies logical zero in this form
- __ isel(NegateCondition(cond), reg, r0, reg, cr);
- break;
+ switch (cond) {
+ case ne:
+ case ge:
+ case gt:
+ if (check_unordered) {
+ __ LoadImmP(reg, Operand(1));
+ __ LoadImmP(kScratchReg, Operand::Zero());
+ __ bunordered(&done);
+ Label cond_true;
+ __ b(cond, &cond_true, Label::kNear);
+ __ LoadRR(reg, kScratchReg);
+ __ bind(&cond_true);
+ } else {
+ Label cond_true, done_here;
+ __ LoadImmP(reg, Operand(1));
+ __ b(cond, &cond_true, Label::kNear);
+ __ LoadImmP(reg, Operand::Zero());
+ __ bind(&cond_true);
+ }
+ break;
+ case eq:
+ case lt:
+ case le:
+ if (check_unordered) {
+ __ LoadImmP(reg, Operand::Zero());
+ __ LoadImmP(kScratchReg, Operand(1));
+ __ bunordered(&done);
+ Label cond_false;
+ __ b(NegateCondition(cond), &cond_false, Label::kNear);
+ __ LoadRR(reg, kScratchReg);
+ __ bind(&cond_false);
+ } else {
+ __ LoadImmP(reg, Operand::Zero());
+ Label cond_false;
+ __ b(NegateCondition(cond), &cond_false, Label::kNear);
+ __ LoadImmP(reg, Operand(1));
+ __ bind(&cond_false);
+ }
+ break;
default:
UNREACHABLE();
break;
- }
- } else {
- if (reg_value != 0) __ li(reg, Operand::Zero());
- __ b(NegateCondition(cond), &done, cr);
- __ li(reg, Operand(1));
}
__ bind(&done);
}
-
void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
- PPCOperandConverter i(this, instr);
+ S390OperandConverter i(this, instr);
Register input = i.InputRegister(0);
for (size_t index = 2; index < instr->InputCount(); index += 2) {
- __ Cmpi(input, Operand(i.InputInt32(index + 0)), r0);
+ __ CmpP(input, Operand(i.InputInt32(index + 0)));
__ beq(GetLabel(i.InputRpo(index + 1)));
}
AssembleArchJump(i.InputRpo(1));
}
-
void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
- PPCOperandConverter i(this, instr);
+ S390OperandConverter i(this, instr);
Register input = i.InputRegister(0);
int32_t const case_count = static_cast<int32_t>(instr->InputCount() - 2);
Label** cases = zone()->NewArray<Label*>(case_count);
@@ -1577,15 +1628,14 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
cases[index] = GetLabel(i.InputRpo(index + 2));
}
Label* const table = AddJumpTable(cases, case_count);
- __ Cmpli(input, Operand(case_count), r0);
+ __ CmpLogicalP(input, Operand(case_count));
__ bge(GetLabel(i.InputRpo(1)));
- __ mov_label_addr(kScratchReg, table);
- __ ShiftLeftImm(r0, input, Operand(kPointerSizeLog2));
- __ LoadPX(kScratchReg, MemOperand(kScratchReg, r0));
+ __ larl(kScratchReg, table);
+ __ ShiftLeftP(r1, input, Operand(kPointerSizeLog2));
+ __ LoadP(kScratchReg, MemOperand(kScratchReg, r1));
__ Jump(kScratchReg);
}
-
void CodeGenerator::AssembleDeoptimizerCall(
int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
@@ -1596,20 +1646,12 @@ void CodeGenerator::AssembleDeoptimizerCall(
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
}
-
void CodeGenerator::AssemblePrologue() {
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+
if (descriptor->IsCFunctionCall()) {
- __ function_descriptor();
- __ mflr(r0);
- if (FLAG_enable_embedded_constant_pool) {
- __ Push(r0, fp, kConstantPoolRegister);
- // Adjust FP to point to saved FP.
- __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset));
- } else {
- __ Push(r0, fp);
- __ mr(fp, sp);
- }
+ __ Push(r14, fp);
+ __ LoadRR(fp, sp);
} else if (descriptor->IsJSFunctionCall()) {
__ Prologue(this->info()->GeneratePreagedPrologue(), ip);
} else if (frame()->needs_frame()) {
@@ -1643,7 +1685,7 @@ void CodeGenerator::AssemblePrologue() {
stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
}
if (stack_shrink_slots > 0) {
- __ Add(sp, sp, -stack_shrink_slots * kPointerSize, r0);
+ __ lay(sp, MemOperand(sp, -stack_shrink_slots * kPointerSize));
}
// Save callee-saved Double registers.
@@ -1656,10 +1698,7 @@ void CodeGenerator::AssemblePrologue() {
}
// Save callee-saved registers.
- const RegList saves =
- FLAG_enable_embedded_constant_pool
- ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit()
- : descriptor->CalleeSavedRegisters();
+ const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) {
__ MultiPush(saves);
// register save area does not include the fp or constant pool pointer.
@@ -1670,16 +1709,12 @@ void CodeGenerator::AssemblePrologue() {
}
}
-
void CodeGenerator::AssembleReturn() {
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
int pop_count = static_cast<int>(descriptor->StackParameterCount());
// Restore registers.
- const RegList saves =
- FLAG_enable_embedded_constant_pool
- ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit()
- : descriptor->CalleeSavedRegisters();
+ const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) {
__ MultiPop(saves);
}
@@ -1707,10 +1742,9 @@ void CodeGenerator::AssembleReturn() {
__ Ret();
}
-
void CodeGenerator::AssembleMove(InstructionOperand* source,
InstructionOperand* destination) {
- PPCOperandConverter g(this, nullptr);
+ S390OperandConverter g(this, nullptr);
// Dispatch on the source and destination operand kinds. Not all
// combinations are possible.
if (source->IsRegister()) {
@@ -1719,17 +1753,17 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
if (destination->IsRegister()) {
__ Move(g.ToRegister(destination), src);
} else {
- __ StoreP(src, g.ToMemOperand(destination), r0);
+ __ StoreP(src, g.ToMemOperand(destination));
}
} else if (source->IsStackSlot()) {
DCHECK(destination->IsRegister() || destination->IsStackSlot());
MemOperand src = g.ToMemOperand(source);
if (destination->IsRegister()) {
- __ LoadP(g.ToRegister(destination), src, r0);
+ __ LoadP(g.ToRegister(destination), src);
} else {
Register temp = kScratchReg;
__ LoadP(temp, src, r0);
- __ StoreP(temp, g.ToMemOperand(destination), r0);
+ __ StoreP(temp, g.ToMemOperand(destination));
}
} else if (source->IsConstant()) {
Constant src = g.ToConstant(source);
@@ -1768,7 +1802,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
break;
}
case Constant::kRpoNumber:
- UNREACHABLE(); // TODO(dcarney): loading RPO constants on PPC.
+ UNREACHABLE(); // TODO(dcarney): loading RPO constants on S390.
break;
}
if (destination->IsStackSlot()) {
@@ -1780,9 +1814,14 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
: kScratchDoubleReg;
double value = (src.type() == Constant::kFloat32) ? src.ToFloat32()
: src.ToFloat64();
- __ LoadDoubleLiteral(dst, value, kScratchReg);
+ if (src.type() == Constant::kFloat32) {
+ __ LoadFloat32Literal(dst, src.ToFloat32(), kScratchReg);
+ } else {
+ __ LoadDoubleLiteral(dst, value, kScratchReg);
+ }
+
if (destination->IsDoubleStackSlot()) {
- __ StoreDouble(dst, g.ToMemOperand(destination), r0);
+ __ StoreDouble(dst, g.ToMemOperand(destination));
}
}
} else if (source->IsDoubleRegister()) {
@@ -1792,27 +1831,26 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
__ Move(dst, src);
} else {
DCHECK(destination->IsDoubleStackSlot());
- __ StoreDouble(src, g.ToMemOperand(destination), r0);
+ __ StoreDouble(src, g.ToMemOperand(destination));
}
} else if (source->IsDoubleStackSlot()) {
DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
MemOperand src = g.ToMemOperand(source);
if (destination->IsDoubleRegister()) {
- __ LoadDouble(g.ToDoubleRegister(destination), src, r0);
+ __ LoadDouble(g.ToDoubleRegister(destination), src);
} else {
DoubleRegister temp = kScratchDoubleReg;
- __ LoadDouble(temp, src, r0);
- __ StoreDouble(temp, g.ToMemOperand(destination), r0);
+ __ LoadDouble(temp, src);
+ __ StoreDouble(temp, g.ToMemOperand(destination));
}
} else {
UNREACHABLE();
}
}
-
void CodeGenerator::AssembleSwap(InstructionOperand* source,
InstructionOperand* destination) {
- PPCOperandConverter g(this, nullptr);
+ S390OperandConverter g(this, nullptr);
// Dispatch on the source and destination operand kinds. Not all
// combinations are possible.
if (source->IsRegister()) {
@@ -1821,17 +1859,17 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
Register src = g.ToRegister(source);
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
- __ mr(temp, src);
- __ mr(src, dst);
- __ mr(dst, temp);
+ __ LoadRR(temp, src);
+ __ LoadRR(src, dst);
+ __ LoadRR(dst, temp);
} else {
DCHECK(destination->IsStackSlot());
MemOperand dst = g.ToMemOperand(destination);
- __ mr(temp, src);
+ __ LoadRR(temp, src);
__ LoadP(src, dst);
__ StoreP(temp, dst);
}
-#if V8_TARGET_ARCH_PPC64
+#if V8_TARGET_ARCH_S390X
} else if (source->IsStackSlot() || source->IsDoubleStackSlot()) {
#else
} else if (source->IsStackSlot()) {
@@ -1850,27 +1888,28 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
DoubleRegister src = g.ToDoubleRegister(source);
if (destination->IsDoubleRegister()) {
DoubleRegister dst = g.ToDoubleRegister(destination);
- __ fmr(temp, src);
- __ fmr(src, dst);
- __ fmr(dst, temp);
+ __ ldr(temp, src);
+ __ ldr(src, dst);
+ __ ldr(dst, temp);
} else {
DCHECK(destination->IsDoubleStackSlot());
MemOperand dst = g.ToMemOperand(destination);
- __ fmr(temp, src);
- __ lfd(src, dst);
- __ stfd(temp, dst);
+ __ ldr(temp, src);
+ __ LoadDouble(src, dst);
+ __ StoreDouble(temp, dst);
}
-#if !V8_TARGET_ARCH_PPC64
+#if !V8_TARGET_ARCH_S390X
} else if (source->IsDoubleStackSlot()) {
DCHECK(destination->IsDoubleStackSlot());
DoubleRegister temp_0 = kScratchDoubleReg;
DoubleRegister temp_1 = d0;
MemOperand src = g.ToMemOperand(source);
MemOperand dst = g.ToMemOperand(destination);
- __ lfd(temp_0, src);
- __ lfd(temp_1, dst);
- __ stfd(temp_0, dst);
- __ stfd(temp_1, src);
+ // TODO(joransiu): MVC opportunity
+ __ LoadDouble(temp_0, src);
+ __ LoadDouble(temp_1, dst);
+ __ StoreDouble(temp_0, dst);
+ __ StoreDouble(temp_1, src);
#endif
} else {
// No other combinations are possible.
@@ -1878,19 +1917,16 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
}
}
-
void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
for (size_t index = 0; index < target_count; ++index) {
__ emit_label_addr(targets[index]);
}
}
-
void CodeGenerator::AddNopForSmiCodeInlining() {
// We do not insert nops for inlined Smi code.
}
-
void CodeGenerator::EnsureSpaceForLazyDeopt() {
if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
return;
@@ -1901,14 +1937,11 @@ void CodeGenerator::EnsureSpaceForLazyDeopt() {
// instruction for patching the code here.
int current_pc = masm()->pc_offset();
if (current_pc < last_lazy_deopt_pc_ + space_needed) {
- // Block tramoline pool emission for duration of padding.
- v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
- masm());
int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
- DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+ DCHECK_EQ(0, padding_size % 2);
while (padding_size > 0) {
__ nop();
- padding_size -= v8::internal::Assembler::kInstrSize;
+ padding_size -= 2;
}
}
}
« no previous file with comments | « src/compiler/instruction-codes.h ('k') | src/compiler/s390/instruction-codes-s390.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698