[arm] Add support for ROR. Refactor operand2 handling.
This was the last missing bit for full "flexible second operand" / operand2 support on ARM. TEST=cctest/test-instruction-selector-arm,cctest/test-run-machops R=jarin@chromium.org Review URL: https://codereview.chromium.org/434553002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22732 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ec91e4ef42
commit
0eecf982f9
@ -79,6 +79,10 @@ class ArmOperandConverter : public InstructionOperandConverter {
|
||||
return Operand(InputRegister(index + 0), LSR, InputInt5(index + 1));
|
||||
case kMode_Operand2_R_LSR_R:
|
||||
return Operand(InputRegister(index + 0), LSR, InputRegister(index + 1));
|
||||
case kMode_Operand2_R_ROR_I:
|
||||
return Operand(InputRegister(index + 0), ROR, InputInt5(index + 1));
|
||||
case kMode_Operand2_R_ROR_R:
|
||||
return Operand(InputRegister(index + 0), ROR, InputRegister(index + 1));
|
||||
}
|
||||
UNREACHABLE();
|
||||
return Operand::Zero();
|
||||
@ -96,6 +100,8 @@ class ArmOperandConverter : public InstructionOperandConverter {
|
||||
case kMode_Operand2_R_LSL_R:
|
||||
case kMode_Operand2_R_LSR_I:
|
||||
case kMode_Operand2_R_LSR_R:
|
||||
case kMode_Operand2_R_ROR_I:
|
||||
case kMode_Operand2_R_ROR_R:
|
||||
break;
|
||||
case kMode_Offset_RI:
|
||||
*first_index += 2;
|
||||
|
@ -73,9 +73,11 @@ namespace compiler {
|
||||
V(Operand2_R_ASR_I) /* %r0 ASR K */ \
|
||||
V(Operand2_R_LSL_I) /* %r0 LSL K */ \
|
||||
V(Operand2_R_LSR_I) /* %r0 LSR K */ \
|
||||
V(Operand2_R_ROR_I) /* %r0 ROR K */ \
|
||||
V(Operand2_R_ASR_R) /* %r0 ASR %r1 */ \
|
||||
V(Operand2_R_LSL_R) /* %r0 LSL %r1 */ \
|
||||
V(Operand2_R_LSR_R) /* %r0 LSR %r1 */
|
||||
V(Operand2_R_LSR_R) /* %r0 LSR %r1 */ \
|
||||
V(Operand2_R_ROR_R) /* %r0 ROR %r1 */
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
|
@ -121,75 +121,122 @@ static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
|
||||
}
|
||||
|
||||
|
||||
static Instruction* EmitBinop(InstructionSelector* selector,
|
||||
InstructionCode opcode, size_t output_count,
|
||||
InstructionOperand** outputs, Node* left,
|
||||
Node* right, size_t label_count,
|
||||
InstructionOperand** labels) {
|
||||
static bool TryMatchROR(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
ArmOperandGenerator g(selector);
|
||||
InstructionOperand* inputs[5];
|
||||
size_t input_count = 0;
|
||||
|
||||
inputs[input_count++] = g.UseRegister(left);
|
||||
if (g.CanBeImmediate(right, opcode)) {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_I);
|
||||
inputs[input_count++] = g.UseImmediate(right);
|
||||
} else if (right->opcode() == IrOpcode::kWord32Sar) {
|
||||
Int32BinopMatcher mright(right);
|
||||
inputs[input_count++] = g.UseRegister(mright.left().node());
|
||||
if (mright.right().IsInRange(1, 32)) {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I);
|
||||
inputs[input_count++] = g.UseImmediate(mright.right().node());
|
||||
} else {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_R);
|
||||
inputs[input_count++] = g.UseRegister(mright.right().node());
|
||||
}
|
||||
} else if (right->opcode() == IrOpcode::kWord32Shl) {
|
||||
Int32BinopMatcher mright(right);
|
||||
inputs[input_count++] = g.UseRegister(mright.left().node());
|
||||
if (mright.right().IsInRange(0, 31)) {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
|
||||
inputs[input_count++] = g.UseImmediate(mright.right().node());
|
||||
} else {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_R);
|
||||
inputs[input_count++] = g.UseRegister(mright.right().node());
|
||||
}
|
||||
} else if (right->opcode() == IrOpcode::kWord32Shr) {
|
||||
Int32BinopMatcher mright(right);
|
||||
inputs[input_count++] = g.UseRegister(mright.left().node());
|
||||
if (mright.right().IsInRange(1, 32)) {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R_LSR_I);
|
||||
inputs[input_count++] = g.UseImmediate(mright.right().node());
|
||||
} else {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R_LSR_R);
|
||||
inputs[input_count++] = g.UseRegister(mright.right().node());
|
||||
}
|
||||
} else {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R);
|
||||
inputs[input_count++] = g.UseRegister(right);
|
||||
if (node->opcode() != IrOpcode::kWord32Or) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
Node* shl = m.left().node();
|
||||
Node* shr = m.right().node();
|
||||
if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) {
|
||||
std::swap(shl, shr);
|
||||
} else if (!m.left().IsWord32Shl() || !m.right().IsWord32Shr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Append the optional labels.
|
||||
while (label_count-- != 0) {
|
||||
inputs[input_count++] = *labels++;
|
||||
Int32BinopMatcher mshr(shr);
|
||||
Int32BinopMatcher mshl(shl);
|
||||
Node* value = mshr.left().node();
|
||||
if (value != mshl.left().node()) return false;
|
||||
Node* shift = mshr.right().node();
|
||||
Int32Matcher mshift(shift);
|
||||
if (mshift.IsInRange(1, 31) && mshl.right().Is(32 - mshift.Value())) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
|
||||
*value_return = g.UseRegister(value);
|
||||
*shift_return = g.UseImmediate(shift);
|
||||
return true;
|
||||
}
|
||||
|
||||
ASSERT_NE(0, input_count);
|
||||
ASSERT_GE(ARRAY_SIZE(inputs), input_count);
|
||||
ASSERT_NE(kMode_None, AddressingModeField::decode(opcode));
|
||||
|
||||
return selector->Emit(opcode, output_count, outputs, input_count, inputs);
|
||||
if (mshl.right().IsInt32Sub()) {
|
||||
Int32BinopMatcher mshlright(mshl.right().node());
|
||||
if (!mshlright.left().Is(32)) return false;
|
||||
if (mshlright.right().node() != shift) return false;
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_R);
|
||||
*value_return = g.UseRegister(value);
|
||||
*shift_return = g.UseRegister(shift);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static Instruction* EmitBinop(InstructionSelector* selector,
|
||||
InstructionCode opcode, Node* node, Node* left,
|
||||
Node* right) {
|
||||
static inline bool TryMatchASR(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
ArmOperandGenerator g(selector);
|
||||
InstructionOperand* outputs[] = {g.DefineAsRegister(node)};
|
||||
const size_t output_count = ARRAY_SIZE(outputs);
|
||||
return EmitBinop(selector, opcode, output_count, outputs, left, right, 0,
|
||||
NULL);
|
||||
if (node->opcode() != IrOpcode::kWord32Sar) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(1, 32)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_I);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_R);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchLSL(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (node->opcode() != IrOpcode::kWord32Shl) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(0, 31)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_R);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchLSR(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return, Node* node,
|
||||
InstructionOperand** value_return,
|
||||
InstructionOperand** shift_return) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (node->opcode() != IrOpcode::kWord32Shr) return false;
|
||||
Int32BinopMatcher m(node);
|
||||
*value_return = g.UseRegister(m.left().node());
|
||||
if (m.right().IsInRange(1, 32)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I);
|
||||
*shift_return = g.UseImmediate(m.right().node());
|
||||
} else {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R);
|
||||
*shift_return = g.UseRegister(m.right().node());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline bool TryMatchImmediateOrShift(InstructionSelector* selector,
|
||||
InstructionCode* opcode_return,
|
||||
Node* node,
|
||||
size_t* input_count_return,
|
||||
InstructionOperand** inputs) {
|
||||
ArmOperandGenerator g(selector);
|
||||
if (g.CanBeImmediate(node, *opcode_return)) {
|
||||
*opcode_return |= AddressingModeField::encode(kMode_Operand2_I);
|
||||
inputs[0] = g.UseImmediate(node);
|
||||
*input_count_return = 1;
|
||||
return true;
|
||||
}
|
||||
if (TryMatchASR(selector, opcode_return, node, &inputs[0], &inputs[1]) ||
|
||||
TryMatchLSL(selector, opcode_return, node, &inputs[0], &inputs[1]) ||
|
||||
TryMatchLSR(selector, opcode_return, node, &inputs[0], &inputs[1]) ||
|
||||
TryMatchROR(selector, opcode_return, node, &inputs[0], &inputs[1])) {
|
||||
*input_count_return = 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -198,17 +245,32 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
|
||||
InstructionCode opcode, InstructionCode reverse_opcode) {
|
||||
ArmOperandGenerator g(selector);
|
||||
Int32BinopMatcher m(node);
|
||||
InstructionOperand* inputs[3];
|
||||
size_t input_count = 0;
|
||||
|
||||
Node* left = m.left().node();
|
||||
Node* right = m.right().node();
|
||||
if (g.CanBeImmediate(m.left().node(), reverse_opcode) ||
|
||||
m.left().IsWord32Sar() || m.left().IsWord32Shl() ||
|
||||
m.left().IsWord32Shr()) {
|
||||
if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
|
||||
&input_count, &inputs[1])) {
|
||||
inputs[0] = g.UseRegister(m.left().node());
|
||||
input_count++;
|
||||
} else if (TryMatchImmediateOrShift(selector, &reverse_opcode,
|
||||
m.left().node(), &input_count,
|
||||
&inputs[1])) {
|
||||
inputs[0] = g.UseRegister(m.right().node());
|
||||
opcode = reverse_opcode;
|
||||
std::swap(left, right);
|
||||
input_count++;
|
||||
} else {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R);
|
||||
inputs[input_count++] = g.UseRegister(m.left().node());
|
||||
inputs[input_count++] = g.UseRegister(m.right().node());
|
||||
}
|
||||
|
||||
EmitBinop(selector, opcode, node, left, right);
|
||||
ASSERT_NE(0, input_count);
|
||||
ASSERT_GE(ARRAY_SIZE(inputs), input_count);
|
||||
ASSERT_NE(kMode_None, AddressingModeField::decode(opcode));
|
||||
|
||||
InstructionOperand* outputs[1] = {g.DefineAsRegister(node)};
|
||||
const size_t output_count = ARRAY_SIZE(outputs);
|
||||
selector->Emit(opcode, output_count, outputs, input_count, inputs);
|
||||
}
|
||||
|
||||
|
||||
@ -311,20 +373,44 @@ void InstructionSelector::VisitStore(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
static inline void EmitBic(InstructionSelector* selector, Node* node,
|
||||
Node* left, Node* right) {
|
||||
ArmOperandGenerator g(selector);
|
||||
InstructionCode opcode = kArmBic;
|
||||
InstructionOperand* inputs[3];
|
||||
size_t input_count = 0;
|
||||
InstructionOperand* outputs[1] = {g.DefineAsRegister(node)};
|
||||
const size_t output_count = ARRAY_SIZE(outputs);
|
||||
|
||||
inputs[input_count++] = g.UseRegister(left);
|
||||
if (!TryMatchImmediateOrShift(selector, &opcode, right, &input_count,
|
||||
&inputs[input_count])) {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R);
|
||||
inputs[input_count++] = g.UseRegister(right);
|
||||
}
|
||||
|
||||
ASSERT_NE(0, input_count);
|
||||
ASSERT_GE(ARRAY_SIZE(inputs), input_count);
|
||||
ASSERT_NE(kMode_None, AddressingModeField::decode(opcode));
|
||||
|
||||
selector->Emit(opcode, output_count, outputs, input_count, inputs);
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::VisitWord32And(Node* node) {
|
||||
ArmOperandGenerator g(this);
|
||||
Int32BinopMatcher m(node);
|
||||
if (m.left().IsWord32Xor() && CanCover(node, m.left().node())) {
|
||||
Int32BinopMatcher mleft(m.left().node());
|
||||
if (mleft.right().Is(-1)) {
|
||||
EmitBinop(this, kArmBic, node, m.right().node(), mleft.left().node());
|
||||
EmitBic(this, node, m.right().node(), mleft.left().node());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) {
|
||||
Int32BinopMatcher mright(m.right().node());
|
||||
if (mright.right().Is(-1)) {
|
||||
EmitBinop(this, kArmBic, node, m.left().node(), mright.left().node());
|
||||
EmitBic(this, node, m.left().node(), mright.left().node());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -362,6 +448,14 @@ void InstructionSelector::VisitWord32And(Node* node) {
|
||||
|
||||
|
||||
void InstructionSelector::VisitWord32Or(Node* node) {
|
||||
ArmOperandGenerator g(this);
|
||||
InstructionCode opcode = kArmMov;
|
||||
InstructionOperand* value_operand;
|
||||
InstructionOperand* shift_operand;
|
||||
if (TryMatchROR(this, &opcode, node, &value_operand, &shift_operand)) {
|
||||
Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand);
|
||||
return;
|
||||
}
|
||||
VisitBinop(this, node, kArmOrr, kArmOrr);
|
||||
}
|
||||
|
||||
@ -378,18 +472,22 @@ void InstructionSelector::VisitWord32Xor(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
template <typename TryMatchShift>
|
||||
static inline void VisitShift(InstructionSelector* selector, Node* node,
|
||||
TryMatchShift try_match_shift) {
|
||||
ArmOperandGenerator g(selector);
|
||||
InstructionCode opcode = kArmMov;
|
||||
InstructionOperand* value_operand = NULL;
|
||||
InstructionOperand* shift_operand = NULL;
|
||||
CHECK(
|
||||
try_match_shift(selector, &opcode, node, &value_operand, &shift_operand));
|
||||
selector->Emit(opcode, g.DefineAsRegister(node), value_operand,
|
||||
shift_operand);
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::VisitWord32Shl(Node* node) {
|
||||
ArmOperandGenerator g(this);
|
||||
Int32BinopMatcher m(node);
|
||||
if (m.right().IsInRange(0, 31)) {
|
||||
Emit(kArmMov | AddressingModeField::encode(kMode_Operand2_R_LSL_I),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseImmediate(m.right().node()));
|
||||
} else {
|
||||
Emit(kArmMov | AddressingModeField::encode(kMode_Operand2_R_LSL_R),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseRegister(m.right().node()));
|
||||
}
|
||||
VisitShift(this, node, TryMatchLSL);
|
||||
}
|
||||
|
||||
|
||||
@ -413,30 +511,12 @@ void InstructionSelector::VisitWord32Shr(Node* node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m.right().IsInRange(1, 32)) {
|
||||
Emit(kArmMov | AddressingModeField::encode(kMode_Operand2_R_LSR_I),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseImmediate(m.right().node()));
|
||||
return;
|
||||
}
|
||||
Emit(kArmMov | AddressingModeField::encode(kMode_Operand2_R_LSR_R),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseRegister(m.right().node()));
|
||||
VisitShift(this, node, TryMatchLSR);
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::VisitWord32Sar(Node* node) {
|
||||
ArmOperandGenerator g(this);
|
||||
Int32BinopMatcher m(node);
|
||||
if (m.right().IsInRange(1, 32)) {
|
||||
Emit(kArmMov | AddressingModeField::encode(kMode_Operand2_R_ASR_I),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseImmediate(m.right().node()));
|
||||
} else {
|
||||
Emit(kArmMov | AddressingModeField::encode(kMode_Operand2_R_ASR_R),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseRegister(m.right().node()));
|
||||
}
|
||||
VisitShift(this, node, TryMatchASR);
|
||||
}
|
||||
|
||||
|
||||
@ -711,31 +791,44 @@ static void VisitWordCompare(InstructionSelector* selector, Node* node,
|
||||
bool commutative, bool requires_output) {
|
||||
ArmOperandGenerator g(selector);
|
||||
Int32BinopMatcher m(node);
|
||||
InstructionOperand* inputs[5];
|
||||
size_t input_count = 0;
|
||||
InstructionOperand* outputs[1];
|
||||
size_t output_count = 0;
|
||||
|
||||
Node* left = m.left().node();
|
||||
Node* right = m.right().node();
|
||||
if (g.CanBeImmediate(m.left().node(), opcode) || m.left().IsWord32Sar() ||
|
||||
m.left().IsWord32Shl() || m.left().IsWord32Shr()) {
|
||||
if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
|
||||
&input_count, &inputs[1])) {
|
||||
inputs[0] = g.UseRegister(m.left().node());
|
||||
input_count++;
|
||||
} else if (TryMatchImmediateOrShift(selector, &opcode, m.left().node(),
|
||||
&input_count, &inputs[1])) {
|
||||
if (!commutative) cont->Commute();
|
||||
std::swap(left, right);
|
||||
inputs[0] = g.UseRegister(m.right().node());
|
||||
input_count++;
|
||||
} else {
|
||||
opcode |= AddressingModeField::encode(kMode_Operand2_R);
|
||||
inputs[input_count++] = g.UseRegister(m.left().node());
|
||||
inputs[input_count++] = g.UseRegister(m.right().node());
|
||||
}
|
||||
|
||||
opcode = cont->Encode(opcode);
|
||||
if (cont->IsBranch()) {
|
||||
InstructionOperand* outputs[1];
|
||||
size_t output_count = 0;
|
||||
if (requires_output) {
|
||||
outputs[output_count++] = g.DefineAsRegister(node);
|
||||
}
|
||||
InstructionOperand* labels[] = {g.Label(cont->true_block()),
|
||||
g.Label(cont->false_block())};
|
||||
const size_t label_count = ARRAY_SIZE(labels);
|
||||
EmitBinop(selector, opcode, output_count, outputs, left, right, label_count,
|
||||
labels)->MarkAsControl();
|
||||
inputs[input_count++] = g.Label(cont->true_block());
|
||||
inputs[input_count++] = g.Label(cont->false_block());
|
||||
} else {
|
||||
ASSERT(cont->IsSet());
|
||||
EmitBinop(selector, opcode, cont->result(), left, right);
|
||||
outputs[output_count++] = g.DefineAsRegister(cont->result());
|
||||
}
|
||||
|
||||
ASSERT_NE(0, input_count);
|
||||
ASSERT_GE(ARRAY_SIZE(inputs), input_count);
|
||||
ASSERT_GE(ARRAY_SIZE(outputs), output_count);
|
||||
|
||||
Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
|
||||
outputs, input_count, inputs);
|
||||
if (cont->IsBranch()) instr->MarkAsControl();
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,6 +101,25 @@ class RawMachineAssemblerTester
|
||||
: MachineAssemblerTester<RawMachineAssembler>(
|
||||
ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3,
|
||||
p4) {}
|
||||
|
||||
template <typename Ci, typename Fn>
|
||||
void Run(const Ci& ci, const Fn& fn) {
|
||||
typename Ci::const_iterator i;
|
||||
for (i = ci.begin(); i != ci.end(); ++i) {
|
||||
CHECK_EQ(fn(*i), this->Call(*i));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ci, typename Cj, typename Fn>
|
||||
void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
|
||||
typename Ci::const_iterator i;
|
||||
typename Cj::const_iterator j;
|
||||
for (i = ci.begin(); i != ci.end(); ++i) {
|
||||
for (j = cj.begin(); j != cj.end(); ++j) {
|
||||
CHECK_EQ(fn(*i, *j), this->Call(*i, *j));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -163,6 +182,17 @@ class BinopTester {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ci, typename Cj, typename Fn>
|
||||
void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
|
||||
typename Ci::const_iterator i;
|
||||
typename Cj::const_iterator j;
|
||||
for (i = ci.begin(); i != ci.end(); ++i) {
|
||||
for (j = cj.begin(); j != cj.end(); ++j) {
|
||||
CHECK_EQ(fn(*i, *j), this->call(*i, *j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
CType p0;
|
||||
CType p1;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <list>
|
||||
|
||||
#include "test/cctest/compiler/instruction-selector-tester.h"
|
||||
#include "test/cctest/compiler/value-helper.h"
|
||||
|
||||
using namespace v8::internal;
|
||||
using namespace v8::internal::compiler;
|
||||
@ -130,6 +131,66 @@ TEST(InstructionSelectorDPIAndShiftP) {
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorDPIAndRotateRightP) {
|
||||
DPIs dpis;
|
||||
for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
|
||||
DPI dpi = *i;
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror = m.Word32Or(
|
||||
m.Word32Shr(value, shift),
|
||||
m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
|
||||
m.Return(m.NewNode(dpi.op, m.Parameter(0), ror));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror =
|
||||
m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
|
||||
m.Word32Shr(value, shift));
|
||||
m.Return(m.NewNode(dpi.op, m.Parameter(0), ror));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror = m.Word32Or(
|
||||
m.Word32Shr(value, shift),
|
||||
m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
|
||||
m.Return(m.NewNode(dpi.op, ror, m.Parameter(0)));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror =
|
||||
m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
|
||||
m.Word32Shr(value, shift));
|
||||
m.Return(m.NewNode(dpi.op, ror, m.Parameter(0)));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorDPIAndShiftImm) {
|
||||
DPIs dpis;
|
||||
Shifts shifts;
|
||||
@ -224,6 +285,100 @@ TEST(InstructionSelectorWord32XorWithMinus1P) {
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorShiftP) {
|
||||
Shifts shifts;
|
||||
for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
|
||||
Shift shift = *i;
|
||||
InstructionSelectorTester m;
|
||||
m.Return(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(2, m.code[0]->InputCount());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorShiftImm) {
|
||||
Shifts shifts;
|
||||
for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) {
|
||||
Shift shift = *i;
|
||||
for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) {
|
||||
InstructionSelectorTester m;
|
||||
m.Return(m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(2, m.code[0]->InputCount());
|
||||
CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorRotateRightP) {
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(0);
|
||||
Node* shift = m.Parameter(1);
|
||||
m.Return(
|
||||
m.Word32Or(m.Word32Shr(value, shift),
|
||||
m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift))));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(2, m.code[0]->InputCount());
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(0);
|
||||
Node* shift = m.Parameter(1);
|
||||
m.Return(
|
||||
m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
|
||||
m.Word32Shr(value, shift)));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(2, m.code[0]->InputCount());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorRotateRightImm) {
|
||||
FOR_INPUTS(uint32_t, ror, i) {
|
||||
uint32_t shift = *i;
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(0);
|
||||
m.Return(m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)),
|
||||
m.Word32Shl(value, m.Int32Constant(32 - shift))));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(2, m.code[0]->InputCount());
|
||||
CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1)));
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
Node* value = m.Parameter(0);
|
||||
m.Return(m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)),
|
||||
m.Word32Shr(value, m.Int32Constant(shift))));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmMov, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(2, m.code[0]->InputCount());
|
||||
CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorInt32MulP) {
|
||||
InstructionSelectorTester m;
|
||||
m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
|
||||
@ -919,6 +1074,185 @@ TEST(InstructionSelectorBranchWithWord32EqualAndShiftImm) {
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorBranchWithWord32EqualAndRotateRightP) {
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror =
|
||||
m.Word32Or(m.Word32Shr(value, shift),
|
||||
m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
|
||||
m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror =
|
||||
m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
|
||||
m.Word32Shr(value, shift));
|
||||
m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror =
|
||||
m.Word32Or(m.Word32Shr(value, shift),
|
||||
m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)));
|
||||
m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* shift = m.Parameter(2);
|
||||
Node* ror =
|
||||
m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)),
|
||||
m.Word32Shr(value, shift));
|
||||
m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorBranchWithWord32EqualAndRotateRightImm) {
|
||||
FOR_INPUTS(uint32_t, ror, i) {
|
||||
uint32_t shift = *i;
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* ror = m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)),
|
||||
m.Word32Shl(value, m.Int32Constant(32 - shift)));
|
||||
m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
CHECK_LE(3, m.code[0]->InputCount());
|
||||
CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* ror = m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)),
|
||||
m.Word32Shr(value, m.Int32Constant(shift)));
|
||||
m.Branch(m.Word32Equal(input, ror), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
CHECK_LE(3, m.code[0]->InputCount());
|
||||
CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* ror = m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)),
|
||||
m.Word32Shl(value, m.Int32Constant(32 - shift)));
|
||||
m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
CHECK_LE(3, m.code[0]->InputCount());
|
||||
CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
|
||||
}
|
||||
{
|
||||
InstructionSelectorTester m;
|
||||
MLabel blocka, blockb;
|
||||
Node* input = m.Parameter(0);
|
||||
Node* value = m.Parameter(1);
|
||||
Node* ror = m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)),
|
||||
m.Word32Shr(value, m.Int32Constant(shift)));
|
||||
m.Branch(m.Word32Equal(ror, input), &blocka, &blockb);
|
||||
m.Bind(&blocka);
|
||||
m.Return(m.Int32Constant(1));
|
||||
m.Bind(&blockb);
|
||||
m.Return(m.Int32Constant(0));
|
||||
m.SelectInstructions();
|
||||
CHECK_EQ(1, m.code.size());
|
||||
CHECK_EQ(kArmCmp, m.code[0]->arch_opcode());
|
||||
CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode());
|
||||
CHECK_EQ(kFlags_branch, m.code[0]->flags_mode());
|
||||
CHECK_EQ(kEqual, m.code[0]->flags_condition());
|
||||
CHECK_LE(3, m.code[0]->InputCount());
|
||||
CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(InstructionSelectorBranchWithDPIP) {
|
||||
DPIs dpis;
|
||||
for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) {
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "test/cctest/cctest.h"
|
||||
#include "test/cctest/compiler/codegen-tester.h"
|
||||
@ -3680,6 +3680,53 @@ TEST(RunTestIntPtrArithmetic) {
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t rotr32(uint32_t i, uint32_t j) {
|
||||
return (i >> j) | (i << (32 - j));
|
||||
}
|
||||
|
||||
|
||||
TEST(RunTestInt32RotateRightP) {
|
||||
{
|
||||
RawMachineAssemblerTester<int32_t> m;
|
||||
Int32BinopTester bt(&m);
|
||||
bt.AddReturn(m.Word32Or(
|
||||
m.Word32Shr(bt.param0, bt.param1),
|
||||
m.Word32Shl(bt.param0, m.Int32Sub(m.Int32Constant(32), bt.param1))));
|
||||
bt.Run(ValueHelper::uint32_vector(), ValueHelper::ror_vector(), rotr32);
|
||||
}
|
||||
{
|
||||
RawMachineAssemblerTester<int32_t> m;
|
||||
Int32BinopTester bt(&m);
|
||||
bt.AddReturn(m.Word32Or(
|
||||
m.Word32Shl(bt.param0, m.Int32Sub(m.Int32Constant(32), bt.param1)),
|
||||
m.Word32Shr(bt.param0, bt.param1)));
|
||||
bt.Run(ValueHelper::uint32_vector(), ValueHelper::ror_vector(), rotr32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(RunTestInt32RotateRightImm) {
|
||||
FOR_INPUTS(uint32_t, ror, i) {
|
||||
{
|
||||
RawMachineAssemblerTester<int32_t> m(kMachineWord32);
|
||||
Node* value = m.Parameter(0);
|
||||
m.Return(m.Word32Or(m.Word32Shr(value, m.Int32Constant(*i)),
|
||||
m.Word32Shl(value, m.Int32Constant(32 - *i))));
|
||||
m.Run(ValueHelper::uint32_vector(),
|
||||
std::bind2nd(std::ptr_fun(&rotr32), *i));
|
||||
}
|
||||
{
|
||||
RawMachineAssemblerTester<int32_t> m(kMachineWord32);
|
||||
Node* value = m.Parameter(0);
|
||||
m.Return(m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - *i)),
|
||||
m.Word32Shr(value, m.Int32Constant(*i))));
|
||||
m.Run(ValueHelper::uint32_vector(),
|
||||
std::bind2nd(std::ptr_fun(&rotr32), *i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(RunSpillLotsOfThings) {
|
||||
static const int kInputSize = 1000;
|
||||
RawMachineAssemblerTester<void> m;
|
||||
|
@ -104,6 +104,13 @@ class ValueHelper {
|
||||
V8_INFINITY * 0.0, nan};
|
||||
return std::vector<double>(&values[0], &values[ARRAY_SIZE(values)]);
|
||||
}
|
||||
|
||||
static const std::vector<uint32_t> ror_vector() {
|
||||
static const uint32_t kValues[31] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||
return std::vector<uint32_t>(&kValues[0], &kValues[ARRAY_SIZE(kValues)]);
|
||||
}
|
||||
};
|
||||
|
||||
// Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... }
|
||||
@ -116,8 +123,9 @@ class ValueHelper {
|
||||
#define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var)
|
||||
#define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var)
|
||||
#define FOR_FLOAT64_INPUTS(var) FOR_INPUTS(double, float64, var)
|
||||
}
|
||||
}
|
||||
} // namespace v8::internal::compiler
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_CCTEST_COMPILER_VALUE_HELPER_H_
|
||||
|
Loading…
Reference in New Issue
Block a user