Commit 400f6c50 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: Extends testb and cmpb/cmpw instruction support in the ia32 assembler.

  port 22523f25 (r34925)

  original commit message:
  This is in preparation for a CL that does the equivalent of http://crrev.com/1780193003 for ia32.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#34974}
parent 9deff0fa
......@@ -2170,7 +2170,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (expected.CanBeUndetectable()) {
// Undetectable -> false.
__ test_b(FieldOperand(map, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, instr->FalseLabel(chunk_));
}
}
......@@ -2412,7 +2412,7 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
}
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
__ test_b(FieldOperand(temp, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
EmitBranch(instr, not_zero);
}
......@@ -2603,7 +2603,7 @@ void LCodeGen::DoHasInPrototypeChainAndBranch(
// Deoptimize if the object needs to be access checked.
__ test_b(FieldOperand(object_map, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
Immediate(1 << Map::kIsAccessCheckNeeded));
DeoptimizeIf(not_zero, instr, Deoptimizer::kAccessCheck);
// Deoptimize for proxies.
__ CmpInstanceType(object_map, JS_PROXY_TYPE);
......@@ -3129,6 +3129,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
// object as a receiver to normal functions. Values have to be
// passed unchanged to builtins and strict-mode functions.
Label receiver_ok, global_object;
Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
Register scratch = ToRegister(instr->temp());
if (!instr->hydrogen()->known_function()) {
......@@ -3137,20 +3138,20 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
__ mov(scratch,
FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
__ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
1 << SharedFunctionInfo::kStrictModeBitWithinByte);
__ j(not_equal, &receiver_ok);
Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
__ j(not_equal, &receiver_ok, dist);
// Do not transform the receiver to object for builtins.
__ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
1 << SharedFunctionInfo::kNativeBitWithinByte);
__ j(not_equal, &receiver_ok);
Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
__ j(not_equal, &receiver_ok, dist);
}
// Normal function. Replace undefined or null with global receiver.
__ cmp(receiver, factory()->null_value());
__ j(equal, &global_object);
__ j(equal, &global_object, Label::kNear);
__ cmp(receiver, factory()->undefined_value());
__ j(equal, &global_object);
__ j(equal, &global_object, Label::kNear);
// The receiver should be a JS object.
__ test(receiver, Immediate(kSmiTagMask));
......@@ -5061,7 +5062,7 @@ void LCodeGen::DoCheckArrayBufferNotNeutered(
__ mov(scratch, FieldOperand(view, JSArrayBufferView::kBufferOffset));
__ test_b(FieldOperand(scratch, JSArrayBuffer::kBitFieldOffset),
1 << JSArrayBuffer::WasNeutered::kShift);
Immediate(1 << JSArrayBuffer::WasNeutered::kShift));
DeoptimizeIf(not_zero, instr, Deoptimizer::kOutOfBounds);
}
......@@ -5077,8 +5078,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
InstanceType last;
instr->hydrogen()->GetCheckInterval(&first, &last);
__ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
static_cast<int8_t>(first));
__ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), Immediate(first));
// If there is only one type in the interval check for equality.
if (first == last) {
......@@ -5087,8 +5087,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
DeoptimizeIf(below, instr, Deoptimizer::kWrongInstanceType);
// Omit check for the last type.
if (last != LAST_TYPE) {
__ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
static_cast<int8_t>(last));
__ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), Immediate(last));
DeoptimizeIf(above, instr, Deoptimizer::kWrongInstanceType);
}
}
......@@ -5099,7 +5098,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
if (base::bits::IsPowerOfTwo32(mask)) {
DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
__ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask);
__ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), Immediate(mask));
DeoptimizeIf(tag == 0 ? not_zero : zero, instr,
Deoptimizer::kWrongInstanceType);
} else {
......@@ -5535,7 +5534,7 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
// Check for undetectable objects => true.
__ mov(input, FieldOperand(input, HeapObject::kMapOffset));
__ test_b(FieldOperand(input, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
final_branch_condition = not_zero;
} else if (String::Equals(type_name, factory()->function_string())) {
......@@ -5556,7 +5555,7 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
__ j(below, false_label, false_distance);
// Check for callable or undetectable objects => false.
__ test_b(FieldOperand(input, Map::kBitFieldOffset),
(1 << Map::kIsCallable) | (1 << Map::kIsUndetectable));
Immediate((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
final_branch_condition = zero;
// clang-format off
......
......@@ -3679,7 +3679,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
// Check for undetectable objects => true.
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
__ test_b(FieldOperand(edx, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
Split(not_zero, if_true, if_false, fall_through);
} else if (String::Equals(check, factory->function_string())) {
__ JumpIfSmi(eax, if_false);
......@@ -3698,7 +3698,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ j(below, if_false);
// Check for callable or undetectable objects => false.
__ test_b(FieldOperand(edx, Map::kBitFieldOffset),
(1 << Map::kIsCallable) | (1 << Map::kIsUndetectable));
Immediate((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
Split(zero, if_true, if_false, fall_through);
// clang-format off
#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \
......@@ -3812,7 +3812,7 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
__ JumpIfSmi(eax, if_false);
__ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
__ test_b(FieldOperand(eax, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
Split(not_zero, if_true, if_false, fall_through);
}
context()->Plug(if_true, if_false);
......
......@@ -94,7 +94,7 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
// Bail out if the receiver has a named interceptor or requires access checks.
__ test_b(FieldOperand(scratch0, Map::kBitFieldOffset),
kInterceptorOrAccessCheckNeededMask);
Immediate(kInterceptorOrAccessCheckNeededMask));
__ j(not_zero, miss_label);
// Check that receiver is a JSObject.
......
......@@ -150,8 +150,9 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
__ mov(map, FieldOperand(receiver, HeapObject::kMapOffset));
// Check bit field.
__ test_b(FieldOperand(map, Map::kBitFieldOffset),
(1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit));
__ test_b(
FieldOperand(map, Map::kBitFieldOffset),
Immediate((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)));
__ j(not_zero, slow);
// Check that the object is some kind of JS object EXCEPT JS Value type. In
// the case that the object is a value-wrapper object, we enter the runtime
......@@ -202,9 +203,9 @@ static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
// scratch2: map of current prototype
__ CmpInstanceType(scratch2, JS_OBJECT_TYPE);
__ j(below, slow);
__ test_b(
FieldOperand(scratch2, Map::kBitFieldOffset),
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor));
__ test_b(FieldOperand(scratch2, Map::kBitFieldOffset),
Immediate((1 << Map::kIsAccessCheckNeeded) |
(1 << Map::kHasIndexedInterceptor)));
__ j(not_zero, slow);
__ cmp(scratch, masm->isolate()->factory()->empty_fixed_array());
__ j(not_equal, slow);
......@@ -251,7 +252,7 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
// bit test is enough.
STATIC_ASSERT(kNotInternalizedTag != 0);
__ test_b(FieldOperand(map, Map::kInstanceTypeOffset),
kIsNotInternalizedMask);
Immediate(kIsNotInternalizedMask));
__ j(not_zero, not_unique);
__ bind(&unique);
......@@ -521,7 +522,7 @@ void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
// Check that the receiver does not require access checks and is not observed.
// The generic stub does not perform map checks or handle observed objects.
__ test_b(FieldOperand(edi, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved);
Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
__ j(not_zero, &slow);
// Check that the key is a smi.
__ JumpIfNotSmi(key, &maybe_name_key);
......
......@@ -510,7 +510,8 @@ void RegExpMacroAssemblerX87::CheckBitInTable(
__ and_(ebx, current_character());
index = ebx;
}
__ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize), 0);
__ cmpb(FieldOperand(eax, index, times_1, ByteArray::kHeaderSize),
Immediate(0));
BranchOrBacktrack(not_equal, on_bit_set);
}
......
......@@ -452,6 +452,11 @@ void Assembler::emit_code_relative_offset(Label* label) {
}
}
void Assembler::emit_b(Immediate x) {
DCHECK(x.is_int8() || x.is_uint8());
uint8_t value = static_cast<uint8_t>(x.x_);
*pc_++ = value;
}
void Assembler::emit_w(const Immediate& x) {
DCHECK(RelocInfo::IsNone(x.rmode_));
......
......@@ -617,8 +617,8 @@ void Assembler::and_(const Operand& dst, Register src) {
emit_operand(src, dst);
}
void Assembler::cmpb(const Operand& op, int8_t imm8) {
void Assembler::cmpb(const Operand& op, Immediate imm8) {
DCHECK(imm8.is_int8() || imm8.is_uint8());
EnsureSpace ensure_space(this);
if (op.is_reg(eax)) {
EMIT(0x3C);
......@@ -626,7 +626,7 @@ void Assembler::cmpb(const Operand& op, int8_t imm8) {
EMIT(0x80);
emit_operand(edi, op); // edi == 7
}
EMIT(imm8);
emit_b(imm8);
}
......@@ -655,6 +655,19 @@ void Assembler::cmpw(const Operand& op, Immediate imm16) {
emit_w(imm16);
}
void Assembler::cmpw(Register reg, const Operand& op) {
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x39);
emit_operand(reg, op);
}
void Assembler::cmpw(const Operand& op, Register reg) {
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x3B);
emit_operand(reg, op);
}
void Assembler::cmp(Register reg, int32_t imm32) {
EnsureSpace ensure_space(this);
......@@ -1039,8 +1052,8 @@ void Assembler::sub(const Operand& dst, Register src) {
void Assembler::test(Register reg, const Immediate& imm) {
if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
test_b(reg, imm.x_);
if (imm.is_uint8()) {
test_b(reg, imm);
return;
}
......@@ -1077,8 +1090,8 @@ void Assembler::test(const Operand& op, const Immediate& imm) {
test(op.reg(), imm);
return;
}
if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
return test_b(op, imm.x_);
if (imm.is_uint8()) {
return test_b(op, imm);
}
EnsureSpace ensure_space(this);
EMIT(0xF7);
......@@ -1086,25 +1099,25 @@ void Assembler::test(const Operand& op, const Immediate& imm) {
emit(imm);
}
void Assembler::test_b(Register reg, uint8_t imm8) {
void Assembler::test_b(Register reg, Immediate imm8) {
DCHECK(imm8.is_uint8());
EnsureSpace ensure_space(this);
// Only use test against byte for registers that have a byte
// variant: eax, ebx, ecx, and edx.
if (reg.is(eax)) {
EMIT(0xA8);
EMIT(imm8);
emit_b(imm8);
} else if (reg.is_byte_register()) {
emit_arith_b(0xF6, 0xC0, reg, imm8);
emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.x_));
} else {
EMIT(0x66);
EMIT(0xF7);
EMIT(0xC0 | reg.code());
emit(imm8);
emit_w(imm8);
}
}
void Assembler::test_b(const Operand& op, uint8_t imm8) {
void Assembler::test_b(const Operand& op, Immediate imm8) {
if (op.is_reg_only()) {
test_b(op.reg(), imm8);
return;
......@@ -1112,7 +1125,7 @@ void Assembler::test_b(const Operand& op, uint8_t imm8) {
EnsureSpace ensure_space(this);
EMIT(0xF6);
emit_operand(eax, op);
EMIT(imm8);
emit_b(imm8);
}
......
......@@ -282,6 +282,9 @@ class Immediate BASE_EMBEDDED {
bool is_int8() const {
return -128 <= x_ && x_ < 128 && RelocInfo::IsNone(rmode_);
}
bool is_uint8() const {
return v8::internal::is_uint8(x_) && RelocInfo::IsNone(rmode_);
}
bool is_int16() const {
return -32768 <= x_ && x_ < 32768 && RelocInfo::IsNone(rmode_);
}
......@@ -660,13 +663,18 @@ class Assembler : public AssemblerBase {
void and_(const Operand& dst, Register src);
void and_(const Operand& dst, const Immediate& x);
void cmpb(Register reg, int8_t imm8) { cmpb(Operand(reg), imm8); }
void cmpb(const Operand& op, int8_t imm8);
void cmpb(Register reg, Immediate imm8) { cmpb(Operand(reg), imm8); }
void cmpb(const Operand& op, Immediate imm8);
void cmpb(Register reg, const Operand& op);
void cmpb(const Operand& op, Register reg);
void cmpb(Register dst, Register src) { cmpb(Operand(dst), src); }
void cmpb_al(const Operand& op);
void cmpw_ax(const Operand& op);
void cmpw(const Operand& op, Immediate imm16);
void cmpw(const Operand& dst, Immediate src);
void cmpw(Register dst, Immediate src) { cmpw(Operand(dst), src); }
void cmpw(Register dst, const Operand& src);
void cmpw(Register dst, Register src) { cmpw(Operand(dst), src); }
void cmpw(const Operand& dst, Register src);
void cmp(Register reg, int32_t imm32);
void cmp(Register reg, Handle<Object> handle);
void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
......@@ -758,8 +766,8 @@ class Assembler : public AssemblerBase {
void test(Register reg, const Operand& op);
void test_b(Register reg, const Operand& op);
void test(const Operand& op, const Immediate& imm);
void test_b(Register reg, uint8_t imm8);
void test_b(const Operand& op, uint8_t imm8);
void test_b(Register reg, Immediate imm8);
void test_b(const Operand& op, Immediate imm8);
void xor_(Register dst, int32_t imm32);
void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
......@@ -1005,6 +1013,7 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode rmode,
TypeFeedbackId id = TypeFeedbackId::None());
inline void emit(const Immediate& x);
inline void emit_b(Immediate x);
inline void emit_w(const Immediate& x);
inline void emit_q(uint64_t x);
......
......@@ -1004,7 +1004,8 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
Label receiver_not_callable;
__ JumpIfSmi(edi, &receiver_not_callable, Label::kNear);
__ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsCallable));
__ j(zero, &receiver_not_callable, Label::kNear);
// 3. Tail call with no arguments if argArray is null or undefined.
......@@ -1127,7 +1128,8 @@ void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
Label target_not_callable;
__ JumpIfSmi(edi, &target_not_callable, Label::kNear);
__ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsCallable));
__ j(zero, &target_not_callable, Label::kNear);
// 3a. Apply the target to the given argumentsList (passing undefined for
......@@ -1192,14 +1194,16 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
Label target_not_constructor;
__ JumpIfSmi(edi, &target_not_constructor, Label::kNear);
__ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsConstructor));
__ j(zero, &target_not_constructor, Label::kNear);
// 3. Make sure the target is actually a constructor.
Label new_target_not_constructor;
__ JumpIfSmi(edx, &new_target_not_constructor, Label::kNear);
__ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsConstructor));
__ j(zero, &new_target_not_constructor, Label::kNear);
// 4a. Construct the target with the given new.target and argumentsList.
......@@ -1954,7 +1958,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
SharedFunctionInfo::kClassConstructorBitsWithinByte);
Immediate(SharedFunctionInfo::kClassConstructorBitsWithinByte));
__ j(not_zero, &class_constructor);
// Enter the context of the function; ToObject has to run in the function
......@@ -1966,8 +1970,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
// We need to convert the receiver for non-native sloppy mode functions.
Label done_convert;
__ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset),
(1 << SharedFunctionInfo::kNativeBitWithinByte) |
(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
Immediate((1 << SharedFunctionInfo::kNativeBitWithinByte) |
(1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
__ j(not_zero, &done_convert);
{
// ----------- S t a t e -------------
......@@ -2189,7 +2193,8 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
RelocInfo::CODE_TARGET);
// Check if target has a [[Call]] internal method.
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsCallable));
__ j(zero, &non_callable);
__ CmpInstanceType(ecx, JS_PROXY_TYPE);
......@@ -2325,7 +2330,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
RelocInfo::CODE_TARGET);
// Check if target has a [[Construct]] internal method.
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsConstructor));
__ j(zero, &non_constructor, Label::kNear);
// Only dispatch to bound functions after checking whether they are
......
......@@ -540,11 +540,11 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ mov(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
// (5a) Is subject sequential two byte? If yes, go to (9).
__ test_b(ebx, kStringRepresentationMask | kStringEncodingMask);
__ test_b(ebx, Immediate(kStringRepresentationMask | kStringEncodingMask));
STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string); // Go to (9).
// (5b) Is subject external? If yes, go to (8).
__ test_b(ebx, kStringRepresentationMask);
__ test_b(ebx, Immediate(kStringRepresentationMask));
// The underlying external string is never a short external string.
STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
......@@ -787,7 +787,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
if (FLAG_debug_code) {
// Assert that we do not have a cons or slice (indirect strings) here.
// Sequential strings have already been ruled out.
__ test_b(ebx, kIsIndirectStringMask);
__ test_b(ebx, Immediate(kIsIndirectStringMask));
__ Assert(zero, kExternalStringExpectedButNotFound);
}
__ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
......@@ -796,7 +796,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
STATIC_ASSERT(kTwoByteStringTag == 0);
// (8a) Is the external string one byte? If yes, go to (6).
__ test_b(ebx, kStringEncodingMask);
__ test_b(ebx, Immediate(kStringEncodingMask));
__ j(not_zero, &seq_one_byte_string); // Goto (6).
// eax: sequential subject string (or look-alike, external string)
......@@ -921,13 +921,13 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
__ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
__ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
// Call runtime on identical JSObjects. Otherwise return equal.
__ cmpb(ecx, static_cast<uint8_t>(FIRST_JS_RECEIVER_TYPE));
__ cmpb(ecx, Immediate(FIRST_JS_RECEIVER_TYPE));
__ j(above_equal, &runtime_call, Label::kFar);
// Call runtime on identical symbols since we need to throw a TypeError.
__ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
__ cmpb(ecx, Immediate(SYMBOL_TYPE));
__ j(equal, &runtime_call, Label::kFar);
// Call runtime on identical SIMD values since we must throw a TypeError.
__ cmpb(ecx, static_cast<uint8_t>(SIMD128_VALUE_TYPE));
__ cmpb(ecx, Immediate(SIMD128_VALUE_TYPE));
__ j(equal, &runtime_call, Label::kFar);
}
__ Move(eax, Immediate(Smi::FromInt(EQUAL)));
......@@ -1099,10 +1099,10 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
__ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
__ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, &undetectable, Label::kNear);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, &return_unequal, Label::kNear);
__ CmpInstanceType(ebx, FIRST_JS_RECEIVER_TYPE);
......@@ -1116,7 +1116,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
__ bind(&undetectable);
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Immediate(1 << Map::kIsUndetectable));
__ j(zero, &return_unequal, Label::kNear);
// If both sides are JSReceivers, then the result is false according to
......@@ -1836,12 +1836,12 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
// Go to the runtime if the function is not a constructor.
__ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
static_cast<uint8_t>(1 << Map::kIsConstructor));
Immediate(1 << Map::kIsConstructor));
__ j(zero, &slow_case);
// Ensure that {function} has an instance prototype.
__ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
static_cast<uint8_t>(1 << Map::kHasNonInstancePrototype));
Immediate(1 << Map::kHasNonInstancePrototype));
__ j(not_zero, &slow_case);
// Get the "prototype" (or initial map) of the {function}.
......@@ -1875,7 +1875,7 @@ void InstanceOfStub::Generate(MacroAssembler* masm) {
// Check if the object needs to be access checked.
__ test_b(FieldOperand(object_map, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded);
Immediate(1 << Map::kIsAccessCheckNeeded));
__ j(not_zero, &fast_runtime_fallback, Label::kNear);
// Check if the current object is a Proxy.
__ CmpInstanceType(object_map, JS_PROXY_TYPE);
......@@ -2220,13 +2220,13 @@ void SubStringStub::Generate(MacroAssembler* masm) {
Label two_byte_sequential, runtime_drop_two, sequential_string;
STATIC_ASSERT(kExternalStringTag != 0);
STATIC_ASSERT(kSeqStringTag == 0);
__ test_b(ebx, kExternalStringTag);
__ test_b(ebx, Immediate(kExternalStringTag));
__ j(zero, &sequential_string);
// Handle external string.
// Rule out short external strings.
STATIC_ASSERT(kShortExternalStringTag != 0);
__ test_b(ebx, kShortExternalStringMask);
__ test_b(ebx, Immediate(kShortExternalStringMask));
__ j(not_zero, &runtime);
__ mov(edi, FieldOperand(edi, ExternalString::kResourceDataOffset));
// Move the pointer so that offset-wise, it looks like a sequential string.
......@@ -2239,7 +2239,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
__ push(edi);
__ SmiUntag(ecx);
STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
__ test_b(ebx, kStringEncodingMask);
__ test_b(ebx, Immediate(kStringEncodingMask));
__ j(zero, &two_byte_sequential);
// Sequential one byte string. Allocate the result.
......@@ -4101,7 +4101,7 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
// is the low bit set? If so, we are holey and that is good.
__ test_b(edx, 1);
__ test_b(edx, Immediate(1));
__ j(not_zero, &normal_sequence);
}
......@@ -5229,7 +5229,7 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
Label profiler_disabled;
Label end_profiler_check;
__ mov(eax, Immediate(ExternalReference::is_profiling_address(isolate)));
__ cmpb(Operand(eax, 0), 0);
__ cmpb(Operand(eax, 0), Immediate(0));
__ j(zero, &profiler_disabled);
// Additional parameter is the address of the actual getter function.
......
......@@ -545,11 +545,11 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
}
// Rule out short external strings.
STATIC_ASSERT(kShortExternalStringTag != 0);
__ test_b(result, kShortExternalStringMask);
__ test_b(result, Immediate(kShortExternalStringMask));
__ j(not_zero, call_runtime);
// Check encoding.
STATIC_ASSERT(kTwoByteStringTag == 0);
__ test_b(result, kStringEncodingMask);
__ test_b(result, Immediate(kStringEncodingMask));
__ mov(result, FieldOperand(string, ExternalString::kResourceDataOffset));
__ j(not_equal, &one_byte_external, Label::kNear);
// Two-byte string.
......
......@@ -1281,6 +1281,13 @@ int DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
int imm = *reinterpret_cast<int16_t*>(data);
AppendToBuffer(",0x%x", imm);
data += 2;
} else if (*data == 0xF7) {
data++;
AppendToBuffer("%s ", "test_w");
data += PrintRightOperand(data);
int imm = *reinterpret_cast<int16_t*>(data);
AppendToBuffer(",0x%x", imm);
data += 2;
} else if (*data == 0x0F) {
data++;
if (*data == 0x38) {
......
......@@ -376,7 +376,7 @@ void MacroAssembler::RecordWriteField(
lea(dst, FieldOperand(object, offset));
if (emit_debug_code()) {
Label ok;
test_b(dst, (1 << kPointerSizeLog2) - 1);
test_b(dst, Immediate((1 << kPointerSizeLog2) - 1));
j(zero, &ok, Label::kNear);
int3();
bind(&ok);
......@@ -406,7 +406,7 @@ void MacroAssembler::RecordWriteForMap(Register object, Handle<Map> map,
if (emit_debug_code()) {
Label ok;
lea(address, FieldOperand(object, HeapObject::kMapOffset));
test_b(address, (1 << kPointerSizeLog2) - 1);
test_b(address, Immediate((1 << kPointerSizeLog2) - 1));
j(zero, &ok, Label::kNear);
int3();
bind(&ok);
......@@ -699,8 +699,7 @@ void MacroAssembler::CmpObjectType(Register heap_object,
void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
cmpb(FieldOperand(map, Map::kInstanceTypeOffset),
static_cast<int8_t>(type));
cmpb(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type));
}
......@@ -712,7 +711,7 @@ void MacroAssembler::CheckFastElements(Register map,
STATIC_ASSERT(FAST_ELEMENTS == 2);
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
cmpb(FieldOperand(map, Map::kBitField2Offset),
Map::kMaximumBitField2FastHoleyElementValue);
Immediate(Map::kMaximumBitField2FastHoleyElementValue));
j(above, fail, distance);
}
......@@ -725,10 +724,10 @@ void MacroAssembler::CheckFastObjectElements(Register map,
STATIC_ASSERT(FAST_ELEMENTS == 2);
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
cmpb(FieldOperand(map, Map::kBitField2Offset),
Map::kMaximumBitField2FastHoleySmiElementValue);
Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
j(below_equal, fail, distance);
cmpb(FieldOperand(map, Map::kBitField2Offset),
Map::kMaximumBitField2FastHoleyElementValue);
Immediate(Map::kMaximumBitField2FastHoleyElementValue));
j(above, fail, distance);
}
......@@ -739,7 +738,7 @@ void MacroAssembler::CheckFastSmiElements(Register map,
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
cmpb(FieldOperand(map, Map::kBitField2Offset),
Map::kMaximumBitField2FastHoleySmiElementValue);
Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
j(above, fail, distance);
}
......@@ -826,7 +825,7 @@ Condition MacroAssembler::IsObjectNameType(Register heap_object,
Register instance_type) {
mov(map, FieldOperand(heap_object, HeapObject::kMapOffset));
movzx_b(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
cmpb(instance_type, static_cast<uint8_t>(LAST_NAME_TYPE));
cmpb(instance_type, Immediate(LAST_NAME_TYPE));
return below_equal;
}
......@@ -1944,7 +1943,7 @@ void MacroAssembler::BooleanBitTest(Register object,
int byte_index = bit_index / kBitsPerByte;
int byte_bit_index = bit_index & (kBitsPerByte - 1);
test_b(FieldOperand(object, field_offset + byte_index),
static_cast<byte>(1 << byte_bit_index));
Immediate(1 << byte_bit_index));
}
......@@ -2264,7 +2263,7 @@ void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target,
Label skip_flooding;
ExternalReference step_in_enabled =
ExternalReference::debug_step_in_enabled_address(isolate());
cmpb(Operand::StaticVariable(step_in_enabled), 0);
cmpb(Operand::StaticVariable(step_in_enabled), Immediate(0));
j(equal, &skip_flooding);
{
FrameScope frame(this,
......@@ -2861,7 +2860,7 @@ void MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand,
Label succeed;
test(operand, Immediate(kIsNotStringMask | kIsNotInternalizedMask));
j(zero, &succeed);
cmpb(operand, static_cast<uint8_t>(SYMBOL_TYPE));
cmpb(operand, Immediate(SYMBOL_TYPE));
j(not_equal, not_unique_name, distance);
bind(&succeed);
......@@ -3009,8 +3008,7 @@ void MacroAssembler::CheckPageFlag(
and_(scratch, object);
}
if (mask < (1 << kBitsPerByte)) {
test_b(Operand(scratch, MemoryChunk::kFlagsOffset),
static_cast<uint8_t>(mask));
test_b(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask));
} else {
test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask));
}
......@@ -3033,7 +3031,7 @@ void MacroAssembler::CheckPageFlagForMap(
DCHECK(!isolate()->heap()->mark_compact_collector()->
IsOnEvacuationCandidate(*map));
if (mask < (1 << kBitsPerByte)) {
test_b(Operand::StaticVariable(reference), static_cast<uint8_t>(mask));
test_b(Operand::StaticVariable(reference), Immediate(mask));
} else {
test(Operand::StaticVariable(reference), Immediate(mask));
}
......@@ -3073,7 +3071,8 @@ void MacroAssembler::HasColor(Register object,
jmp(&other_color, Label::kNear);
bind(&word_boundary);
test_b(Operand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize), 1);
test_b(Operand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize),
Immediate(1));
j(second_bit == 1 ? not_zero : zero, has_color, has_color_distance);
bind(&other_color);
......
......@@ -244,7 +244,7 @@ TEST(DisasmIa320) {
__ cmp(ebx, 12345);
__ cmp(ebx, Immediate(12));
__ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
__ cmpb(eax, 100);
__ cmpb(eax, Immediate(100));
__ or_(ebx, 12345);
......@@ -268,7 +268,7 @@ TEST(DisasmIa320) {
__ test(edx, Operand(ebx, ecx, times_8, 10000));
__ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
__ test_b(edx, Operand(ecx, ebx, times_2, 1000));
__ test_b(Operand(eax, -20), 0x9A);
__ test_b(Operand(eax, -20), Immediate(0x9A));
__ nop();
__ xor_(edx, 12345);
......
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