Revision: 12855
Author: [email protected]
Date: Mon Nov 5 05:28:10 2012
Log: Add rotate-right instruction to hydrogen and use it instead of
bitwise operations
of the form ((x >>> i) | (x << (32 - i))).
This CL is based on https://chromiumcodereview.appspot.com/10984057/
by Jay Conrod <[email protected]>.
[email protected],[email protected],[email protected]
Review URL: https://chromiumcodereview.appspot.com/11033005
http://code.google.com/p/v8/source/detail?r=12855
Added:
/branches/bleeding_edge/test/mjsunit/compiler/rotate.js
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/simulator-arm.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/ia32/assembler-ia32.cc
/branches/bleeding_edge/src/ia32/assembler-ia32.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/token.h
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/compiler/rotate.js Mon Nov 5
05:28:10 2012
@@ -0,0 +1,224 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+// Test shift operations that can be replaced by rotate operation.
+
+function SideEffect() {
+ with ({}) { } // not inlinable
+}
+
+function Twenty() {
+ SideEffect();
+ return 20;
+}
+
+function Twelve() {
+ SideEffect();
+ return 12;
+}
+
+
+function ROR(x, sa) {
+ return (x >>> sa) | (x << (32 - sa));
+}
+
+function ROR1(x, sa) {
+ return (x >>> sa) | (x << (32 - sa));
+}
+
+function ROR2(x, sa) {
+ return (x >>> (32 - sa)) | (x << (sa));
+}
+
+function ROR3(x, sa) {
+ return (x << (32 - sa)) | (x >>> sa);
+}
+
+function ROR4(x, sa) {
+ return (x << (sa)) | (x >>> (32 - sa));
+}
+
+assertEquals(1 << ((2 % 32)), ROR(1, 30));
+assertEquals(1 << ((2 % 32)), ROR(1, 30));
+%OptimizeFunctionOnNextCall(ROR);
+assertEquals(1 << ((2 % 32)), ROR(1, 30));
+
+assertEquals(0xF0000FFF | 0, ROR1(0x0000FFFF, 4));
+assertEquals(0xF0000FFF | 0, ROR1(0x0000FFFF, 4));
+%OptimizeFunctionOnNextCall(ROR1);
+assertEquals(0xF0000FFF | 0, ROR1(0x0000FFFF, 4));
+
+assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, 20));
+assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, 20));
+%OptimizeFunctionOnNextCall(ROR1);
+assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, 20));
+
+assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, Twenty()));
+assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, Twenty()));
+%OptimizeFunctionOnNextCall(ROR1);
+assertEquals(0x0FFFF000 | 0, ROR1(0x0000FFFF, Twenty()));
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(0xFFFFFFFF | 0, ROR1(0xFFFFFFFF, i));
+ assertEquals(0xFFFFFFFF | 0, ROR1(0xFFFFFFFF, i));
+ %OptimizeFunctionOnNextCall(ROR1);
+ assertEquals(0xFFFFFFFF | 0, ROR1(0xFFFFFFFF, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(-1, ROR1(-1, i));
+ assertEquals(-1, ROR1(-1, i));
+ %OptimizeFunctionOnNextCall(ROR1);
+ assertEquals(-1, ROR1(-1, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(1 << (32 - (i % 32)), ROR1(1, i));
+ assertEquals(1 << (32 - (i % 32)), ROR1(1, i));
+ %OptimizeFunctionOnNextCall(ROR1);
+ assertEquals(1 << (32 - (i % 32)), ROR1(1, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(1 << (32 - (i % 32)), ROR1(1.4, i));
+ assertEquals(1 << (32 - (i % 32)), ROR1(1.4, i));
+ %OptimizeFunctionOnNextCall(ROR1);
+ assertEquals(1 << (32 - (i % 32)), ROR1(1.4, i));
+}
+
+
+
+assertEquals(0xF0000FFF | 0, ROR2(0x0000FFFF, 28));
+assertEquals(0xF0000FFF | 0, ROR2(0x0000FFFF, 28));
+%OptimizeFunctionOnNextCall(ROR2);
+assertEquals(0xF0000FFF | 0, ROR2(0x0000FFFF, 28));
+
+assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, 12));
+assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, 12));
+%OptimizeFunctionOnNextCall(ROR2);
+assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, 12));
+
+assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, Twelve()));
+assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, Twelve()));
+%OptimizeFunctionOnNextCall(ROR2);
+assertEquals(0x0FFFF000 | 0, ROR2(0x0000FFFF, Twelve()));
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(0xFFFFFFFF | 0, ROR2(0xFFFFFFFF, i));
+ assertEquals(0xFFFFFFFF | 0, ROR2(0xFFFFFFFF, i));
+ %OptimizeFunctionOnNextCall(ROR2);
+ assertEquals(0xFFFFFFFF | 0, ROR2(0xFFFFFFFF, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(-1, ROR2(-1, i));
+ assertEquals(-1, ROR2(-1, i));
+ %OptimizeFunctionOnNextCall(ROR2);
+ assertEquals(-1, ROR2(-1, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(1 << ((i % 32)), ROR2(1, i));
+ assertEquals(1 << ((i % 32)), ROR2(1, i));
+ %OptimizeFunctionOnNextCall(ROR2);
+ assertEquals(1 << ((i % 32)), ROR2(1, i));
+}
+
+assertEquals(0xF0000FFF | 0, ROR3(0x0000FFFF, 4));
+assertEquals(0xF0000FFF | 0, ROR3(0x0000FFFF, 4));
+%OptimizeFunctionOnNextCall(ROR3);
+assertEquals(0xF0000FFF | 0, ROR3(0x0000FFFF, 4));
+
+assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, 20));
+assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, 20));
+%OptimizeFunctionOnNextCall(ROR3);
+assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, 20));
+
+assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, Twenty()));
+assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, Twenty()));
+%OptimizeFunctionOnNextCall(ROR3);
+assertEquals(0x0FFFF000 | 0, ROR3(0x0000FFFF, Twenty()));
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(0xFFFFFFFF | 0, ROR3(0xFFFFFFFF, i));
+ assertEquals(0xFFFFFFFF | 0, ROR3(0xFFFFFFFF, i));
+ %OptimizeFunctionOnNextCall(ROR3);
+ assertEquals(0xFFFFFFFF | 0, ROR3(0xFFFFFFFF, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(-1, ROR3(-1, i));
+ assertEquals(-1, ROR3(-1, i));
+ %OptimizeFunctionOnNextCall(ROR3);
+ assertEquals(-1, ROR3(-1, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(1 << (32 - (i % 32)), ROR3(1, i));
+ assertEquals(1 << (32 - (i % 32)), ROR3(1, i));
+ %OptimizeFunctionOnNextCall(ROR3);
+ assertEquals(1 << (32 - (i % 32)), ROR3(1, i));
+}
+
+assertEquals(0xF0000FFF | 0, ROR4(0x0000FFFF, 28));
+assertEquals(0xF0000FFF | 0, ROR4(0x0000FFFF, 28));
+%OptimizeFunctionOnNextCall(ROR4);
+assertEquals(0xF0000FFF | 0, ROR4(0x0000FFFF, 28));
+
+assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, 12));
+assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, 12));
+%OptimizeFunctionOnNextCall(ROR4);
+assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, 12));
+
+assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, Twelve()));
+assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, Twelve()));
+%OptimizeFunctionOnNextCall(ROR4);
+assertEquals(0x0FFFF000 | 0, ROR4(0x0000FFFF, Twelve()));
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(0xFFFFFFFF | 0, ROR4(0xFFFFFFFF, i));
+ assertEquals(0xFFFFFFFF | 0, ROR4(0xFFFFFFFF, i));
+ %OptimizeFunctionOnNextCall(ROR4);
+ assertEquals(0xFFFFFFFF | 0, ROR4(0xFFFFFFFF, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(-1, ROR4(-1, i));
+ assertEquals(-1, ROR4(-1, i));
+ %OptimizeFunctionOnNextCall(ROR4);
+ assertEquals(-1, ROR4(-1, i));
+}
+
+for (var i = 0; i <= 100; i++) {
+ assertEquals(1 << ((i % 32)), ROR4(1, i));
+ assertEquals(1 << ((i % 32)), ROR4(1, i));
+ %OptimizeFunctionOnNextCall(ROR4);
+ assertEquals(1 << ((i % 32)), ROR4(1, i));
+}
+
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Mon Nov 5 00:53:54 2012
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Mon Nov 5 05:28:10 2012
@@ -177,6 +177,7 @@
case Token::BIT_AND: return "bit-and-t";
case Token::BIT_OR: return "bit-or-t";
case Token::BIT_XOR: return "bit-xor-t";
+ case Token::ROR: return "ror-t";
case Token::SHL: return "shl-t";
case Token::SAR: return "sar-t";
case Token::SHR: return "shr-t";
@@ -1097,6 +1098,11 @@
argument_count_ -= instr->argument_count();
return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, r0), instr);
}
+
+
+LInstruction* LChunkBuilder::DoRor(HRor* instr) {
+ return DoShift(Token::ROR, instr);
+}
LInstruction* LChunkBuilder::DoShr(HShr* instr) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Nov 5
00:53:54 2012
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Nov 5
05:28:10 2012
@@ -1489,6 +1489,9 @@
// Mask the right_op operand.
__ and_(scratch, ToRegister(right_op), Operand(0x1F));
switch (instr->op()) {
+ case Token::ROR:
+ __ mov(result, Operand(left, ROR, scratch));
+ break;
case Token::SAR:
__ mov(result, Operand(left, ASR, scratch));
break;
@@ -1512,6 +1515,13 @@
int value = ToInteger32(LConstantOperand::cast(right_op));
uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
switch (instr->op()) {
+ case Token::ROR:
+ if (shift_count != 0) {
+ __ mov(result, Operand(left, ROR, shift_count));
+ } else {
+ __ Move(result, left);
+ }
+ break;
case Token::SAR:
if (shift_count != 0) {
__ mov(result, Operand(left, ASR, shift_count));
=======================================
--- /branches/bleeding_edge/src/arm/simulator-arm.cc Mon Oct 15 08:42:09
2012
+++ /branches/bleeding_edge/src/arm/simulator-arm.cc Mon Nov 5 05:28:10
2012
@@ -1459,7 +1459,14 @@
}
case ROR: {
- UNIMPLEMENTED();
+ if (shift_amount == 0) {
+ *carry_out = c_flag_;
+ } else {
+ uint32_t left = static_cast<uint32_t>(result) >> shift_amount;
+ uint32_t right = static_cast<uint32_t>(result) << (32 -
shift_amount);
+ result = right | left;
+ *carry_out = (static_cast<uint32_t>(result) >> 31) != 0;
+ }
break;
}
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Nov 5 00:53:54
2012
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon Nov 5 05:28:10
2012
@@ -152,6 +152,7 @@
V(Random) \
V(RegExpLiteral) \
V(Return) \
+ V(Ror) \
V(Sar) \
V(Shl) \
V(Shr) \
@@ -3729,6 +3730,25 @@
};
+class HRor: public HBitwiseBinaryOperation {
+ public:
+ HRor(HValue* context, HValue* left, HValue* right)
+ : HBitwiseBinaryOperation(context, left, right) {
+ ChangeRepresentation(Representation::Integer32());
+ }
+
+ static HInstruction* NewHRor(Zone* zone,
+ HValue* context,
+ HValue* left,
+ HValue* right);
+
+ DECLARE_CONCRETE_INSTRUCTION(Ror)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
+};
+
+
class HOsrEntry: public HTemplateInstruction<0> {
public:
explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Mon Nov 5 02:06:24 2012
+++ /branches/bleeding_edge/src/hydrogen.cc Mon Nov 5 05:28:10 2012
@@ -8226,6 +8226,61 @@
return new(zone()) HStringCharCodeAt(context, string, checked_index);
}
+// Checks if the given shift amounts have form: (sa) and (32 - sa).
+static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
+ HValue* const32_minus_sa) {
+ if (!const32_minus_sa->IsSub()) return false;
+ HSub* sub = HSub::cast(const32_minus_sa);
+ HValue* const32 = sub->left();
+ if (!const32->IsConstant() ||
+ HConstant::cast(const32)->Integer32Value() != 32) {
+ return false;
+ }
+ return (sub->right() == sa);
+}
+
+
+// Checks if the left and the right are shift instructions with the oposite
+// directions that can be replaced by one rotate right instruction or not.
+// Returns the operand and the shift amount for the rotate instruction in
the
+// former case.
+bool HGraphBuilder::MatchRotateRight(HValue* left,
+ HValue* right,
+ HValue** operand,
+ HValue** shift_amount) {
+ HShl* shl;
+ HShr* shr;
+ if (left->IsShl() && right->IsShr()) {
+ shl = HShl::cast(left);
+ shr = HShr::cast(right);
+ } else if (left->IsShr() && right->IsShl()) {
+ shl = HShl::cast(right);
+ shr = HShr::cast(left);
+ } else {
+ return false;
+ }
+
+ if (!ShiftAmountsAllowReplaceByRotate(shl->right(), shr->right()) &&
+ !ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) {
+ return false;
+ }
+ *operand= shr->left();
+ *shift_amount = shr->right();
+ return true;
+}
+
+
+bool CanBeZero(HValue *right) {
+ if (right->IsConstant()) {
+ HConstant* right_const = HConstant::cast(right);
+ if (right_const->HasInteger32Value() &&
+ (right_const->Integer32Value() & 0x1f) != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
HValue* left,
@@ -8264,25 +8319,26 @@
break;
case Token::BIT_XOR:
case Token::BIT_AND:
- case Token::BIT_OR:
instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left,
right);
break;
+ case Token::BIT_OR: {
+ HValue* operand, *shift_amount;
+ if (info.IsInteger32() &&
+ MatchRotateRight(left, right, &operand, &shift_amount)) {
+ instr = new(zone()) HRor(context, operand, shift_amount);
+ } else {
+ instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left,
right);
+ }
+ break;
+ }
case Token::SAR:
instr = HSar::NewHSar(zone(), context, left, right);
break;
case Token::SHR:
instr = HShr::NewHShr(zone(), context, left, right);
- if (FLAG_opt_safe_uint32_operations && instr->IsShr()) {
- bool can_be_shift_by_zero = true;
- if (right->IsConstant()) {
- HConstant* right_const = HConstant::cast(right);
- if (right_const->HasInteger32Value() &&
- (right_const->Integer32Value() & 0x1f) != 0) {
- can_be_shift_by_zero = false;
- }
- }
-
- if (can_be_shift_by_zero) graph()->RecordUint32Instruction(instr);
+ if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
+ CanBeZero(right)) {
+ graph()->RecordUint32Instruction(instr);
}
break;
case Token::SHL:
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Mon Nov 5 02:06:24 2012
+++ /branches/bleeding_edge/src/hydrogen.h Mon Nov 5 05:28:10 2012
@@ -270,6 +270,7 @@
void DehoistSimpleArrayIndexComputations();
void DeadCodeElimination();
void PropagateDeoptimizingMark();
+ void EliminateUnusedInstructions();
// Returns false if there are phi-uses of the arguments-object
// which are not supported by the optimizing compiler.
@@ -1220,6 +1221,11 @@
HValue* receiver,
Handle<Map> receiver_map);
+ bool MatchRotateRight(HValue* left,
+ HValue* right,
+ HValue** operand,
+ HValue** shift_amount);
+
Zone* zone() const { return zone_; }
// The translation state of the currently-being-translated function.
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc Mon Oct 22 08:59:58
2012
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc Mon Nov 5 05:28:10
2012
@@ -1063,6 +1063,25 @@
EMIT(imm8);
}
}
+
+void Assembler::ror(Register dst, uint8_t imm8) {
+ EnsureSpace ensure_space(this);
+ ASSERT(is_uint5(imm8)); // illegal shift count
+ if (imm8 == 1) {
+ EMIT(0xD1);
+ EMIT(0xC8 | dst.code());
+ } else {
+ EMIT(0xC1);
+ EMIT(0xC8 | dst.code());
+ EMIT(imm8);
+ }
+}
+
+void Assembler::ror_cl(Register dst) {
+ EnsureSpace ensure_space(this);
+ EMIT(0xD3);
+ EMIT(0xC8 | dst.code());
+}
void Assembler::sar(Register dst, uint8_t imm8) {
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Thu Oct 18 05:21:42
2012
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Mon Nov 5 05:28:10
2012
@@ -817,6 +817,8 @@
void rcl(Register dst, uint8_t imm8);
void rcr(Register dst, uint8_t imm8);
+ void ror(Register dst, uint8_t imm8);
+ void ror_cl(Register dst);
void sar(Register dst, uint8_t imm8);
void sar_cl(Register dst);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Nov 5
00:53:54 2012
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Nov 5
05:28:10 2012
@@ -1300,6 +1300,13 @@
ASSERT(ToRegister(right).is(ecx));
switch (instr->op()) {
+ case Token::ROR:
+ __ ror_cl(ToRegister(left));
+ if (instr->can_deopt()) {
+ __ test(ToRegister(left), Immediate(0x80000000));
+ DeoptimizeIf(not_zero, instr->environment());
+ }
+ break;
case Token::SAR:
__ sar_cl(ToRegister(left));
break;
@@ -1321,6 +1328,14 @@
int value = ToInteger32(LConstantOperand::cast(right));
uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
switch (instr->op()) {
+ case Token::ROR:
+ if (shift_count == 0 && instr->can_deopt()) {
+ __ test(ToRegister(left), Immediate(0x80000000));
+ DeoptimizeIf(not_zero, instr->environment());
+ } else {
+ __ ror(ToRegister(left), shift_count);
+ }
+ break;
case Token::SAR:
if (shift_count != 0) {
__ sar(ToRegister(left), shift_count);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Nov 5 00:53:54
2012
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Nov 5 05:28:10
2012
@@ -179,6 +179,7 @@
case Token::BIT_AND: return "bit-and-t";
case Token::BIT_OR: return "bit-or-t";
case Token::BIT_XOR: return "bit-xor-t";
+ case Token::ROR: return "ror-t";
case Token::SHL: return "sal-t";
case Token::SAR: return "sar-t";
case Token::SHR: return "shr-t";
@@ -1158,6 +1159,11 @@
LOperand* context = UseFixed(instr->context(), esi);
return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), eax),
instr);
}
+
+
+LInstruction* LChunkBuilder::DoRor(HRor* instr) {
+ return DoShift(Token::ROR, instr);
+}
LInstruction* LChunkBuilder::DoShr(HShr* instr) {
=======================================
--- /branches/bleeding_edge/src/token.h Fri Mar 2 05:40:14 2012
+++ /branches/bleeding_edge/src/token.h Mon Nov 5 05:28:10 2012
@@ -99,6 +99,7 @@
T(SHL, "<<", 11) \
T(SAR, ">>", 11) \
T(SHR, ">>>", 11) \
+ T(ROR, "rotate right", 11) /* only used by Crankshaft */ \
T(ADD, "+", 12) \
T(SUB, "-", 12) \
T(MUL, "*", 13) \
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Thu Oct 18 05:21:42 2012
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Mon Nov 5 05:28:10 2012
@@ -1020,6 +1020,14 @@
void ror(Register dst, Immediate imm8) {
shift(dst, imm8, 0x1);
}
+
+ void rorl(Register dst, Immediate imm8) {
+ shift_32(dst, imm8, 0x1);
+ }
+
+ void rorl_cl(Register dst) {
+ shift_32(dst, 0x1);
+ }
// Shifts dst:src left by cl bits, affecting only dst.
void shld(Register dst, Register src);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Nov 5
00:53:54 2012
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Nov 5
05:28:10 2012
@@ -1210,6 +1210,9 @@
ASSERT(ToRegister(right).is(rcx));
switch (instr->op()) {
+ case Token::ROR:
+ __ rorl_cl(ToRegister(left));
+ break;
case Token::SAR:
__ sarl_cl(ToRegister(left));
break;
@@ -1231,6 +1234,11 @@
int value = ToInteger32(LConstantOperand::cast(right));
uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
switch (instr->op()) {
+ case Token::ROR:
+ if (shift_count != 0) {
+ __ rorl(ToRegister(left), Immediate(shift_count));
+ }
+ break;
case Token::SAR:
if (shift_count != 0) {
__ sarl(ToRegister(left), Immediate(shift_count));
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Mon Nov 5 00:53:54 2012
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Mon Nov 5 05:28:10 2012
@@ -179,6 +179,7 @@
case Token::BIT_AND: return "bit-and-t";
case Token::BIT_OR: return "bit-or-t";
case Token::BIT_XOR: return "bit-xor-t";
+ case Token::ROR: return "ror-t";
case Token::SHL: return "sal-t";
case Token::SAR: return "sar-t";
case Token::SHR: return "shr-t";
@@ -1098,6 +1099,11 @@
argument_count_ -= instr->argument_count();
return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, rax), instr);
}
+
+
+LInstruction* LChunkBuilder::DoRor(HRor* instr) {
+ return DoShift(Token::ROR, instr);
+}
LInstruction* LChunkBuilder::DoShr(HShr* instr) {
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev