Commit 0eecf982 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

[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
parent ec91e4ef
...@@ -79,6 +79,10 @@ class ArmOperandConverter : public InstructionOperandConverter { ...@@ -79,6 +79,10 @@ class ArmOperandConverter : public InstructionOperandConverter {
return Operand(InputRegister(index + 0), LSR, InputInt5(index + 1)); return Operand(InputRegister(index + 0), LSR, InputInt5(index + 1));
case kMode_Operand2_R_LSR_R: case kMode_Operand2_R_LSR_R:
return Operand(InputRegister(index + 0), LSR, InputRegister(index + 1)); 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(); UNREACHABLE();
return Operand::Zero(); return Operand::Zero();
...@@ -96,6 +100,8 @@ class ArmOperandConverter : public InstructionOperandConverter { ...@@ -96,6 +100,8 @@ class ArmOperandConverter : public InstructionOperandConverter {
case kMode_Operand2_R_LSL_R: case kMode_Operand2_R_LSL_R:
case kMode_Operand2_R_LSR_I: case kMode_Operand2_R_LSR_I:
case kMode_Operand2_R_LSR_R: case kMode_Operand2_R_LSR_R:
case kMode_Operand2_R_ROR_I:
case kMode_Operand2_R_ROR_R:
break; break;
case kMode_Offset_RI: case kMode_Offset_RI:
*first_index += 2; *first_index += 2;
......
...@@ -73,9 +73,11 @@ namespace compiler { ...@@ -73,9 +73,11 @@ namespace compiler {
V(Operand2_R_ASR_I) /* %r0 ASR K */ \ V(Operand2_R_ASR_I) /* %r0 ASR K */ \
V(Operand2_R_LSL_I) /* %r0 LSL K */ \ V(Operand2_R_LSL_I) /* %r0 LSL K */ \
V(Operand2_R_LSR_I) /* %r0 LSR 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_ASR_R) /* %r0 ASR %r1 */ \
V(Operand2_R_LSL_R) /* %r0 LSL %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 compiler
} // namespace internal } // namespace internal
......
...@@ -101,6 +101,25 @@ class RawMachineAssemblerTester ...@@ -101,6 +101,25 @@ class RawMachineAssemblerTester
: MachineAssemblerTester<RawMachineAssembler>( : MachineAssemblerTester<RawMachineAssembler>(
ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3, ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3,
p4) {} 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 { ...@@ -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: protected:
CType p0; CType p0;
CType p1; CType p1;
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <functional>
#include <limits> #include <limits>
#include "src/v8.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
#include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/codegen-tester.h"
...@@ -3680,6 +3680,53 @@ TEST(RunTestIntPtrArithmetic) { ...@@ -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) { TEST(RunSpillLotsOfThings) {
static const int kInputSize = 1000; static const int kInputSize = 1000;
RawMachineAssemblerTester<void> m; RawMachineAssemblerTester<void> m;
......
...@@ -104,6 +104,13 @@ class ValueHelper { ...@@ -104,6 +104,13 @@ class ValueHelper {
V8_INFINITY * 0.0, nan}; V8_INFINITY * 0.0, nan};
return std::vector<double>(&values[0], &values[ARRAY_SIZE(values)]); 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 ... } // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... }
...@@ -116,8 +123,9 @@ class ValueHelper { ...@@ -116,8 +123,9 @@ class ValueHelper {
#define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var) #define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var)
#define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var) #define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var)
#define FOR_FLOAT64_INPUTS(var) FOR_INPUTS(double, float64, var) #define FOR_FLOAT64_INPUTS(var) FOR_INPUTS(double, float64, var)
}
} } // namespace compiler
} // namespace v8::internal::compiler } // namespace internal
} // namespace v8
#endif // V8_CCTEST_COMPILER_VALUE_HELPER_H_ #endif // V8_CCTEST_COMPILER_VALUE_HELPER_H_
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