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(
break;
case kS390_Tst32:
if (HasRegisterInput(instr, 1)) {
__ AndP(r0, i.InputRegister(0), i.InputRegister(1));
__ lr(r0, i.InputRegister(0));
__ nr(r0, i.InputRegister(1));
} 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 {
__ lr(r0, i.InputRegister(0));
__ nilf(r0, opnd);
}
}
__ LoadAndTestP_ExtendSrc(r0, r0);
break;
#if V8_TARGET_ARCH_S390X
case kS390_Tst64:
if (HasRegisterInput(instr, 1)) {
__ AndP(r0, i.InputRegister(0), i.InputRegister(1));
} 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;
#endif
case kS390_Float64SilenceNaN: {
DoubleRegister value = i.InputDoubleRegister(0);
DoubleRegister result = i.OutputDoubleRegister();
......
......@@ -1625,9 +1625,27 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
if (selector->CanCover(user, value)) {
switch (value->opcode()) {
case IrOpcode::kWord32Equal:
case IrOpcode::kWord32Equal: {
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);
case IrOpcode::kWord32And:
return VisitWordCompare(selector, value, kS390_Tst64, cont,
true, kUint32Imm);
default:
break;
}
}
}
return VisitWord32Compare(selector, value, cont);
}
case IrOpcode::kInt32LessThan:
cont->OverwriteAndNegateIfEqual(kSignedLessThan);
return VisitWord32Compare(selector, value, cont);
......@@ -1641,9 +1659,27 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
return VisitWord32Compare(selector, value, cont);
#if V8_TARGET_ARCH_S390X
case IrOpcode::kWord64Equal:
case IrOpcode::kWord64Equal: {
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);
}
case IrOpcode::kInt64LessThan:
cont->OverwriteAndNegateIfEqual(kSignedLessThan);
return VisitWord64Compare(selector, value, cont);
......
......@@ -7779,47 +7779,38 @@ EVALUATE(TMLH) {
EVALUATE(TMLL) {
DCHECK_OPCODE(TMLL);
DECODE_RI_A_INSTRUCTION(instr, r1, i2);
int mask = i2 & 0x0000FFFF;
if (mask == 0) {
condition_reg_ = 0x0;
return length;
}
uint32_t mask = i2 & 0x0000FFFF;
uint32_t r1_val = get_low_register<uint32_t>(r1);
r1_val = r1_val & 0x0000FFFF; // uses only the last 16bits
// Test if all selected bits are Zero
bool allSelectedBitsAreZeros = true;
for (int i = 0; i < 15; i++) {
if (mask & (1 << i)) {
if (r1_val & (1 << i)) {
allSelectedBitsAreZeros = false;
break;
}
}
}
if (allSelectedBitsAreZeros) {
// Test if all selected bits are zeros or mask is zero
if (0 == (mask & r1_val)) {
condition_reg_ = 0x8;
return length; // Done!
}
DCHECK(mask != 0);
// Test if all selected bits are one
bool allSelectedBitsAreOnes = true;
for (int i = 0; i < 15; i++) {
if (mask & (1 << i)) {
if (!(r1_val & (1 << i))) {
allSelectedBitsAreOnes = false;
break;
}
}
}
if (allSelectedBitsAreOnes) {
if (mask == (mask & r1_val)) {
condition_reg_ = 0x1;
return length; // Done!
}
// Now we know selected bits mixed zeros and ones
// 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 (r1_val & (1 << i)) {
// leftmost bit is one
......@@ -7831,6 +7822,8 @@ EVALUATE(TMLL) {
return length; // Done!
}
}
#endif
UNREACHABLE();
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