Commit d6a92013 authored by jyan's avatar jyan Committed by Commit bot

s390: exploit new mul in TF

R=joransiu@ca.ibm.com, bjaideep@ca.ibm.com

Review-Url: https://codereview.chromium.org/2795803003
Cr-Commit-Position: refs/heads/master@{#44392}
parent e46f8418
......@@ -311,6 +311,7 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
case kS390_Sub64:
case kS390_Abs64:
case kS390_Abs32:
case kS390_Mul32:
return overflow;
default:
break;
......@@ -322,6 +323,9 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
case kS390_Add64:
case kS390_Sub32:
case kS390_Sub64:
case kS390_Abs64:
case kS390_Abs32:
case kS390_Mul32:
return nooverflow;
default:
break;
......@@ -1624,7 +1628,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
case kS390_Mul32:
// zero-ext
ASSEMBLE_BIN32_OP(RRInstr(Mul32), RM32Instr(Mul32), RIInstr(Mul32));
if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
ASSEMBLE_BIN32_OP(RRRInstr(msrkc), RM32Instr(msc), RIInstr(Mul32));
} else {
ASSEMBLE_BIN32_OP(RRInstr(Mul32), RM32Instr(Mul32), RIInstr(Mul32));
}
break;
case kS390_Mul32WithOverflow:
// zero-ext
......@@ -2549,8 +2557,8 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
// Overflow checked for add/sub only.
DCHECK((condition != kOverflow && condition != kNotOverflow) ||
(op == kS390_Add32 || kS390_Add64 || op == kS390_Sub32 ||
op == kS390_Sub64));
(op == kS390_Add32 || op == kS390_Add64 || op == kS390_Sub32 ||
op == kS390_Sub64 || op == kS390_Mul32));
// Materialize a full 32-bit 1 or 0 value. The result register is always the
// last output of the instruction.
......
......@@ -1359,10 +1359,16 @@ static inline bool TryMatchInt32SubWithOverflow(InstructionSelector* selector,
static inline bool TryMatchInt32MulWithOverflow(InstructionSelector* selector,
Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf);
VisitWord32BinOp(selector, node, kS390_Mul32WithOverflow,
OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps,
&cont);
if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
DCHECK(TryMatchInt32OpWithOverflow<kS390_Mul32>(
selector, node,
OperandMode::kAllowRRR | OperandMode::kAllowRM) == true);
} else {
FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf);
VisitWord32BinOp(selector, node, kS390_Mul32WithOverflow,
OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps,
&cont);
}
return true;
}
return TryMatchShiftFromMul<Int32BinopMatcher, kS390_ShiftLeft32>(selector,
......
......@@ -963,7 +963,9 @@ typedef uint64_t SixByteInstr;
V(ley, LEY, 0xED64) /* type = RXY_A LOAD (short) */ \
V(ldy, LDY, 0xED65) /* type = RXY_A LOAD (long) */ \
V(stey, STEY, 0xED66) /* type = RXY_A STORE (short) */ \
V(stdy, STDY, 0xED67) /* type = RXY_A STORE (long) */
V(stdy, STDY, 0xED67) /* type = RXY_A STORE (long) */ \
V(msc, MSC, 0xE353) /* type = RSY_A MULTIPLY SINGLE (32) */ \
V(msgc, MSGC, 0xE383) /* type = RSY_A MULTIPLY SINGLE (64) */
#define S390_RXY_B_OPCODE_LIST(V) \
V(pfd, PFD, 0xE336) /* type = RXY_B PREFETCH DATA */
......@@ -1715,7 +1717,7 @@ enum Opcode {
#undef DECLARE_OPCODES
BKPT = 0x0001, // GDB Software Breakpoint
DUMY = 0xE353 // Special dummy opcode
DUMY = 0xE352 // Special dummy opcode
};
// Instruction encoding bits and masks.
......
......@@ -1436,6 +1436,12 @@ bool Decoder::DecodeSixByte(Instruction* instr) {
case MSY:
Format(instr, "msy\t'r1,'d2('r2d,'r3)");
break;
case MSC:
Format(instr, "msc\t'r1,'d2('r2d,'r3)");
break;
case MSGC:
Format(instr, "msgc\t'r1,'d2('r2d,'r3)");
break;
case STEY:
Format(instr, "stey\t'f1,'d2('r2d,'r3)");
break;
......
......@@ -1300,6 +1300,7 @@ void Simulator::EvalTableInit() {
EvalTable[BCTG] = &Simulator::Evaluate_BCTG;
EvalTable[STY] = &Simulator::Evaluate_STY;
EvalTable[MSY] = &Simulator::Evaluate_MSY;
EvalTable[MSC] = &Simulator::Evaluate_MSC;
EvalTable[NY] = &Simulator::Evaluate_NY;
EvalTable[CLY] = &Simulator::Evaluate_CLY;
EvalTable[OY] = &Simulator::Evaluate_OY;
......@@ -8157,6 +8158,25 @@ EVALUATE(MSY) {
return length;
}
EVALUATE(MSC) {
DCHECK_OPCODE(MSC);
DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t d2_val = d2;
int32_t mem_val = ReadW(b2_val + d2_val + x2_val, instr);
int32_t r1_val = get_low_register<int32_t>(r1);
int64_t result64 =
static_cast<int64_t>(r1_val) * static_cast<int64_t>(mem_val);
int32_t result32 = static_cast<int32_t>(result64);
bool isOF = (static_cast<int64_t>(result32) != result64);
SetS390ConditionCode<int32_t>(result32, 0);
SetS390OverflowCode(isOF);
set_low_register(r1, result32);
set_low_register(r1, mem_val * r1_val);
return length;
}
EVALUATE(NY) {
DCHECK_OPCODE(NY);
DECODE_RXY_A_INSTRUCTION(r1, x2, b2, d2);
......
......@@ -1062,6 +1062,7 @@ class Simulator {
EVALUATE(BCTG);
EVALUATE(STY);
EVALUATE(MSY);
EVALUATE(MSC);
EVALUATE(NY);
EVALUATE(CLY);
EVALUATE(OY);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment