Commit 64eae3fc authored by Jacob.Bramley@arm.com's avatar Jacob.Bramley@arm.com

ARM64: Slightly simplify LShiftI and LShiftS.

BUG=
R=ulan@chromium.org

Review URL: https://codereview.chromium.org/494053002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23277 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 37d886bc
...@@ -2203,8 +2203,7 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op, ...@@ -2203,8 +2203,7 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
return DoArithmeticT(op, instr); return DoArithmeticT(op, instr);
} }
DCHECK(instr->representation().IsInteger32() || DCHECK(instr->representation().IsSmiOrInteger32());
instr->representation().IsSmi());
DCHECK(instr->left()->representation().Equals(instr->representation())); DCHECK(instr->left()->representation().Equals(instr->representation()));
DCHECK(instr->right()->representation().Equals(instr->representation())); DCHECK(instr->right()->representation().Equals(instr->representation()));
...@@ -2215,42 +2214,30 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op, ...@@ -2215,42 +2214,30 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
LOperand* left = instr->representation().IsSmi() LOperand* left = instr->representation().IsSmi()
? UseRegister(instr->left()) ? UseRegister(instr->left())
: UseRegisterAtStart(instr->left()); : UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterOrConstantAtStart(instr->right());
HValue* right_value = instr->right();
LOperand* right = NULL; // The only shift that can deoptimize is `left >>> 0`, where left is negative.
LOperand* temp = NULL; // In these cases, the result is a uint32 that is too large for an int32.
int constant_value = 0; bool right_can_be_zero = !instr->right()->IsConstant() ||
if (right_value->IsConstant()) { (JSShiftAmountFromHConstant(instr->right()) == 0);
right = UseConstant(right_value); bool can_deopt = false;
constant_value = JSShiftAmountFromHConstant(right_value); if ((op == Token::SHR) && right_can_be_zero) {
} 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
// result cannot be truncated to int32.
bool does_deopt = false;
if ((op == Token::SHR) && (constant_value == 0)) {
if (FLAG_opt_safe_uint32_operations) { if (FLAG_opt_safe_uint32_operations) {
does_deopt = !instr->CheckFlag(HInstruction::kUint32); can_deopt = !instr->CheckFlag(HInstruction::kUint32);
} else { } else {
does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); can_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
} }
} }
LInstruction* result; LInstruction* result;
if (instr->representation().IsInteger32()) { if (instr->representation().IsInteger32()) {
result = DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); result = DefineAsRegister(new (zone()) LShiftI(op, left, right, can_deopt));
} else { } else {
DCHECK(instr->representation().IsSmi()); DCHECK(instr->representation().IsSmi());
result = DefineAsRegister( result = DefineAsRegister(new (zone()) LShiftS(op, left, right, can_deopt));
new(zone()) LShiftS(op, left, right, temp, does_deopt));
} }
return does_deopt ? AssignEnvironment(result) : result; return can_deopt ? AssignEnvironment(result) : result;
} }
......
...@@ -2733,19 +2733,17 @@ class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> { ...@@ -2733,19 +2733,17 @@ class LShiftI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
}; };
class LShiftS V8_FINAL : public LTemplateInstruction<1, 2, 1> { class LShiftS V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public: public:
LShiftS(Token::Value op, LOperand* left, LOperand* right, LOperand* temp, LShiftS(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
bool can_deopt) : op_(op), can_deopt_(can_deopt) { : op_(op), can_deopt_(can_deopt) {
inputs_[0] = left; inputs_[0] = left;
inputs_[1] = right; inputs_[1] = right;
temps_[0] = temp;
} }
Token::Value op() const { return op_; } Token::Value op() const { return op_; }
LOperand* left() { return inputs_[0]; } LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; } LOperand* right() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
bool can_deopt() const { return can_deopt_; } bool can_deopt() const { return can_deopt_; }
DECLARE_CONCRETE_INSTRUCTION(ShiftS, "shift-s") DECLARE_CONCRETE_INSTRUCTION(ShiftS, "shift-s")
......
...@@ -4926,32 +4926,33 @@ void LCodeGen::DoShiftS(LShiftS* instr) { ...@@ -4926,32 +4926,33 @@ void LCodeGen::DoShiftS(LShiftS* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
Register result = ToRegister(instr->result()); Register result = ToRegister(instr->result());
// Only ROR by register needs a temp.
DCHECK(((instr->op() == Token::ROR) && right_op->IsRegister()) ||
(instr->temp() == NULL));
if (right_op->IsRegister()) { if (right_op->IsRegister()) {
Register right = ToRegister(instr->right()); Register right = ToRegister(instr->right());
// JavaScript shifts only look at the bottom 5 bits of the 'right' operand.
// Since we're handling smis in X registers, we have to extract these bits
// explicitly.
__ Ubfx(result, right, kSmiShift, 5);
switch (instr->op()) { switch (instr->op()) {
case Token::ROR: { case Token::ROR: {
Register temp = ToRegister(instr->temp()); // This is the only case that needs a scratch register. To keep things
__ Ubfx(temp, right, kSmiShift, 5); // simple for the other cases, borrow a MacroAssembler scratch register.
__ SmiUntag(result, left); UseScratchRegisterScope temps(masm());
__ Ror(result.W(), result.W(), temp.W()); Register temp = temps.AcquireW();
__ SmiUntag(temp, left);
__ Ror(result.W(), temp.W(), result.W());
__ SmiTag(result); __ SmiTag(result);
break; break;
} }
case Token::SAR: case Token::SAR:
__ Ubfx(result, right, kSmiShift, 5);
__ Asr(result, left, result); __ Asr(result, left, result);
__ Bic(result, result, kSmiShiftMask); __ Bic(result, result, kSmiShiftMask);
break; break;
case Token::SHL: case Token::SHL:
__ Ubfx(result, right, kSmiShift, 5);
__ Lsl(result, left, result); __ Lsl(result, left, result);
break; break;
case Token::SHR: case Token::SHR:
__ Ubfx(result, right, kSmiShift, 5);
__ Lsr(result, left, result); __ Lsr(result, left, result);
__ Bic(result, result, kSmiShiftMask); __ Bic(result, result, kSmiShiftMask);
if (instr->can_deopt()) { if (instr->can_deopt()) {
......
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