| Index: src/compiler/s390/code-generator-s390.cc
|
| diff --git a/src/compiler/s390/code-generator-s390.cc b/src/compiler/s390/code-generator-s390.cc
|
| index 8e9db3dcb01b3a9696207d421e6751e6c81721e2..ddf68562b861e7c3d0f6c834daab5ca045b08e11 100644
|
| --- a/src/compiler/s390/code-generator-s390.cc
|
| +++ b/src/compiler/s390/code-generator-s390.cc
|
| @@ -135,26 +135,28 @@ static inline bool HasRegisterOutput(Instruction* instr, int index = 0) {
|
| return instr->OutputCount() > 0 && instr->OutputAt(index)->IsRegister();
|
| }
|
|
|
| -static inline bool HasRegisterInput(Instruction* instr, int index) {
|
| - return instr->InputAt(index)->IsRegister();
|
| -}
|
| -
|
| static inline bool HasFPRegisterInput(Instruction* instr, int index) {
|
| return instr->InputAt(index)->IsFPRegister();
|
| }
|
|
|
| -static inline bool HasImmediateInput(Instruction* instr, size_t index) {
|
| - return instr->InputAt(index)->IsImmediate();
|
| +static inline bool HasRegisterInput(Instruction* instr, int index) {
|
| + return instr->InputAt(index)->IsRegister() ||
|
| + HasFPRegisterInput(instr, index);
|
| }
|
|
|
| -static inline bool HasStackSlotInput(Instruction* instr, size_t index) {
|
| - return instr->InputAt(index)->IsStackSlot();
|
| +static inline bool HasImmediateInput(Instruction* instr, size_t index) {
|
| + return instr->InputAt(index)->IsImmediate();
|
| }
|
|
|
| static inline bool HasFPStackSlotInput(Instruction* instr, size_t index) {
|
| return instr->InputAt(index)->IsFPStackSlot();
|
| }
|
|
|
| +static inline bool HasStackSlotInput(Instruction* instr, size_t index) {
|
| + return instr->InputAt(index)->IsStackSlot() ||
|
| + HasFPStackSlotInput(instr, index);
|
| +}
|
| +
|
| namespace {
|
|
|
| class OutOfLineLoadNAN32 final : public OutOfLineCode {
|
| @@ -330,175 +332,177 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
|
| return kNoCondition;
|
| }
|
|
|
| -typedef void (MacroAssembler::*RRTypeInstr)(Register, Register);
|
| -typedef void (MacroAssembler::*RMTypeInstr)(Register, const MemOperand&);
|
| -typedef void (MacroAssembler::*RITypeInstr)(Register, const Operand&);
|
| -typedef void (MacroAssembler::*RRRTypeInstr)(Register, Register, Register);
|
| -typedef void (MacroAssembler::*RRMTypeInstr)(Register, Register,
|
| - const MemOperand&);
|
| -typedef void (MacroAssembler::*RRITypeInstr)(Register, Register,
|
| - const Operand&);
|
| -
|
| -#define CHECK_AND_ZERO_EXT_OUTPUT(num) \
|
| - { \
|
| - CHECK(HasImmediateInput(instr, (num))); \
|
| - int doZeroExt = i.InputInt32(num); \
|
| - if (doZeroExt) masm->LoadlW(i.OutputRegister(), i.OutputRegister()); \
|
| +#define GET_MEMOPERAND32(ret, fi) \
|
| + ([&](int& ret) { \
|
| + AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
|
| + MemOperand mem(r0); \
|
| + if (mode != kMode_None) { \
|
| + size_t first_index = (fi); \
|
| + mem = i.MemoryOperand(&mode, &first_index); \
|
| + ret = first_index; \
|
| + } else { \
|
| + mem = i.InputStackSlot32(fi); \
|
| + } \
|
| + return mem; \
|
| + })(ret)
|
| +
|
| +#define GET_MEMOPERAND(ret, fi) \
|
| + ([&](int& ret) { \
|
| + AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
|
| + MemOperand mem(r0); \
|
| + if (mode != kMode_None) { \
|
| + size_t first_index = (fi); \
|
| + mem = i.MemoryOperand(&mode, &first_index); \
|
| + ret = first_index; \
|
| + } else { \
|
| + mem = i.InputStackSlot(fi); \
|
| + } \
|
| + return mem; \
|
| + })(ret)
|
| +
|
| +#define RRInstr(instr) \
|
| + [&]() { \
|
| + DCHECK(i.OutputRegister().is(i.InputRegister(0))); \
|
| + __ instr(i.OutputRegister(), i.InputRegister(1)); \
|
| + return 2; \
|
| }
|
| +#define RIInstr(instr) \
|
| + [&]() { \
|
| + DCHECK(i.OutputRegister().is(i.InputRegister(0))); \
|
| + __ instr(i.OutputRegister(), i.InputImmediate(1)); \
|
| + return 2; \
|
| + }
|
| +#define RMInstr(instr, GETMEM) \
|
| + [&]() { \
|
| + DCHECK(i.OutputRegister().is(i.InputRegister(0))); \
|
| + int ret = 2; \
|
| + __ instr(i.OutputRegister(), GETMEM(ret, 1)); \
|
| + return ret; \
|
| + }
|
| +#define RM32Instr(instr) RMInstr(instr, GET_MEMOPERAND32)
|
| +#define RM64Instr(instr) RMInstr(instr, GET_MEMOPERAND)
|
|
|
| -void AssembleBinOp(S390OperandConverter& i, MacroAssembler* masm,
|
| - Instruction* instr, RRTypeInstr rr_instr,
|
| - RMTypeInstr rm_instr, RITypeInstr ri_instr) {
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - AddressingMode mode = AddressingModeField::decode(instr->opcode());
|
| - int zeroExtIndex = 2;
|
| - if (mode != kMode_None) {
|
| - size_t first_index = 1;
|
| - MemOperand operand = i.MemoryOperand(&mode, &first_index);
|
| - zeroExtIndex = first_index;
|
| - CHECK(rm_instr != NULL);
|
| - (masm->*rm_instr)(i.OutputRegister(), operand);
|
| - } else if (HasRegisterInput(instr, 1)) {
|
| - (masm->*rr_instr)(i.OutputRegister(), i.InputRegister(1));
|
| - } else if (HasImmediateInput(instr, 1)) {
|
| - (masm->*ri_instr)(i.OutputRegister(), i.InputImmediate(1));
|
| - } else if (HasStackSlotInput(instr, 1)) {
|
| - (masm->*rm_instr)(i.OutputRegister(), i.InputStackSlot32(1));
|
| - } else {
|
| - UNREACHABLE();
|
| +#define RRRInstr(instr) \
|
| + [&]() { \
|
| + __ instr(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); \
|
| + return 2; \
|
| + }
|
| +#define RRIInstr(instr) \
|
| + [&]() { \
|
| + __ instr(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); \
|
| + return 2; \
|
| + }
|
| +#define RRMInstr(instr, GETMEM) \
|
| + [&]() { \
|
| + int ret = 2; \
|
| + __ instr(i.OutputRegister(), i.InputRegister(0), GETMEM(ret, 1)); \
|
| + return ret; \
|
| + }
|
| +#define RRM32Instr(instr) RRMInstr(instr, GET_MEMOPERAND32)
|
| +#define RRM64Instr(instr) RRMInstr(instr, GET_MEMOPERAND)
|
| +
|
| +#define DDInstr(instr) \
|
| + [&]() { \
|
| + DCHECK(i.OutputDoubleRegister().is(i.InputDoubleRegister(0))); \
|
| + __ instr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); \
|
| + return 2; \
|
| }
|
| - CHECK_AND_ZERO_EXT_OUTPUT(zeroExtIndex);
|
| -}
|
|
|
| -void AssembleBinOp(S390OperandConverter& i, MacroAssembler* masm,
|
| - Instruction* instr, RRRTypeInstr rrr_instr,
|
| - RMTypeInstr rm_instr, RITypeInstr ri_instr) {
|
| - AddressingMode mode = AddressingModeField::decode(instr->opcode());
|
| - int zeroExtIndex = 2;
|
| - if (mode != kMode_None) {
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - size_t first_index = 1;
|
| - MemOperand operand = i.MemoryOperand(&mode, &first_index);
|
| - zeroExtIndex = first_index;
|
| - CHECK(rm_instr != NULL);
|
| - (masm->*rm_instr)(i.OutputRegister(), operand);
|
| - } else if (HasRegisterInput(instr, 1)) {
|
| - (masm->*rrr_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputRegister(1));
|
| - } else if (HasImmediateInput(instr, 1)) {
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - (masm->*ri_instr)(i.OutputRegister(), i.InputImmediate(1));
|
| - } else if (HasStackSlotInput(instr, 1)) {
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - (masm->*rm_instr)(i.OutputRegister(), i.InputStackSlot32(1));
|
| - } else {
|
| - UNREACHABLE();
|
| +#define DMInstr(instr) \
|
| + [&]() { \
|
| + DCHECK(i.OutputDoubleRegister().is(i.InputDoubleRegister(0))); \
|
| + int ret = 2; \
|
| + __ instr(i.OutputDoubleRegister(), GET_MEMOPERAND(ret, 1)); \
|
| + return ret; \
|
| }
|
| - CHECK_AND_ZERO_EXT_OUTPUT(zeroExtIndex);
|
| -}
|
|
|
| -void AssembleBinOp(S390OperandConverter& i, MacroAssembler* masm,
|
| - Instruction* instr, RRRTypeInstr rrr_instr,
|
| - RMTypeInstr rm_instr, RRITypeInstr rri_instr) {
|
| - AddressingMode mode = AddressingModeField::decode(instr->opcode());
|
| - int zeroExtIndex = 2;
|
| - if (mode != kMode_None) {
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - size_t first_index = 1;
|
| - MemOperand operand = i.MemoryOperand(&mode, &first_index);
|
| - zeroExtIndex = first_index;
|
| - CHECK(rm_instr != NULL);
|
| - (masm->*rm_instr)(i.OutputRegister(), operand);
|
| - } else if (HasRegisterInput(instr, 1)) {
|
| - (masm->*rrr_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputRegister(1));
|
| - } else if (HasImmediateInput(instr, 1)) {
|
| - (masm->*rri_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputImmediate(1));
|
| - } else if (HasStackSlotInput(instr, 1)) {
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - (masm->*rm_instr)(i.OutputRegister(), i.InputStackSlot32(1));
|
| - } else {
|
| - UNREACHABLE();
|
| +#define DMTInstr(instr) \
|
| + [&]() { \
|
| + DCHECK(i.OutputDoubleRegister().is(i.InputDoubleRegister(0))); \
|
| + int ret = 2; \
|
| + __ instr(i.OutputDoubleRegister(), GET_MEMOPERAND(ret, 1), \
|
| + kScratchDoubleReg); \
|
| + return ret; \
|
| }
|
| - CHECK_AND_ZERO_EXT_OUTPUT(zeroExtIndex);
|
| -}
|
|
|
| -void AssembleBinOp(S390OperandConverter& i, MacroAssembler* masm,
|
| - Instruction* instr, RRRTypeInstr rrr_instr,
|
| - RRMTypeInstr rrm_instr, RRITypeInstr rri_instr) {
|
| - AddressingMode mode = AddressingModeField::decode(instr->opcode());
|
| - int zeroExtIndex = 2;
|
| - if (mode != kMode_None) {
|
| - size_t first_index = 1;
|
| - MemOperand operand = i.MemoryOperand(&mode, &first_index);
|
| - zeroExtIndex = first_index;
|
| - CHECK(rrm_instr != NULL);
|
| - (masm->*rrm_instr)(i.OutputRegister(), i.InputRegister(0), operand);
|
| - } else if (HasRegisterInput(instr, 1)) {
|
| - (masm->*rrr_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputRegister(1));
|
| - } else if (HasImmediateInput(instr, 1)) {
|
| - (masm->*rri_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputImmediate(1));
|
| - } else if (HasStackSlotInput(instr, 1)) {
|
| - (masm->*rrm_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputStackSlot32(1));
|
| - } else {
|
| - UNREACHABLE();
|
| +#define R_MInstr(instr) \
|
| + [&]() { \
|
| + int ret = 2; \
|
| + __ instr(i.OutputRegister(), GET_MEMOPERAND(ret, 0)); \
|
| + return ret; \
|
| }
|
| - CHECK_AND_ZERO_EXT_OUTPUT(zeroExtIndex);
|
| -}
|
|
|
| -void AssembleBinOp(S390OperandConverter& i, MacroAssembler* masm,
|
| - Instruction* instr, RRRTypeInstr rrr_instr,
|
| - RRITypeInstr rri_instr) {
|
| - AddressingMode mode = AddressingModeField::decode(instr->opcode());
|
| - CHECK(mode == kMode_None);
|
| - int zeroExtIndex = 2;
|
| - if (HasRegisterInput(instr, 1)) {
|
| - (masm->*rrr_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputRegister(1));
|
| - } else if (HasImmediateInput(instr, 1)) {
|
| - (masm->*rri_instr)(i.OutputRegister(), i.InputRegister(0),
|
| - i.InputImmediate(1));
|
| - } else {
|
| - UNREACHABLE();
|
| +#define R_DInstr(instr) \
|
| + [&]() { \
|
| + __ instr(i.OutputRegister(), i.InputDoubleRegister(0)); \
|
| + return 2; \
|
| + }
|
| +
|
| +#define D_DInstr(instr) \
|
| + [&]() { \
|
| + __ instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
|
| + return 2; \
|
| + }
|
| +
|
| +#define D_MInstr(instr) \
|
| + [&]() { \
|
| + int ret = 2; \
|
| + __ instr(i.OutputDoubleRegister(), GET_MEMOPERAND(ret, 0)); \
|
| + return ret; \
|
| }
|
| - CHECK_AND_ZERO_EXT_OUTPUT(zeroExtIndex);
|
| +
|
| +#define D_MTInstr(instr) \
|
| + [&]() { \
|
| + int ret = 2; \
|
| + __ instr(i.OutputDoubleRegister(), GET_MEMOPERAND(ret, 0), \
|
| + kScratchDoubleReg); \
|
| + return ret; \
|
| + }
|
| +
|
| +static int nullInstr() {
|
| + UNREACHABLE();
|
| + return -1;
|
| }
|
|
|
| -void AssembleBinOp(S390OperandConverter& i, MacroAssembler* masm,
|
| - Instruction* instr, RRTypeInstr rr_instr,
|
| - RITypeInstr ri_instr) {
|
| +template <int numOfOperand, class RType, class MType, class IType>
|
| +static inline int AssembleOp(Instruction* instr, RType r, MType m, IType i) {
|
| AddressingMode mode = AddressingModeField::decode(instr->opcode());
|
| - CHECK(mode == kMode_None);
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - int zeroExtIndex = 2;
|
| - if (HasRegisterInput(instr, 1)) {
|
| - (masm->*rr_instr)(i.OutputRegister(), i.InputRegister(1));
|
| - } else if (HasImmediateInput(instr, 1)) {
|
| - (masm->*ri_instr)(i.OutputRegister(), i.InputImmediate(1));
|
| + if (mode != kMode_None || HasStackSlotInput(instr, numOfOperand - 1)) {
|
| + return m();
|
| + } else if (HasRegisterInput(instr, numOfOperand - 1)) {
|
| + return r();
|
| + } else if (HasImmediateInput(instr, numOfOperand - 1)) {
|
| + return i();
|
| } else {
|
| UNREACHABLE();
|
| + return -1;
|
| }
|
| - CHECK_AND_ZERO_EXT_OUTPUT(zeroExtIndex);
|
| }
|
|
|
| -#define ASSEMBLE_BIN_OP(instr1, instr2, instr3) \
|
| - AssembleBinOp(i, masm(), instr, &MacroAssembler::instr1, \
|
| - &MacroAssembler::instr2, &MacroAssembler::instr3)
|
| -
|
| -#undef CHECK_AND_ZERO_EXT_OUTPUT
|
| +template <class _RR, class _RM, class _RI>
|
| +static inline int AssembleBinOp(Instruction* instr, _RR _rr, _RM _rm, _RI _ri) {
|
| + return AssembleOp<2>(instr, _rr, _rm, _ri);
|
| +}
|
|
|
| -} // namespace
|
| +template <class _R, class _M, class _I>
|
| +static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) {
|
| + return AssembleOp<1>(instr, _r, _m, _i);
|
| +}
|
|
|
| #define CHECK_AND_ZERO_EXT_OUTPUT(num) \
|
| - { \
|
| - CHECK(HasImmediateInput(instr, (num))); \
|
| - int doZeroExt = i.InputInt32(num); \
|
| + ([&](int index) { \
|
| + DCHECK(HasImmediateInput(instr, (index))); \
|
| + int doZeroExt = i.InputInt32(index); \
|
| if (doZeroExt) __ LoadlW(i.OutputRegister(), i.OutputRegister()); \
|
| - }
|
| + })(num)
|
| +
|
| +#define ASSEMBLE_BIN_OP(_rr, _rm, _ri) AssembleBinOp(instr, _rr, _rm, _ri)
|
| +#define ASSEMBLE_UNARY_OP(_r, _m, _i) AssembleUnaryOp(instr, _r, _m, _i)
|
| +
|
| +#define ASSEMBLE_BIN32_OP(_rr, _rm, _ri) \
|
| + { CHECK_AND_ZERO_EXT_OUTPUT(AssembleBinOp(instr, _rr, _rm, _ri)); }
|
| +
|
| +} // namespace
|
|
|
| #define ASSEMBLE_FLOAT_UNOP(asm_instr) \
|
| do { \
|
| @@ -511,19 +515,6 @@ void AssembleBinOp(S390OperandConverter& i, MacroAssembler* masm,
|
| i.InputDoubleRegister(1)); \
|
| } while (0)
|
|
|
| -#define ASSEMBLE_BINOP(asm_instr) \
|
| - do { \
|
| - if (HasRegisterInput(instr, 1)) { \
|
| - __ asm_instr(i.OutputRegister(), i.InputRegister(0), \
|
| - i.InputRegister(1)); \
|
| - } else if (HasImmediateInput(instr, 1)) { \
|
| - __ asm_instr(i.OutputRegister(), i.InputRegister(0), \
|
| - i.InputImmediate(1)); \
|
| - } else { \
|
| - UNIMPLEMENTED(); \
|
| - } \
|
| - } while (0)
|
| -
|
| #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \
|
| do { \
|
| AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
|
| @@ -1353,76 +1344,76 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| }
|
| case kS390_And32:
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - ASSEMBLE_BIN_OP(nrk, And, nilf);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(nrk), RM32Instr(And), RIInstr(nilf));
|
| } else {
|
| - ASSEMBLE_BIN_OP(nr, And, nilf);
|
| + ASSEMBLE_BIN32_OP(RRInstr(nr), RM32Instr(And), RIInstr(nilf));
|
| }
|
| break;
|
| case kS390_And64:
|
| - ASSEMBLE_BINOP(AndP);
|
| + if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| + ASSEMBLE_BIN_OP(RRRInstr(ngrk), RM64Instr(ng), nullInstr);
|
| + } else {
|
| + ASSEMBLE_BIN_OP(RRInstr(ngr), RM64Instr(ng), nullInstr);
|
| + }
|
| break;
|
| case kS390_Or32:
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - ASSEMBLE_BIN_OP(ork, Or, oilf);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(ork), RM32Instr(Or), RIInstr(oilf));
|
| } else {
|
| - ASSEMBLE_BIN_OP(or_z, Or, oilf);
|
| + ASSEMBLE_BIN32_OP(RRInstr(or_z), RM32Instr(Or), RIInstr(oilf));
|
| }
|
| break;
|
| case kS390_Or64:
|
| - ASSEMBLE_BINOP(OrP);
|
| + if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| + ASSEMBLE_BIN_OP(RRRInstr(ogrk), RM64Instr(og), nullInstr);
|
| + } else {
|
| + ASSEMBLE_BIN_OP(RRInstr(ogr), RM64Instr(og), nullInstr);
|
| + }
|
| break;
|
| case kS390_Xor32:
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - ASSEMBLE_BIN_OP(xrk, Xor, xilf);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(xrk), RM32Instr(Xor), RIInstr(xilf));
|
| } else {
|
| - ASSEMBLE_BIN_OP(xr, Xor, xilf);
|
| + ASSEMBLE_BIN32_OP(RRInstr(xr), RM32Instr(Xor), RIInstr(xilf));
|
| }
|
| break;
|
| case kS390_Xor64:
|
| - ASSEMBLE_BINOP(XorP);
|
| + if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| + ASSEMBLE_BIN_OP(RRRInstr(xgrk), RM64Instr(xg), nullInstr);
|
| + } else {
|
| + ASSEMBLE_BIN_OP(RRInstr(xgr), RM64Instr(xg), nullInstr);
|
| + }
|
| break;
|
| case kS390_ShiftLeft32:
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - AssembleBinOp(i, masm(), instr, &MacroAssembler::ShiftLeft,
|
| - &MacroAssembler::ShiftLeft);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(ShiftLeft), nullInstr, RRIInstr(ShiftLeft));
|
| } else {
|
| - AssembleBinOp(i, masm(), instr, &MacroAssembler::sll,
|
| - &MacroAssembler::sll);
|
| + ASSEMBLE_BIN32_OP(RRInstr(sll), nullInstr, RIInstr(sll));
|
| }
|
| break;
|
| -#if V8_TARGET_ARCH_S390X
|
| case kS390_ShiftLeft64:
|
| - ASSEMBLE_BINOP(sllg);
|
| + ASSEMBLE_BIN_OP(RRRInstr(sllg), nullInstr, RRIInstr(sllg));
|
| break;
|
| -#endif
|
| case kS390_ShiftRight32:
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - AssembleBinOp(i, masm(), instr, &MacroAssembler::srlk,
|
| - &MacroAssembler::srlk);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(srlk), nullInstr, RRIInstr(srlk));
|
| } else {
|
| - AssembleBinOp(i, masm(), instr, &MacroAssembler::srl,
|
| - &MacroAssembler::srl);
|
| + ASSEMBLE_BIN32_OP(RRInstr(srl), nullInstr, RIInstr(srl));
|
| }
|
| break;
|
| -#if V8_TARGET_ARCH_S390X
|
| case kS390_ShiftRight64:
|
| - ASSEMBLE_BINOP(srlg);
|
| + ASSEMBLE_BIN_OP(RRRInstr(srlg), nullInstr, RRIInstr(srlg));
|
| break;
|
| -#endif
|
| case kS390_ShiftRightArith32:
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - AssembleBinOp(i, masm(), instr, &MacroAssembler::srak,
|
| - &MacroAssembler::srak);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(srak), nullInstr, RRIInstr(srak));
|
| } else {
|
| - AssembleBinOp(i, masm(), instr, &MacroAssembler::sra,
|
| - &MacroAssembler::sra);
|
| + ASSEMBLE_BIN32_OP(RRInstr(sra), nullInstr, RIInstr(sra));
|
| }
|
| break;
|
| -#if V8_TARGET_ARCH_S390X
|
| case kS390_ShiftRightArith64:
|
| - ASSEMBLE_BINOP(srag);
|
| + ASSEMBLE_BIN_OP(RRRInstr(srag), nullInstr, RRIInstr(srag));
|
| break;
|
| -#endif
|
| #if !V8_TARGET_ARCH_S390X
|
| case kS390_AddPair:
|
| // i.InputRegister(0) ... left low word.
|
| @@ -1509,16 +1500,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| CHECK_AND_ZERO_EXT_OUTPUT(2);
|
| break;
|
| }
|
| -#if V8_TARGET_ARCH_S390X
|
| case kS390_RotRight64:
|
| if (HasRegisterInput(instr, 1)) {
|
| - __ LoadComplementRR(kScratchReg, i.InputRegister(1));
|
| + __ lcgr(kScratchReg, i.InputRegister(1));
|
| __ rllg(i.OutputRegister(), i.InputRegister(0), kScratchReg);
|
| } else {
|
| + DCHECK(HasImmediateInput(instr, 1));
|
| __ rllg(i.OutputRegister(), i.InputRegister(0),
|
| Operand(64 - i.InputInt32(1)));
|
| }
|
| break;
|
| + // TODO(john.yan): clean up kS390_RotLeftAnd...
|
| case kS390_RotLeftAndClear64:
|
| if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) {
|
| int shiftAmount = i.InputInt32(1);
|
| @@ -1566,191 +1558,112 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| __ sllg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit));
|
| }
|
| break;
|
| -#endif
|
| case kS390_Add32: {
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - ASSEMBLE_BIN_OP(ark, Add32, Add32_RRI);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(ark), RM32Instr(Add32), RRIInstr(Add32));
|
| } else {
|
| - ASSEMBLE_BIN_OP(ar, Add32, Add32_RI);
|
| + ASSEMBLE_BIN32_OP(RRInstr(ar), RM32Instr(Add32), RIInstr(Add32));
|
| }
|
| break;
|
| }
|
| case kS390_Add64:
|
| - ASSEMBLE_BINOP(AddP);
|
| - break;
|
| - case kS390_AddFloat:
|
| - // Ensure we don't clobber right/InputReg(1)
|
| - if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) {
|
| - ASSEMBLE_FLOAT_UNOP(aebr);
|
| + if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| + ASSEMBLE_BIN_OP(RRRInstr(agrk), RM64Instr(ag), RRIInstr(AddP));
|
| } else {
|
| - if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0)))
|
| - __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| - __ aebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
|
| + ASSEMBLE_BIN_OP(RRInstr(agr), RM64Instr(ag), RIInstr(agfi));
|
| }
|
| break;
|
| + case kS390_AddFloat:
|
| + ASSEMBLE_BIN_OP(DDInstr(aebr), DMTInstr(AddFloat32), nullInstr);
|
| + 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));
|
| - }
|
| + ASSEMBLE_BIN_OP(DDInstr(adbr), DMTInstr(AddFloat64), nullInstr);
|
| break;
|
| case kS390_Sub32:
|
| if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| - ASSEMBLE_BIN_OP(srk, Sub32, Sub32_RRI);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(srk), RM32Instr(Sub32), RRIInstr(Sub32));
|
| } else {
|
| - ASSEMBLE_BIN_OP(sr, Sub32, Sub32_RI);
|
| + ASSEMBLE_BIN32_OP(RRInstr(sr), RM32Instr(Sub32), RIInstr(Sub32));
|
| }
|
| break;
|
| case kS390_Sub64:
|
| - ASSEMBLE_BINOP(SubP);
|
| - break;
|
| - 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);
|
| + if (CpuFeatures::IsSupported(DISTINCT_OPS)) {
|
| + ASSEMBLE_BIN_OP(RRRInstr(sgrk), RM64Instr(sg), RRIInstr(SubP));
|
| } else {
|
| - if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) {
|
| - __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| - }
|
| - __ sebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
|
| + ASSEMBLE_BIN_OP(RRInstr(sgr), RM64Instr(sg), RIInstr(SubP));
|
| }
|
| break;
|
| + case kS390_SubFloat:
|
| + ASSEMBLE_BIN_OP(DDInstr(sebr), DMTInstr(SubFloat32), nullInstr);
|
| + break;
|
| 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));
|
| - }
|
| + ASSEMBLE_BIN_OP(DDInstr(sdbr), DMTInstr(SubFloat64), nullInstr);
|
| break;
|
| case kS390_Mul32:
|
| - ASSEMBLE_BIN_OP(Mul32, Mul32, Mul32);
|
| + ASSEMBLE_BIN32_OP(RRInstr(Mul32), RM32Instr(Mul32), RIInstr(Mul32));
|
| break;
|
| case kS390_Mul32WithOverflow:
|
| - ASSEMBLE_BIN_OP(Mul32WithOverflowIfCCUnequal,
|
| - Mul32WithOverflowIfCCUnequal,
|
| - Mul32WithOverflowIfCCUnequal);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(Mul32WithOverflowIfCCUnequal),
|
| + RRM32Instr(Mul32WithOverflowIfCCUnequal),
|
| + RRIInstr(Mul32WithOverflowIfCCUnequal));
|
| break;
|
| case kS390_Mul64:
|
| - CHECK(i.OutputRegister().is(i.InputRegister(0)));
|
| - if (HasRegisterInput(instr, 1)) {
|
| - __ Mul64(i.InputRegister(0), i.InputRegister(1));
|
| - } else if (HasImmediateInput(instr, 1)) {
|
| - __ Mul64(i.InputRegister(0), i.InputImmediate(1));
|
| - } else if (HasStackSlotInput(instr, 1)) {
|
| - __ Mul64(i.InputRegister(0), i.InputStackSlot(1));
|
| - } else {
|
| - UNIMPLEMENTED();
|
| - }
|
| + ASSEMBLE_BIN_OP(RRInstr(Mul64), RM64Instr(Mul64), RIInstr(Mul64));
|
| break;
|
| case kS390_MulHigh32:
|
| - ASSEMBLE_BIN_OP(MulHigh32, MulHigh32, MulHigh32);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(MulHigh32), RRM32Instr(MulHigh32),
|
| + RRIInstr(MulHigh32));
|
| break;
|
| case kS390_MulHighU32:
|
| - ASSEMBLE_BIN_OP(MulHighU32, MulHighU32, MulHighU32);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(MulHighU32), RRM32Instr(MulHighU32),
|
| + RRIInstr(MulHighU32));
|
| 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));
|
| - }
|
| + ASSEMBLE_BIN_OP(DDInstr(meebr), DMTInstr(MulFloat32), nullInstr);
|
| 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));
|
| - }
|
| + ASSEMBLE_BIN_OP(DDInstr(mdbr), DMTInstr(MulFloat64), nullInstr);
|
| break;
|
| -#if V8_TARGET_ARCH_S390X
|
| case kS390_Div64:
|
| - __ LoadRR(r1, i.InputRegister(0));
|
| - __ dsgr(r0, i.InputRegister(1)); // R1: Dividend
|
| - __ ltgr(i.OutputRegister(), r1); // Copy R1: Quotient to output
|
| + ASSEMBLE_BIN_OP(RRRInstr(Div64), RRM64Instr(Div64), nullInstr);
|
| break;
|
| -#endif
|
| case kS390_Div32: {
|
| - ASSEMBLE_BIN_OP(Div32, Div32, Div32);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(Div32), RRM32Instr(Div32), nullInstr);
|
| 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: Dividend
|
| - __ ltgr(i.OutputRegister(), r1); // Copy R1: Quotient to output
|
| + ASSEMBLE_BIN_OP(RRRInstr(DivU64), RRM64Instr(DivU64), nullInstr);
|
| break;
|
| -#endif
|
| case kS390_DivU32: {
|
| - ASSEMBLE_BIN_OP(DivU32, DivU32, DivU32);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(DivU32), RRM32Instr(DivU32), nullInstr);
|
| 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));
|
| - }
|
| + ASSEMBLE_BIN_OP(DDInstr(debr), DMTInstr(DivFloat32), nullInstr);
|
| break;
|
| 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));
|
| - }
|
| + ASSEMBLE_BIN_OP(DDInstr(ddbr), DMTInstr(DivFloat64), nullInstr);
|
| break;
|
| case kS390_Mod32:
|
| - ASSEMBLE_BIN_OP(Mod32, Mod32, Mod32);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(Mod32), RRM32Instr(Mod32), nullInstr);
|
| break;
|
| case kS390_ModU32:
|
| - ASSEMBLE_BIN_OP(ModU32, ModU32, ModU32);
|
| + ASSEMBLE_BIN32_OP(RRRInstr(ModU32), RRM32Instr(ModU32), nullInstr);
|
| break;
|
| -#if V8_TARGET_ARCH_S390X
|
| case kS390_Mod64:
|
| - __ LoadRR(r1, i.InputRegister(0));
|
| - __ dsgr(r0, i.InputRegister(1)); // R1: Dividend
|
| - __ ltgr(i.OutputRegister(), r0); // Copy R0: Remainder to output
|
| + ASSEMBLE_BIN_OP(RRRInstr(Mod64), RRM64Instr(Mod64), nullInstr);
|
| break;
|
| case kS390_ModU64:
|
| - __ LoadRR(r1, i.InputRegister(0));
|
| - __ LoadImmP(r0, Operand::Zero());
|
| - __ dlgr(r0, i.InputRegister(1)); // R0:R1: Dividend
|
| - __ ltgr(i.OutputRegister(), r0); // Copy R0: Remainder to output
|
| + ASSEMBLE_BIN_OP(RRRInstr(ModU64), RRM64Instr(ModU64), nullInstr);
|
| break;
|
| -#endif
|
| case kS390_AbsFloat:
|
| __ lpebr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
| case kS390_SqrtFloat:
|
| - ASSEMBLE_FLOAT_UNOP(sqebr);
|
| + ASSEMBLE_UNARY_OP(D_DInstr(sqebr), nullInstr, nullInstr);
|
| + break;
|
| + case kS390_SqrtDouble:
|
| + ASSEMBLE_UNARY_OP(D_DInstr(sqdbr), nullInstr, nullInstr);
|
| break;
|
| case kS390_FloorFloat:
|
| __ fiebra(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
|
| @@ -1856,9 +1769,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| case kS390_AbsDouble:
|
| __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
| - case kS390_SqrtDouble:
|
| - ASSEMBLE_FLOAT_UNOP(sqdbr);
|
| - break;
|
| case kS390_FloorDouble:
|
| __ fidbra(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
|
| v8::internal::Assembler::FIDBRA_ROUND_TOWARD_NEG_INF);
|
| @@ -1876,10 +1786,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| v8::internal::Assembler::FIDBRA_ROUND_TO_NEAREST_AWAY_FROM_0);
|
| break;
|
| case kS390_NegFloat:
|
| - ASSEMBLE_FLOAT_UNOP(lcebr);
|
| + ASSEMBLE_UNARY_OP(D_DInstr(lcebr), nullInstr, nullInstr);
|
| break;
|
| case kS390_NegDouble:
|
| - ASSEMBLE_FLOAT_UNOP(lcdbr);
|
| + ASSEMBLE_UNARY_OP(D_DInstr(lcdbr), nullInstr, nullInstr);
|
| break;
|
| case kS390_Cntlz32: {
|
| __ llgfr(i.OutputRegister(), i.InputRegister(0));
|
| @@ -2144,10 +2054,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| }
|
| #endif
|
| case kS390_DoubleToFloat32:
|
| - __ ledbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| + ASSEMBLE_UNARY_OP(D_DInstr(ledbr), nullInstr, nullInstr);
|
| break;
|
| case kS390_Float32ToDouble:
|
| - __ ldebr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| + ASSEMBLE_UNARY_OP(D_DInstr(ldebr), D_MTInstr(LoadFloat32ToDouble),
|
| + nullInstr);
|
| break;
|
| case kS390_DoubleExtractLowWord32:
|
| __ lgdr(i.OutputRegister(), i.InputDoubleRegister(0));
|
| @@ -2176,15 +2087,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| __ ldgr(i.OutputDoubleRegister(), kScratchReg);
|
| break;
|
| case kS390_LoadWordS8:
|
| - ASSEMBLE_LOAD_INTEGER(LoadlB);
|
| -#if V8_TARGET_ARCH_S390X
|
| - __ lgbr(i.OutputRegister(), i.OutputRegister());
|
| -#else
|
| - __ lbr(i.OutputRegister(), i.OutputRegister());
|
| -#endif
|
| + ASSEMBLE_LOAD_INTEGER(LoadB);
|
| break;
|
| case kS390_BitcastFloat32ToInt32:
|
| - __ MovFloatToInt(i.OutputRegister(), i.InputDoubleRegister(0));
|
| + ASSEMBLE_UNARY_OP(R_DInstr(MovFloatToInt), R_MInstr(LoadlW), nullInstr);
|
| break;
|
| case kS390_BitcastInt32ToFloat32:
|
| __ MovIntToFloat(i.OutputDoubleRegister(), i.InputRegister(0));
|
| @@ -2231,11 +2137,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| case kS390_LoadReverse64RR:
|
| __ lrvgr(i.OutputRegister(), i.InputRegister(0));
|
| break;
|
| -#if V8_TARGET_ARCH_S390X
|
| case kS390_LoadWord64:
|
| ASSEMBLE_LOAD_INTEGER(lg);
|
| break;
|
| -#endif
|
| case kS390_LoadAndTestWord32: {
|
| ASSEMBLE_LOADANDTEST32(ltr, lt_z);
|
| break;
|
| @@ -2283,12 +2187,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
| __ lay(i.OutputRegister(), i.MemoryOperand());
|
| break;
|
| case kCheckedLoadInt8:
|
| - ASSEMBLE_CHECKED_LOAD_INTEGER(LoadlB);
|
| -#if V8_TARGET_ARCH_S390X
|
| - __ lgbr(i.OutputRegister(), i.OutputRegister());
|
| -#else
|
| - __ lbr(i.OutputRegister(), i.OutputRegister());
|
| -#endif
|
| + ASSEMBLE_CHECKED_LOAD_INTEGER(LoadB);
|
| break;
|
| case kCheckedLoadUint8:
|
| ASSEMBLE_CHECKED_LOAD_INTEGER(LoadlB);
|
| @@ -2495,6 +2394,8 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
|
| : Operand(1));
|
| __ bunordered(&done);
|
| }
|
| +
|
| + // TODO(john.yan): use load imm high on condition here
|
| __ LoadImmP(reg, Operand::Zero());
|
| __ LoadImmP(kScratchReg, Operand(1));
|
| // locr is sufficient since reg's upper 32 is guarrantee to be 0
|
|
|