Commit 8a7f302d authored by dusan.m.milosavljevic's avatar dusan.m.milosavljevic Committed by Commit bot

MIPS64: [turbofan] Improve matching for And(Shr(x, imm), mask).

Utilise Dextu, Dextm on mips64 for widths and positions larger
than 32.

TEST=
BUG=

Review URL: https://codereview.chromium.org/1552483002

Cr-Commit-Position: refs/heads/master@{#33138}
parent 6cd8535c
......@@ -774,10 +774,22 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
i.InputInt8(2));
}
break;
case kMips64Dext:
__ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
i.InputInt8(2));
case kMips64Dext: {
int16_t pos = i.InputInt8(1);
int16_t size = i.InputInt8(2);
if (size > 0 && size <= 32 && pos >= 0 && pos < 32) {
__ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
i.InputInt8(2));
} else if (size > 32 && size <= 64 && pos > 0 && pos < 32) {
__ Dextm(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
i.InputInt8(2));
} else {
DCHECK(size > 0 && size <= 32 && pos >= 32 && pos < 64);
__ Dextu(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
i.InputInt8(2));
}
break;
}
case kMips64Dins:
if (instr->InputAt(1)->IsImmediate() && i.InputInt8(1) == 0) {
__ Dins(i.OutputRegister(), zero_reg, i.InputInt8(1), i.InputInt8(2));
......
......@@ -2427,6 +2427,22 @@ void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
}
void Assembler::dextm(Register rt, Register rs, uint16_t pos, uint16_t size) {
// Should be called via MacroAssembler::Dextm.
// Dextm instr has 'rt' field as dest, and two uint5: msb, lsb.
DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(SPECIAL3, rs, rt, size - 1 - 32, pos, DEXTM);
}
void Assembler::dextu(Register rt, Register rs, uint16_t pos, uint16_t size) {
// Should be called via MacroAssembler::Dextu.
// Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos - 32, DEXTU);
}
void Assembler::bitswap(Register rd, Register rt) {
DCHECK(kArchVariant == kMips64r6);
GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
......
......@@ -886,6 +886,8 @@ class Assembler : public AssemblerBase {
void ins_(Register rt, Register rs, uint16_t pos, uint16_t size);
void ext_(Register rt, Register rs, uint16_t pos, uint16_t size);
void dext_(Register rt, Register rs, uint16_t pos, uint16_t size);
void dextm(Register rt, Register rs, uint16_t pos, uint16_t size);
void dextu(Register rt, Register rs, uint16_t pos, uint16_t size);
void dins_(Register rt, Register rs, uint16_t pos, uint16_t size);
void bitswap(Register rd, Register rt);
void dbitswap(Register rd, Register rt);
......
......@@ -1228,6 +1228,8 @@ Instruction::Type Instruction::InstructionType(TypeChecks checks) const {
case INS:
case EXT:
case DEXT:
case DEXTM:
case DEXTU:
return kRegisterType;
case BSHFL: {
int sa = SaFieldRaw() >> kSaShift;
......
......@@ -1507,6 +1507,22 @@ void MacroAssembler::Dext(Register rt, Register rs, uint16_t pos,
}
void MacroAssembler::Dextm(Register rt, Register rs, uint16_t pos,
uint16_t size) {
DCHECK(pos < 32);
DCHECK(size <= 64);
dextm(rt, rs, pos, size);
}
void MacroAssembler::Dextu(Register rt, Register rs, uint16_t pos,
uint16_t size) {
DCHECK(pos >= 32 && pos < 64);
DCHECK(size < 33);
dextu(rt, rs, pos, size);
}
void MacroAssembler::Dins(Register rt, Register rs, uint16_t pos,
uint16_t size) {
DCHECK(pos < 32);
......
......@@ -801,6 +801,8 @@ class MacroAssembler: public Assembler {
void Dins(Register rt, Register rs, uint16_t pos, uint16_t size);
void Ext(Register rt, Register rs, uint16_t pos, uint16_t size);
void Dext(Register rt, Register rs, uint16_t pos, uint16_t size);
void Dextm(Register rt, Register rs, uint16_t pos, uint16_t size);
void Dextu(Register rt, Register rs, uint16_t pos, uint16_t size);
// ---------------------------------------------------------------------------
// FPU macros. These do not handle special cases like NaN or +- inf.
......
......@@ -3893,6 +3893,28 @@ void Simulator::DecodeTypeRegisterSPECIAL3() {
SetResult(rt_reg(), alu_out);
break;
}
case DEXTM: {
// Interpret rd field as 5-bit msb of extract.
uint16_t msb = rd_reg();
// Interpret sa field as 5-bit lsb of extract.
uint16_t lsb = sa();
uint16_t size = msb + 33;
uint64_t mask = (1ULL << size) - 1;
alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb);
SetResult(rt_reg(), alu_out);
break;
}
case DEXTU: {
// Interpret rd field as 5-bit msb of extract.
uint16_t msb = rd_reg();
// Interpret sa field as 5-bit lsb of extract.
uint16_t lsb = sa() + 32;
uint16_t size = msb + 1;
uint64_t mask = (1ULL << size) - 1;
alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb);
SetResult(rt_reg(), alu_out);
break;
}
case BSHFL: {
int32_t sa = get_instr()->SaFieldRaw() >> kSaShift;
switch (sa) {
......
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