Ensure using byte registers for byte instructions on ia32 and x64.
BUG=v8:1945 TEST=regress-1945.js Review URL: https://chromiumcodereview.appspot.com/9418005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10719 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
dd95fee084
commit
cc2780403a
@ -32,7 +32,7 @@
|
||||
|
||||
// The original source code covered by the above license above has been modified
|
||||
// significantly by Google Inc.
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
|
||||
#include "v8.h"
|
||||
|
||||
@ -575,7 +575,7 @@ void Assembler::leave() {
|
||||
|
||||
|
||||
void Assembler::mov_b(Register dst, const Operand& src) {
|
||||
ASSERT(dst.code() < 4);
|
||||
CHECK(dst.is_byte_register());
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x8A);
|
||||
emit_operand(dst, src);
|
||||
@ -591,7 +591,7 @@ void Assembler::mov_b(const Operand& dst, int8_t imm8) {
|
||||
|
||||
|
||||
void Assembler::mov_b(const Operand& dst, Register src) {
|
||||
ASSERT(src.code() < 4);
|
||||
CHECK(src.is_byte_register());
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x88);
|
||||
emit_operand(src, dst);
|
||||
@ -829,7 +829,7 @@ void Assembler::cmpb(const Operand& op, int8_t imm8) {
|
||||
|
||||
|
||||
void Assembler::cmpb(const Operand& op, Register reg) {
|
||||
ASSERT(reg.is_byte_register());
|
||||
CHECK(reg.is_byte_register());
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x38);
|
||||
emit_operand(reg, op);
|
||||
@ -837,7 +837,7 @@ void Assembler::cmpb(const Operand& op, Register reg) {
|
||||
|
||||
|
||||
void Assembler::cmpb(Register reg, const Operand& op) {
|
||||
ASSERT(reg.is_byte_register());
|
||||
CHECK(reg.is_byte_register());
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x3A);
|
||||
emit_operand(reg, op);
|
||||
@ -901,6 +901,7 @@ void Assembler::cmpw_ax(const Operand& op) {
|
||||
|
||||
|
||||
void Assembler::dec_b(Register dst) {
|
||||
CHECK(dst.is_byte_register());
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0xFE);
|
||||
EMIT(0xC8 | dst.code());
|
||||
@ -1174,7 +1175,9 @@ void Assembler::test(Register reg, const Immediate& imm) {
|
||||
EnsureSpace ensure_space(this);
|
||||
// Only use test against byte for registers that have a byte
|
||||
// variant: eax, ebx, ecx, and edx.
|
||||
if (imm.rmode_ == RelocInfo::NONE && is_uint8(imm.x_) && reg.code() < 4) {
|
||||
if (imm.rmode_ == RelocInfo::NONE &&
|
||||
is_uint8(imm.x_) &&
|
||||
reg.is_byte_register()) {
|
||||
uint8_t imm8 = imm.x_;
|
||||
if (reg.is(eax)) {
|
||||
EMIT(0xA8);
|
||||
@ -1204,6 +1207,7 @@ void Assembler::test(Register reg, const Operand& op) {
|
||||
|
||||
|
||||
void Assembler::test_b(Register reg, const Operand& op) {
|
||||
CHECK(reg.is_byte_register());
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0x84);
|
||||
emit_operand(reg, op);
|
||||
@ -1219,7 +1223,7 @@ void Assembler::test(const Operand& op, const Immediate& imm) {
|
||||
|
||||
|
||||
void Assembler::test_b(const Operand& op, uint8_t imm8) {
|
||||
if (op.is_reg_only() && op.reg().code() >= 4) {
|
||||
if (op.is_reg_only() && !op.reg().is_byte_register()) {
|
||||
test(op, Immediate(imm8));
|
||||
return;
|
||||
}
|
||||
|
@ -1868,11 +1868,10 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Faster code path to avoid two compares: subtract lower bound from the
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
|
||||
__ mov(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ cmpb(Operand(temp2),
|
||||
static_cast<int8_t>(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ j(above, is_false);
|
||||
}
|
||||
|
||||
@ -4079,7 +4078,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
|
||||
} else {
|
||||
__ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ and_(temp, mask);
|
||||
__ cmpb(Operand(temp), tag);
|
||||
__ cmp(temp, tag);
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// 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:
|
||||
@ -775,7 +775,7 @@ void Assembler::immediate_arithmetic_op_8(byte subcode,
|
||||
Register dst,
|
||||
Immediate src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
if (dst.code() > 3) {
|
||||
if (!dst.is_byte_register()) {
|
||||
// Use 64-bit mode byte registers.
|
||||
emit_rex_64(dst);
|
||||
}
|
||||
@ -1059,7 +1059,7 @@ void Assembler::decl(const Operand& dst) {
|
||||
|
||||
void Assembler::decb(Register dst) {
|
||||
EnsureSpace ensure_space(this);
|
||||
if (dst.code() > 3) {
|
||||
if (!dst.is_byte_register()) {
|
||||
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
|
||||
emit_rex_32(dst);
|
||||
}
|
||||
@ -1387,7 +1387,7 @@ void Assembler::leave() {
|
||||
|
||||
void Assembler::movb(Register dst, const Operand& src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
if (dst.code() > 3) {
|
||||
if (!dst.is_byte_register()) {
|
||||
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
|
||||
emit_rex_32(dst, src);
|
||||
} else {
|
||||
@ -1400,7 +1400,7 @@ void Assembler::movb(Register dst, const Operand& src) {
|
||||
|
||||
void Assembler::movb(Register dst, Immediate imm) {
|
||||
EnsureSpace ensure_space(this);
|
||||
if (dst.code() > 3) {
|
||||
if (!dst.is_byte_register()) {
|
||||
emit_rex_32(dst);
|
||||
}
|
||||
emit(0xB0 + dst.low_bits());
|
||||
@ -1410,7 +1410,7 @@ void Assembler::movb(Register dst, Immediate imm) {
|
||||
|
||||
void Assembler::movb(const Operand& dst, Register src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
if (src.code() > 3) {
|
||||
if (!src.is_byte_register()) {
|
||||
emit_rex_32(src, dst);
|
||||
} else {
|
||||
emit_optional_rex_32(src, dst);
|
||||
@ -1931,7 +1931,7 @@ void Assembler::setcc(Condition cc, Register reg) {
|
||||
}
|
||||
EnsureSpace ensure_space(this);
|
||||
ASSERT(is_uint4(cc));
|
||||
if (reg.code() > 3) { // Use x64 byte registers, where different.
|
||||
if (!reg.is_byte_register()) { // Use x64 byte registers, where different.
|
||||
emit_rex_32(reg);
|
||||
}
|
||||
emit(0x0F);
|
||||
@ -1996,7 +1996,7 @@ void Assembler::testb(Register dst, Register src) {
|
||||
emit(0x84);
|
||||
emit_modrm(src, dst);
|
||||
} else {
|
||||
if (dst.code() > 3 || src.code() > 3) {
|
||||
if (!dst.is_byte_register() || !src.is_byte_register()) {
|
||||
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
|
||||
emit_rex_32(dst, src);
|
||||
}
|
||||
@ -2013,7 +2013,7 @@ void Assembler::testb(Register reg, Immediate mask) {
|
||||
emit(0xA8);
|
||||
emit(mask.value_); // Low byte emitted.
|
||||
} else {
|
||||
if (reg.code() > 3) {
|
||||
if (!reg.is_byte_register()) {
|
||||
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
|
||||
emit_rex_32(reg);
|
||||
}
|
||||
@ -2036,7 +2036,7 @@ void Assembler::testb(const Operand& op, Immediate mask) {
|
||||
|
||||
void Assembler::testb(const Operand& op, Register reg) {
|
||||
EnsureSpace ensure_space(this);
|
||||
if (reg.code() > 3) {
|
||||
if (!reg.is_byte_register()) {
|
||||
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
|
||||
emit_rex_32(reg, op);
|
||||
} else {
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
// The original source code covered by the above license above has been
|
||||
// modified significantly by Google Inc.
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
|
||||
// A lightweight X64 Assembler.
|
||||
|
||||
@ -131,6 +131,8 @@ struct Register {
|
||||
}
|
||||
bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
|
||||
bool is(Register reg) const { return code_ == reg.code_; }
|
||||
// rax, rbx, rcx and rdx are byte registers, the rest are not.
|
||||
bool is_byte_register() const { return code_ <= 3; }
|
||||
int code() const {
|
||||
ASSERT(is_valid());
|
||||
return code_;
|
||||
|
@ -1793,11 +1793,10 @@ void LCodeGen::EmitClassOfTest(Label* is_true,
|
||||
// Faster code path to avoid two compares: subtract lower bound from the
|
||||
// actual type and do a signed compare with the width of the type range.
|
||||
__ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
|
||||
__ movq(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ subb(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ cmpb(temp2,
|
||||
Immediate(static_cast<int8_t>(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)));
|
||||
__ movzxbl(temp2, FieldOperand(temp, Map::kInstanceTypeOffset));
|
||||
__ subq(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ cmpq(temp2, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
|
||||
FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
||||
__ j(above, is_false);
|
||||
}
|
||||
|
||||
|
34
test/mjsunit/regress/regress-1945.js
Normal file
34
test/mjsunit/regress/regress-1945.js
Normal file
@ -0,0 +1,34 @@
|
||||
// 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
|
||||
|
||||
var _d = new Date();
|
||||
_d.setHours(0,0,0,0);
|
||||
_d.setHours(0,0,0,0);
|
||||
%OptimizeFunctionOnNextCall(_d.setHours);
|
||||
_d.setHours(0,0,0,0);
|
Loading…
Reference in New Issue
Block a user