Revision: 24388
Author: [email protected]
Date: Thu Oct 2 09:08:09 2014 UTC
Log: [turbofan] support all shift operands on x64
[email protected]
BUG=
Review URL: https://codereview.chromium.org/615223005
https://code.google.com/p/v8/source/detail?r=24388
Modified:
/branches/bleeding_edge/src/compiler/x64/code-generator-x64.cc
/branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc
/branches/bleeding_edge/src/x64/assembler-x64.cc
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/src/x64/disasm-x64.cc
/branches/bleeding_edge/test/cctest/test-disasm-x64.cc
=======================================
--- /branches/bleeding_edge/src/compiler/x64/code-generator-x64.cc Wed Oct
1 14:03:02 2014 UTC
+++ /branches/bleeding_edge/src/compiler/x64/code-generator-x64.cc Thu Oct
2 09:08:09 2014 UTC
@@ -184,13 +184,21 @@
} while (0)
-#define ASSEMBLE_SHIFT(asm_instr, width) \
- do { \
- if (HasImmediateInput(instr, 1)) { \
- __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \
- } else { \
- __ asm_instr##_cl(i.OutputRegister()); \
- } \
+#define ASSEMBLE_SHIFT(asm_instr, width)
\
+ do {
\
+ if (HasImmediateInput(instr, 1)) {
\
+ if (instr->Output()->IsRegister()) {
\
+ __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1)));
\
+ } else {
\
+ __ asm_instr(i.OutputOperand(), Immediate(i.InputInt##width(1)));
\
+ }
\
+ } else {
\
+ if (instr->Output()->IsRegister()) {
\
+ __ asm_instr##_cl(i.OutputRegister());
\
+ } else {
\
+ __ asm_instr##_cl(i.OutputOperand());
\
+ }
\
+ }
\
} while (0)
=======================================
--- /branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc
Wed Oct 1 10:47:14 2014 UTC
+++ /branches/bleeding_edge/src/compiler/x64/instruction-selector-x64.cc
Thu Oct 2 09:08:09 2014 UTC
@@ -20,8 +20,6 @@
return new (zone())
UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
Register::ToAllocationIndex(reg));
}
-
- InstructionOperand* UseImmediate64(Node* node) { return
UseImmediate(node); }
bool CanBeImmediate(Node* node) {
switch (node->opcode()) {
@@ -31,23 +29,6 @@
return false;
}
}
-
- bool CanBeImmediate64(Node* node) {
- switch (node->opcode()) {
- case IrOpcode::kInt32Constant:
- return true;
- case IrOpcode::kNumberConstant:
- return true;
- case IrOpcode::kHeapConstant: {
- // Constants in new space cannot be used as immediates in V8
because
- // the GC does not scan code objects when collecting the new
generation.
- Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node);
- return !isolate()->heap()->InNewSpace(*value.handle());
- }
- default:
- return false;
- }
- }
bool CanBeBetterLeftOperand(Node* node) const {
return !selector()->IsLive(node);
@@ -350,9 +331,8 @@
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
- // TODO(turbofan): assembler only supports some addressing modes for
shifts.
if (g.CanBeImmediate(right)) {
- selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
+ selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left),
g.UseImmediate(right));
} else {
Int32BinopMatcher m(node);
@@ -362,7 +342,7 @@
right = mright.left().node();
}
}
- selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
+ selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left),
g.UseFixed(right, rcx));
}
}
@@ -376,9 +356,8 @@
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
- // TODO(turbofan): assembler only supports some addressing modes for
shifts.
if (g.CanBeImmediate(right)) {
- selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
+ selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left),
g.UseImmediate(right));
} else {
Int64BinopMatcher m(node);
@@ -388,7 +367,7 @@
right = mright.left().node();
}
}
- selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
+ selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left),
g.UseFixed(right, rcx));
}
}
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Tue Sep 30 10:24:11
2014 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.cc Thu Oct 2 09:08:09
2014 UTC
@@ -615,6 +615,24 @@
emit(shift_amount.value_);
}
}
+
+
+void Assembler::shift(Operand dst, Immediate shift_amount, int subcode,
+ int size) {
+ EnsureSpace ensure_space(this);
+ DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
+ : is_uint5(shift_amount.value_));
+ if (shift_amount.value_ == 1) {
+ emit_rex(dst, size);
+ emit(0xD1);
+ emit_operand(subcode, dst);
+ } else {
+ emit_rex(dst, size);
+ emit(0xC1);
+ emit_operand(subcode, dst);
+ emit(shift_amount.value_);
+ }
+}
void Assembler::shift(Register dst, int subcode, int size) {
@@ -623,6 +641,14 @@
emit(0xD3);
emit_modrm(subcode, dst);
}
+
+
+void Assembler::shift(Operand dst, int subcode, int size) {
+ EnsureSpace ensure_space(this);
+ emit_rex(dst, size);
+ emit(0xD3);
+ emit_operand(subcode, dst);
+}
void Assembler::bt(const Operand& dst, Register src) {
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Thu Sep 25 06:37:23
2014 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Thu Oct 2 09:08:09
2014 UTC
@@ -813,30 +813,42 @@
// Multiply rax by src, put the result in rdx:rax.
void mul(Register src);
-#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
- void instruction##p(Register dst, Immediate imm8) { \
- shift(dst, imm8, subcode, kPointerSize); \
- } \
- \
- void instruction##l(Register dst, Immediate imm8) { \
- shift(dst, imm8, subcode, kInt32Size); \
- } \
- \
- void instruction##q(Register dst, Immediate imm8) { \
- shift(dst, imm8, subcode, kInt64Size); \
- } \
- \
- void instruction##p_cl(Register dst) { \
- shift(dst, subcode, kPointerSize); \
- } \
- \
- void instruction##l_cl(Register dst) { \
- shift(dst, subcode, kInt32Size); \
- } \
- \
- void instruction##q_cl(Register dst) { \
- shift(dst, subcode, kInt64Size); \
- }
+#define DECLARE_SHIFT_INSTRUCTION(instruction,
subcode) \
+ void instruction##p(Register dst, Immediate imm8)
{ \
+ shift(dst, imm8, subcode,
kPointerSize); \
+
}
\
+
\
+ void instruction##l(Register dst, Immediate imm8)
{ \
+ shift(dst, imm8, subcode,
kInt32Size); \
+
}
\
+
\
+ void instruction##q(Register dst, Immediate imm8)
{ \
+ shift(dst, imm8, subcode,
kInt64Size); \
+
}
\
+
\
+ void instruction##p(Operand dst, Immediate imm8)
{ \
+ shift(dst, imm8, subcode,
kPointerSize); \
+
}
\
+
\
+ void instruction##l(Operand dst, Immediate imm8)
{ \
+ shift(dst, imm8, subcode,
kInt32Size); \
+
}
\
+
\
+ void instruction##q(Operand dst, Immediate imm8)
{ \
+ shift(dst, imm8, subcode,
kInt64Size); \
+
}
\
+
\
+ void instruction##p_cl(Register dst) { shift(dst, subcode,
kPointerSize); } \
+
\
+ void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size);
} \
+
\
+ void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size);
} \
+
\
+ void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize);
} \
+
\
+ void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size);
} \
+
\
+ void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
#undef DECLARE_SHIFT_INSTRUCTION
@@ -1365,9 +1377,11 @@
int size);
// Emit machine code for a shift operation.
+ void shift(Operand dst, Immediate shift_amount, int subcode, int size);
void shift(Register dst, Immediate shift_amount, int subcode, int size);
// Shift dst by cl % 64 bits.
void shift(Register dst, int subcode, int size);
+ void shift(Operand dst, int subcode, int size);
void emit_farith(int b1, int b2, int i);
=======================================
--- /branches/bleeding_edge/src/x64/disasm-x64.cc Mon Aug 4 11:34:54 2014
UTC
+++ /branches/bleeding_edge/src/x64/disasm-x64.cc Thu Oct 2 09:08:09 2014
UTC
@@ -709,65 +709,62 @@
int DisassemblerX64::ShiftInstruction(byte* data) {
byte op = *data & (~1);
+ int count = 1;
if (op != 0xD0 && op != 0xD2 && op != 0xC0) {
UnimplementedInstruction();
- return 1;
+ return count;
}
- byte modrm = *(data + 1);
- int mod, regop, rm;
- get_modrm(modrm, &mod, ®op, &rm);
- regop &= 0x7; // The REX.R bit does not affect the operation.
- int imm8 = -1;
- int num_bytes = 2;
- if (mod != 3) {
- UnimplementedInstruction();
- return num_bytes;
+ // Print mneumonic.
+ {
+ byte modrm = *(data + count);
+ int mod, regop, rm;
+ get_modrm(modrm, &mod, ®op, &rm);
+ regop &= 0x7; // The REX.R bit does not affect the operation.
+ const char* mnem = NULL;
+ switch (regop) {
+ case 0:
+ mnem = "rol";
+ break;
+ case 1:
+ mnem = "ror";
+ break;
+ case 2:
+ mnem = "rcl";
+ break;
+ case 3:
+ mnem = "rcr";
+ break;
+ case 4:
+ mnem = "shl";
+ break;
+ case 5:
+ mnem = "shr";
+ break;
+ case 7:
+ mnem = "sar";
+ break;
+ default:
+ UnimplementedInstruction();
+ return count + 1;
+ }
+ DCHECK_NE(NULL, mnem);
+ AppendToBuffer("%s%c ", mnem, operand_size_code());
}
- const char* mnem = NULL;
- switch (regop) {
- case 0:
- mnem = "rol";
- break;
- case 1:
- mnem = "ror";
- break;
- case 2:
- mnem = "rcl";
- break;
- case 3:
- mnem = "rcr";
- break;
- case 4:
- mnem = "shl";
- break;
- case 5:
- mnem = "shr";
- break;
- case 7:
- mnem = "sar";
- break;
- default:
- UnimplementedInstruction();
- return num_bytes;
- }
- DCHECK_NE(NULL, mnem);
- if (op == 0xD0) {
- imm8 = 1;
- } else if (op == 0xC0) {
- imm8 = *(data + 2);
- num_bytes = 3;
- }
- AppendToBuffer("%s%c %s,",
- mnem,
- operand_size_code(),
- byte_size_operand_ ? NameOfByteCPURegister(rm)
- : NameOfCPURegister(rm));
+ count += PrintRightOperand(data + count);
if (op == 0xD2) {
- AppendToBuffer("cl");
+ AppendToBuffer(", cl");
} else {
- AppendToBuffer("%d", imm8);
+ int imm8 = -1;
+ if (op == 0xD0) {
+ imm8 = 1;
+ } else {
+ DCHECK_EQ(0xC0, op);
+ imm8 = *(data + count);
+ count++;
+ }
+ AppendToBuffer(", %d", imm8);
}
- return num_bytes;
+ return count;
}
=======================================
--- /branches/bleeding_edge/test/cctest/test-disasm-x64.cc Tue Sep 30
10:24:11 2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-disasm-x64.cc Thu Oct 2
09:08:09 2014 UTC
@@ -117,6 +117,26 @@
__ imulq(rdx, rcx);
__ shld(rdx, rcx);
__ shrd(rdx, rcx);
+ __ shlq(Operand(rdi, rax, times_4, 100), Immediate(1));
+ __ shlq(Operand(rdi, rax, times_4, 100), Immediate(6));
+ __ shlq(Operand(r15, 0), Immediate(1));
+ __ shlq(Operand(r15, 0), Immediate(6));
+ __ shlq_cl(Operand(r15, 0));
+ __ shlq_cl(Operand(r15, 0));
+ __ shlq_cl(Operand(rdi, rax, times_4, 100));
+ __ shlq_cl(Operand(rdi, rax, times_4, 100));
+ __ shlq(rdx, Immediate(1));
+ __ shlq(rdx, Immediate(6));
+ __ shll(Operand(rdi, rax, times_4, 100), Immediate(1));
+ __ shll(Operand(rdi, rax, times_4, 100), Immediate(6));
+ __ shll(Operand(r15, 0), Immediate(1));
+ __ shll(Operand(r15, 0), Immediate(6));
+ __ shll_cl(Operand(r15, 0));
+ __ shll_cl(Operand(r15, 0));
+ __ shll_cl(Operand(rdi, rax, times_4, 100));
+ __ shll_cl(Operand(rdi, rax, times_4, 100));
+ __ shll(rdx, Immediate(1));
+ __ shll(rdx, Immediate(6));
__ bts(Operand(rdx, 0), rcx);
__ bts(Operand(rbx, rcx, times_4, 0), rcx);
__ nop();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.