X87: [wasm] Int64Lowering of I64Shl on ia32.
port ddc626e1cf
(r34546)
original commit message:
I64Shl is lowered to a new turbofan operator, WasmWord64Shl. The new
operator takes 3 inputs, the low-word input, the high-word input, and
the shift, and produces 2 output, the low-word output and the high-word
output.
At the moment I implemented the lowering only for ia32, but I think the
CL is already big enough. I will add the other platforms in separate
CLs.
BUG=
Review URL: https://codereview.chromium.org/1773083002
Cr-Commit-Position: refs/heads/master@{#34591}
This commit is contained in:
parent
802a906ed0
commit
8f506ac6a6
@ -717,6 +717,14 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ sar_cl(i.OutputOperand());
|
||||
}
|
||||
break;
|
||||
case kX87PairShl:
|
||||
if (HasImmediateInput(instr, 2)) {
|
||||
__ PairShl(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2));
|
||||
} else {
|
||||
// Shift has been loaded into CL by the register allocator.
|
||||
__ PairShl_cl(i.InputRegister(1), i.InputRegister(0));
|
||||
}
|
||||
break;
|
||||
case kX87Ror:
|
||||
if (HasImmediateInput(instr, 1)) {
|
||||
__ ror(i.OutputOperand(), i.InputInt5(1));
|
||||
|
@ -31,6 +31,7 @@ namespace compiler {
|
||||
V(X87Shl) \
|
||||
V(X87Shr) \
|
||||
V(X87Sar) \
|
||||
V(X87PairShl) \
|
||||
V(X87Ror) \
|
||||
V(X87Lzcnt) \
|
||||
V(X87Popcnt) \
|
||||
|
@ -546,7 +546,26 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
|
||||
VisitShift(this, node, kX87Sar);
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); }
|
||||
void InstructionSelector::VisitWord32PairShl(Node* node) {
|
||||
X87OperandGenerator g(this);
|
||||
|
||||
Node* shift = node->InputAt(2);
|
||||
InstructionOperand shift_operand;
|
||||
if (g.CanBeImmediate(shift)) {
|
||||
shift_operand = g.UseImmediate(shift);
|
||||
} else {
|
||||
shift_operand = g.UseFixed(shift, ecx);
|
||||
}
|
||||
InstructionOperand inputs[] = {g.UseFixed(node->InputAt(0), eax),
|
||||
g.UseFixed(node->InputAt(1), edx),
|
||||
shift_operand};
|
||||
|
||||
InstructionOperand outputs[] = {
|
||||
g.DefineAsFixed(node, eax),
|
||||
g.DefineAsFixed(NodeProperties::FindProjection(node, 1), edx)};
|
||||
|
||||
Emit(kX87PairShl, 2, outputs, 3, inputs);
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitWord32Ror(Node* node) {
|
||||
VisitShift(this, node, kX87Ror);
|
||||
|
@ -946,12 +946,20 @@ void Assembler::sbb(Register dst, const Operand& src) {
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::shld(Register dst, Register src, uint8_t shift) {
|
||||
DCHECK(is_uint5(shift));
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x0F);
|
||||
EMIT(0xA4);
|
||||
emit_operand(src, Operand(dst));
|
||||
EMIT(shift);
|
||||
}
|
||||
|
||||
void Assembler::shld(Register dst, const Operand& src) {
|
||||
void Assembler::shld_cl(Register dst, Register src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x0F);
|
||||
EMIT(0xA5);
|
||||
emit_operand(dst, src);
|
||||
emit_operand(src, Operand(dst));
|
||||
}
|
||||
|
||||
|
||||
|
@ -731,8 +731,8 @@ class Assembler : public AssemblerBase {
|
||||
|
||||
void sbb(Register dst, const Operand& src);
|
||||
|
||||
void shld(Register dst, Register src) { shld(dst, Operand(src)); }
|
||||
void shld(Register dst, const Operand& src);
|
||||
void shld(Register dst, Register src, uint8_t shift);
|
||||
void shld_cl(Register dst, Register src);
|
||||
|
||||
void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); }
|
||||
void shl(const Operand& dst, uint8_t imm8);
|
||||
|
@ -906,18 +906,34 @@ static const char* F0Mnem(byte f0byte) {
|
||||
switch (f0byte) {
|
||||
case 0x0B:
|
||||
return "ud2";
|
||||
case 0x18: return "prefetch";
|
||||
case 0xA2: return "cpuid";
|
||||
case 0xBE: return "movsx_b";
|
||||
case 0xBF: return "movsx_w";
|
||||
case 0xB6: return "movzx_b";
|
||||
case 0xB7: return "movzx_w";
|
||||
case 0xAF: return "imul";
|
||||
case 0xA5: return "shld";
|
||||
case 0xAD: return "shrd";
|
||||
case 0xAC: return "shrd"; // 3-operand version.
|
||||
case 0xAB: return "bts";
|
||||
case 0xBD: return "bsr";
|
||||
case 0x18:
|
||||
return "prefetch";
|
||||
case 0xA2:
|
||||
return "cpuid";
|
||||
case 0xBE:
|
||||
return "movsx_b";
|
||||
case 0xBF:
|
||||
return "movsx_w";
|
||||
case 0xB6:
|
||||
return "movzx_b";
|
||||
case 0xB7:
|
||||
return "movzx_w";
|
||||
case 0xAF:
|
||||
return "imul";
|
||||
case 0xA4:
|
||||
return "shld";
|
||||
case 0xA5:
|
||||
return "shld";
|
||||
case 0xAD:
|
||||
return "shrd";
|
||||
case 0xAC:
|
||||
return "shrd"; // 3-operand version.
|
||||
case 0xAB:
|
||||
return "bts";
|
||||
case 0xBC:
|
||||
return "bsf";
|
||||
case 0xBD:
|
||||
return "bsr";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@ -1134,8 +1150,17 @@ int DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
|
||||
data += SetCC(data);
|
||||
} else if ((f0byte & 0xF0) == 0x40) {
|
||||
data += CMov(data);
|
||||
} else if (f0byte == 0xA4) {
|
||||
data += 2;
|
||||
AppendToBuffer("%s ", f0mnem);
|
||||
int mod, regop, rm;
|
||||
get_modrm(*data, &mod, ®op, &rm);
|
||||
int8_t imm8 = static_cast<int8_t>(data[1]);
|
||||
data += 2;
|
||||
AppendToBuffer("%s,%s,%d", NameOfCPURegister(rm),
|
||||
NameOfCPURegister(regop), static_cast<int>(imm8));
|
||||
} else if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) {
|
||||
// shrd, shld, bts
|
||||
// shrd, shld_cl, bts
|
||||
data += 2;
|
||||
AppendToBuffer("%s ", f0mnem);
|
||||
int mod, regop, rm;
|
||||
|
@ -597,6 +597,27 @@ void MacroAssembler::DebugBreak() {
|
||||
call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT);
|
||||
}
|
||||
|
||||
void MacroAssembler::PairShl(Register high, Register low, uint8_t shift) {
|
||||
if (shift >= 32) {
|
||||
mov(high, low);
|
||||
shl(high, shift - 32);
|
||||
xor_(low, low);
|
||||
} else {
|
||||
shld(high, low, shift);
|
||||
shl(low, shift);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::PairShl_cl(Register high, Register low) {
|
||||
shld_cl(high, low);
|
||||
shl_cl(low);
|
||||
Label done;
|
||||
test(ecx, Immediate(0x20));
|
||||
j(equal, &done, Label::kNear);
|
||||
mov(high, low);
|
||||
xor_(low, low);
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
bool MacroAssembler::IsUnsafeImmediate(const Immediate& x) {
|
||||
static const int kMaxImmediateBits = 17;
|
||||
|
@ -356,6 +356,8 @@ class MacroAssembler: public Assembler {
|
||||
const ParameterCount& actual, InvokeFlag flag,
|
||||
const CallWrapper& call_wrapper);
|
||||
|
||||
void PairShl(Register high, Register low, uint8_t imm8);
|
||||
void PairShl_cl(Register high, Register low);
|
||||
|
||||
// Expression support
|
||||
// Support for constant splitting.
|
||||
|
@ -119,7 +119,8 @@ TEST(DisasmIa320) {
|
||||
|
||||
__ nop();
|
||||
__ imul(edx, ecx);
|
||||
__ shld(edx, ecx);
|
||||
__ shld(edx, ecx, 10);
|
||||
__ shld_cl(edx, ecx);
|
||||
__ shrd(edx, ecx);
|
||||
__ bts(edx, ecx);
|
||||
__ bts(Operand(ebx, ecx, times_4, 0), ecx);
|
||||
@ -214,7 +215,6 @@ TEST(DisasmIa320) {
|
||||
__ sar(Operand(ebx, ecx, times_4, 10000), 6);
|
||||
__ sar_cl(Operand(ebx, ecx, times_4, 10000));
|
||||
__ sbb(edx, Operand(ebx, ecx, times_4, 10000));
|
||||
__ shld(edx, Operand(ebx, ecx, times_4, 10000));
|
||||
__ shl(edx, 1);
|
||||
__ shl(edx, 6);
|
||||
__ shl_cl(edx);
|
||||
|
Loading…
Reference in New Issue
Block a user