Revision: 19117
Author: [email protected]
Date: Wed Feb 5 18:45:42 2014 UTC
Log: A64: Implement LShiftS
BUG=
[email protected]
Review URL: https://codereview.chromium.org/151163006
http://code.google.com/p/v8/source/detail?r=19117
Modified:
/branches/experimental/a64/src/a64/lithium-a64.cc
/branches/experimental/a64/src/a64/lithium-a64.h
/branches/experimental/a64/src/a64/lithium-codegen-a64.cc
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.cc Wed Feb 5 17:41:02
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.cc Wed Feb 5 18:45:42
2014 UTC
@@ -2018,18 +2018,22 @@
LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) {
- // TODO(jbramley): Support smis inline, like integers.
- if (instr->representation().IsSmiOrTagged()) {
+ if (instr->representation().IsTagged()) {
return DoArithmeticT(op, instr);
}
- ASSERT(instr->representation().IsInteger32());
+ ASSERT(instr->representation().IsInteger32() ||
+ instr->representation().IsSmi());
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
- LOperand* left = UseRegisterAtStart(instr->left());
+
+ LOperand* left = instr->representation().IsSmi()
+ ? UseRegister(instr->left())
+ : UseRegisterAtStart(instr->left());
HValue* right_value = instr->right();
LOperand* right = NULL;
+ LOperand* temp = NULL;
int constant_value = 0;
if (right_value->IsConstant()) {
right = UseConstant(right_value);
@@ -2037,6 +2041,9 @@
constant_value = constant->Integer32Value() & 0x1f;
} else {
right = UseRegisterAtStart(right_value);
+ if (op == Token::ROR) {
+ temp = TempRegister();
+ }
}
// Shift operations can only deoptimize if we do a logical shift by 0
and the
@@ -2050,8 +2057,15 @@
}
}
- LInstruction* result =
- DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt));
+ LInstruction* result;
+ if (instr->representation().IsInteger32()) {
+ result = DefineAsRegister(new(zone()) LShiftI(op, left, right,
does_deopt));
+ } else {
+ ASSERT(instr->representation().IsSmi());
+ result = DefineAsRegister(
+ new(zone()) LShiftS(op, left, right, temp, does_deopt));
+ }
+
return does_deopt ? AssignEnvironment(result) : result;
}
=======================================
--- /branches/experimental/a64/src/a64/lithium-a64.h Wed Feb 5 17:41:02
2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-a64.h Wed Feb 5 18:45:42
2014 UTC
@@ -163,6 +163,7 @@
V(Return) \
V(SeqStringSetChar) \
V(ShiftI) \
+ V(ShiftS) \
V(SmiTag) \
V(SmiUntag) \
V(StackCheck) \
@@ -2469,6 +2470,29 @@
};
+class LShiftS V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+ LShiftS(Token::Value op, LOperand* left, LOperand* right, LOperand* temp,
+ bool can_deopt) : op_(op), can_deopt_(can_deopt) {
+ inputs_[0] = left;
+ inputs_[1] = right;
+ temps_[0] = temp;
+ }
+
+ Token::Value op() const { return op_; }
+ LOperand* left() { return inputs_[0]; }
+ LOperand* right() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+ bool can_deopt() const { return can_deopt_; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ShiftS, "shift-s")
+
+ private:
+ Token::Value op_;
+ bool can_deopt_;
+};
+
+
class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 2, 1> {
public:
LStoreCodeEntry(LOperand* function, LOperand* code_object,
=======================================
--- /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Wed Feb 5
17:41:02 2014 UTC
+++ /branches/experimental/a64/src/a64/lithium-codegen-a64.cc Wed Feb 5
18:45:42 2014 UTC
@@ -4515,10 +4515,6 @@
case Token::SHL: __ Lsl(result, left, right); break;
case Token::SHR:
if (instr->can_deopt()) {
- // TODO(all): Using conditional compare may be faster here, eg.
- // Deopt if (right == 0) && (left < 0).
- // __ Cmp(right, 0);
- // __ Ccmp(left, 0, NoFlag, eq);
Label right_not_zero;
__ Cbnz(right, &right_not_zero);
DeoptimizeIfNegative(left, instr->environment());
@@ -4547,6 +4543,81 @@
}
}
}
+
+
+void LCodeGen::DoShiftS(LShiftS* instr) {
+ LOperand* right_op = instr->right();
+ Register left = ToRegister(instr->left());
+ Register result = ToRegister(instr->result());
+
+ // Only ROR by register needs a temp.
+ ASSERT(((instr->op() == Token::ROR) && right_op->IsRegister()) ||
+ (instr->temp() == NULL));
+
+ if (right_op->IsRegister()) {
+ Register right = ToRegister(instr->right());
+ switch (instr->op()) {
+ case Token::ROR: {
+ Register temp = ToRegister(instr->temp());
+ __ Ubfx(temp, right, kSmiShift, 5);
+ __ SmiUntag(result, left);
+ __ Ror(result.W(), result.W(), temp.W());
+ __ SmiTag(result);
+ break;
+ }
+ case Token::SAR:
+ __ Ubfx(result, right, kSmiShift, 5);
+ __ Asr(result, left, result);
+ __ Bic(result, result, kSmiShiftMask);
+ break;
+ case Token::SHL:
+ __ Ubfx(result, right, kSmiShift, 5);
+ __ Lsl(result, left, result);
+ break;
+ case Token::SHR:
+ if (instr->can_deopt()) {
+ Label right_not_zero;
+ __ Cbnz(right, &right_not_zero);
+ DeoptimizeIfNegative(left, instr->environment());
+ __ Bind(&right_not_zero);
+ }
+ __ Ubfx(result, right, kSmiShift, 5);
+ __ Lsr(result, left, result);
+ __ Bic(result, result, kSmiShiftMask);
+ break;
+ default: UNREACHABLE();
+ }
+ } else {
+ ASSERT(right_op->IsConstantOperand());
+ int shift_count = ToInteger32(LConstantOperand::cast(right_op)) & 0x1f;
+ if (shift_count == 0) {
+ if ((instr->op() == Token::SHR) && instr->can_deopt()) {
+ DeoptimizeIfNegative(left, instr->environment());
+ }
+ __ Mov(result, left);
+ } else {
+ switch (instr->op()) {
+ case Token::ROR:
+ __ SmiUntag(result, left);
+ __ Ror(result.W(), result.W(), shift_count);
+ __ SmiTag(result);
+ break;
+ case Token::SAR:
+ __ Asr(result, left, shift_count);
+ __ Bic(result, result, kSmiShiftMask);
+ break;
+ case Token::SHL:
+ __ Lsl(result, left, shift_count);
+ break;
+ case Token::SHR:
+ __ Lsr(result, left, shift_count);
+ __ Bic(result, result, kSmiShiftMask);
+ break;
+ default: UNREACHABLE();
+ }
+ }
+ }
+}
void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
--
--
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/groups/opt_out.