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:
zhengxing.li 2016-03-08 07:01:32 -08:00 committed by Commit bot
parent 802a906ed0
commit 8f506ac6a6
9 changed files with 104 additions and 20 deletions

View File

@ -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));

View File

@ -31,6 +31,7 @@ namespace compiler {
V(X87Shl) \
V(X87Shr) \
V(X87Sar) \
V(X87PairShl) \
V(X87Ror) \
V(X87Lzcnt) \
V(X87Popcnt) \

View File

@ -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);

View File

@ -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));
}

View File

@ -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);

View File

@ -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, &regop, &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;

View File

@ -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;

View File

@ -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.

View File

@ -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);