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; |
} |
} |
} |