Commit 0c3cc68f authored by jyan's avatar jyan Committed by Commit bot

s390: optimize TF to use tmll and fix tmll sim

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

Review-Url: https://codereview.chromium.org/2622073006
Cr-Commit-Position: refs/heads/master@{#42297}
parent e539bd8e
...@@ -1675,21 +1675,30 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1675,21 +1675,30 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break; break;
case kS390_Tst32: case kS390_Tst32:
if (HasRegisterInput(instr, 1)) { if (HasRegisterInput(instr, 1)) {
__ AndP(r0, i.InputRegister(0), i.InputRegister(1)); __ lr(r0, i.InputRegister(0));
__ nr(r0, i.InputRegister(1));
} else {
Operand opnd = i.InputImmediate(1);
if (is_uint16(opnd.immediate())) {
__ tmll(i.InputRegister(0), opnd);
} else { } else {
__ AndP(r0, i.InputRegister(0), i.InputImmediate(1)); __ lr(r0, i.InputRegister(0));
__ nilf(r0, opnd);
}
} }
__ LoadAndTestP_ExtendSrc(r0, r0);
break; break;
#if V8_TARGET_ARCH_S390X
case kS390_Tst64: case kS390_Tst64:
if (HasRegisterInput(instr, 1)) { if (HasRegisterInput(instr, 1)) {
__ AndP(r0, i.InputRegister(0), i.InputRegister(1)); __ AndP(r0, i.InputRegister(0), i.InputRegister(1));
} else { } else {
__ AndP(r0, i.InputRegister(0), i.InputImmediate(1)); Operand opnd = i.InputImmediate(1);
if (is_uint16(opnd.immediate())) {
__ tmll(i.InputRegister(0), opnd);
} else {
__ AndP(r0, i.InputRegister(0), opnd);
}
} }
break; break;
#endif
case kS390_Float64SilenceNaN: { case kS390_Float64SilenceNaN: {
DoubleRegister value = i.InputDoubleRegister(0); DoubleRegister value = i.InputDoubleRegister(0);
DoubleRegister result = i.OutputDoubleRegister(); DoubleRegister result = i.OutputDoubleRegister();
......
...@@ -1625,9 +1625,27 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -1625,9 +1625,27 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
if (selector->CanCover(user, value)) { if (selector->CanCover(user, value)) {
switch (value->opcode()) { switch (value->opcode()) {
case IrOpcode::kWord32Equal: case IrOpcode::kWord32Equal: {
cont->OverwriteAndNegateIfEqual(kEqual); cont->OverwriteAndNegateIfEqual(kEqual);
Int32BinopMatcher m(value);
if (m.right().Is(0)) {
// Try to combine the branch with a comparison.
Node* const user = m.node();
Node* const value = m.left().node();
if (selector->CanCover(user, value)) {
switch (value->opcode()) {
case IrOpcode::kInt32Sub:
return VisitWord32Compare(selector, value, cont); return VisitWord32Compare(selector, value, cont);
case IrOpcode::kWord32And:
return VisitWordCompare(selector, value, kS390_Tst64, cont,
true, kUint32Imm);
default:
break;
}
}
}
return VisitWord32Compare(selector, value, cont);
}
case IrOpcode::kInt32LessThan: case IrOpcode::kInt32LessThan:
cont->OverwriteAndNegateIfEqual(kSignedLessThan); cont->OverwriteAndNegateIfEqual(kSignedLessThan);
return VisitWord32Compare(selector, value, cont); return VisitWord32Compare(selector, value, cont);
...@@ -1641,9 +1659,27 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -1641,9 +1659,27 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
return VisitWord32Compare(selector, value, cont); return VisitWord32Compare(selector, value, cont);
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
case IrOpcode::kWord64Equal: case IrOpcode::kWord64Equal: {
cont->OverwriteAndNegateIfEqual(kEqual); cont->OverwriteAndNegateIfEqual(kEqual);
Int64BinopMatcher m(value);
if (m.right().Is(0)) {
// Try to combine the branch with a comparison.
Node* const user = m.node();
Node* const value = m.left().node();
if (selector->CanCover(user, value)) {
switch (value->opcode()) {
case IrOpcode::kInt64Sub:
return VisitWord64Compare(selector, value, cont);
case IrOpcode::kWord64And:
return VisitWordCompare(selector, value, kS390_Tst64, cont,
true, kUint32Imm);
default:
break;
}
}
}
return VisitWord64Compare(selector, value, cont); return VisitWord64Compare(selector, value, cont);
}
case IrOpcode::kInt64LessThan: case IrOpcode::kInt64LessThan:
cont->OverwriteAndNegateIfEqual(kSignedLessThan); cont->OverwriteAndNegateIfEqual(kSignedLessThan);
return VisitWord64Compare(selector, value, cont); return VisitWord64Compare(selector, value, cont);
......
...@@ -7779,47 +7779,38 @@ EVALUATE(TMLH) { ...@@ -7779,47 +7779,38 @@ EVALUATE(TMLH) {
EVALUATE(TMLL) { EVALUATE(TMLL) {
DCHECK_OPCODE(TMLL); DCHECK_OPCODE(TMLL);
DECODE_RI_A_INSTRUCTION(instr, r1, i2); DECODE_RI_A_INSTRUCTION(instr, r1, i2);
int mask = i2 & 0x0000FFFF; uint32_t mask = i2 & 0x0000FFFF;
if (mask == 0) {
condition_reg_ = 0x0;
return length;
}
uint32_t r1_val = get_low_register<uint32_t>(r1); uint32_t r1_val = get_low_register<uint32_t>(r1);
r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
// Test if all selected bits are Zero // Test if all selected bits are zeros or mask is zero
bool allSelectedBitsAreZeros = true; if (0 == (mask & r1_val)) {
for (int i = 0; i < 15; i++) {
if (mask & (1 << i)) {
if (r1_val & (1 << i)) {
allSelectedBitsAreZeros = false;
break;
}
}
}
if (allSelectedBitsAreZeros) {
condition_reg_ = 0x8; condition_reg_ = 0x8;
return length; // Done! return length; // Done!
} }
DCHECK(mask != 0);
// Test if all selected bits are one // Test if all selected bits are one
bool allSelectedBitsAreOnes = true; if (mask == (mask & r1_val)) {
for (int i = 0; i < 15; i++) {
if (mask & (1 << i)) {
if (!(r1_val & (1 << i))) {
allSelectedBitsAreOnes = false;
break;
}
}
}
if (allSelectedBitsAreOnes) {
condition_reg_ = 0x1; condition_reg_ = 0x1;
return length; // Done! return length; // Done!
} }
// Now we know selected bits mixed zeros and ones // Now we know selected bits mixed zeros and ones
// Test if the leftmost bit is zero or one // Test if the leftmost bit is zero or one
for (int i = 14; i >= 0; i--) { #if defined(__GNUC__)
int leadingZeros = __builtin_clz(mask);
mask = 0x80000000u >> leadingZeros;
if (mask & r1_val) {
// leftmost bit is one
condition_reg_ = 0x4;
} else {
// leftmost bit is zero
condition_reg_ = 0x2;
}
return length; // Done!
#else
for (int i = 15; i >= 0; i--) {
if (mask & (1 << i)) { if (mask & (1 << i)) {
if (r1_val & (1 << i)) { if (r1_val & (1 << i)) {
// leftmost bit is one // leftmost bit is one
...@@ -7831,6 +7822,8 @@ EVALUATE(TMLL) { ...@@ -7831,6 +7822,8 @@ EVALUATE(TMLL) {
return length; // Done! return length; // Done!
} }
} }
#endif
UNREACHABLE();
return length; return length;
} }
......
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