Merge Label and NearLabel

by adding NearLabel's functionality to Label and introducing a "near" parameter to jump instructions.

TEST=compiles; existing tests still pass.

Review URL: http://codereview.chromium.org/6928060

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7832 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
jkummerow@chromium.org 2011-05-10 09:03:42 +00:00
parent 5d8cd989ab
commit 95ff85112f
22 changed files with 839 additions and 726 deletions

View File

@ -78,18 +78,28 @@ class DoubleConstant: public AllStatic {
class Label BASE_EMBEDDED {
public:
INLINE(Label()) { Unuse(); }
enum Distance {
kNear, kFar
};
INLINE(Label()) {
Unuse();
UnuseNear();
}
INLINE(~Label()) { ASSERT(!is_linked()); }
INLINE(void Unuse()) { pos_ = 0; }
INLINE(void UnuseNear()) { near_link_pos_ = 0; }
INLINE(bool is_bound() const) { return pos_ < 0; }
INLINE(bool is_unused() const) { return pos_ == 0; }
INLINE(bool is_unused() const) { return pos_ == 0 && near_link_pos_ == 0; }
INLINE(bool is_linked() const) { return pos_ > 0; }
INLINE(bool is_near_linked() const) { return near_link_pos_ > 0; }
// Returns the position of bound or linked labels. Cannot be used
// for unused labels.
int pos() const;
int near_link_pos() const { return near_link_pos_ - 1; }
private:
// pos_ encodes both the binding state (via its sign)
@ -100,13 +110,21 @@ class Label BASE_EMBEDDED {
// pos_ > 0 linked label, pos() returns the last reference position
int pos_;
// Behaves like |pos_| in the "> 0" case, but for near jumps to this label.
int near_link_pos_;
void bind_to(int pos) {
pos_ = -pos - 1;
ASSERT(is_bound());
}
void link_to(int pos) {
pos_ = pos + 1;
ASSERT(is_linked());
void link_to(int pos, Distance distance = kFar) {
if (distance == kNear) {
near_link_pos_ = pos + 1;
ASSERT(is_near_linked());
} else {
pos_ = pos + 1;
ASSERT(is_linked());
}
}
friend class Assembler;

View File

@ -380,6 +380,18 @@ void Assembler::emit_disp(Label* L, Displacement::Type type) {
}
void Assembler::emit_near_disp(Label* L) {
byte disp = 0x00;
if (L->is_near_linked()) {
int offset = L->near_link_pos() - pc_offset();
ASSERT(is_int8(offset));
disp = static_cast<byte>(offset & 0xFF);
}
L->link_to(pc_offset(), Label::kNear);
*pc_++ = disp;
}
void Operand::set_modrm(int mod, Register rm) {
ASSERT((mod & -4) == 0);
buf_[0] = mod << 6 | rm.code();

View File

@ -1525,6 +1525,21 @@ void Assembler::bind_to(Label* L, int pos) {
}
disp.next(L);
}
while (L->is_near_linked()) {
int fixup_pos = L->near_link_pos();
int offset_to_next =
static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
ASSERT(offset_to_next <= 0);
// Relative address, relative to point after address.
int disp = pos - fixup_pos - sizeof(int8_t);
ASSERT(0 <= disp && disp <= 127);
set_byte_at(fixup_pos, disp);
if (offset_to_next < 0) {
L->link_to(fixup_pos + offset_to_next, Label::kNear);
} else {
L->UnuseNear();
}
}
L->bind_to(pos);
}
@ -1613,7 +1628,7 @@ void Assembler::call(Handle<Code> code,
}
void Assembler::jmp(Label* L) {
void Assembler::jmp(Label* L, Label::Distance distance) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
if (L->is_bound()) {
@ -1630,6 +1645,9 @@ void Assembler::jmp(Label* L) {
EMIT(0xE9);
emit(offs - long_size);
}
} else if (distance == Label::kNear) {
EMIT(0xEB);
emit_near_disp(L);
} else {
// 1110 1001 #32-bit disp.
EMIT(0xE9);
@ -1683,7 +1701,7 @@ void Assembler::jmp(NearLabel* L) {
}
void Assembler::j(Condition cc, Label* L, Hint hint) {
void Assembler::j(Condition cc, Label* L, Hint hint, Label::Distance distance) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
ASSERT(0 <= cc && cc < 16);
@ -1703,6 +1721,9 @@ void Assembler::j(Condition cc, Label* L, Hint hint) {
EMIT(0x80 | cc);
emit(offs - long_size);
}
} else if (distance == Label::kNear) {
EMIT(0x70 | cc);
emit_near_disp(L);
} else {
// 0000 1111 1000 tttn #32-bit disp
// Note: could eliminate cond. jumps to this jump if condition

View File

@ -842,6 +842,7 @@ class Assembler : public AssemblerBase {
// but it may be bound only once.
void bind(Label* L); // binds an unbound label L to the current code position
// DEPRECATED. Use bind(Label*) with jmp(Label*, Label::kNear) instead.
void bind(NearLabel* L);
// Calls
@ -855,20 +856,29 @@ class Assembler : public AssemblerBase {
unsigned ast_id = kNoASTId);
// Jumps
void jmp(Label* L); // unconditional jump to L
// unconditional jump to L
void jmp(Label* L, Label::Distance distance = Label::kFar);
void jmp(byte* entry, RelocInfo::Mode rmode);
void jmp(const Operand& adr);
void jmp(Handle<Code> code, RelocInfo::Mode rmode);
// Short jump
// DEPRECATED. Use jmp(Label*, Label::kNear) instead.
void jmp(NearLabel* L);
// Conditional jumps
void j(Condition cc, Label* L, Hint hint = no_hint);
void j(Condition cc,
Label* L,
Hint hint,
Label::Distance distance = Label::kFar);
void j(Condition cc, Label* L, Label::Distance distance = Label::kFar) {
j(cc, L, no_hint, distance);
}
void j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint = no_hint);
void j(Condition cc, Handle<Code> code, Hint hint = no_hint);
// Conditional short jump
// DEPRECATED. Use j(Condition, Label*, Label::kNear) instead.
void j(Condition cc, NearLabel* L, Hint hint = no_hint);
// Floating-point operations
@ -1105,6 +1115,7 @@ class Assembler : public AssemblerBase {
inline Displacement disp_at(Label* L);
inline void disp_at_put(Label* L, Displacement disp);
inline void emit_disp(Label* L, Displacement::Type type);
inline void emit_near_disp(Label* L);
// record reloc info for current pc_
void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);

View File

@ -520,15 +520,15 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
__ SmiUntag(ecx);
// Switch on the state.
NearLabel not_no_registers, not_tos_eax;
Label not_no_registers, not_tos_eax;
__ cmp(ecx, FullCodeGenerator::NO_REGISTERS);
__ j(not_equal, &not_no_registers);
__ j(not_equal, &not_no_registers, Label::kNear);
__ ret(1 * kPointerSize); // Remove state.
__ bind(&not_no_registers);
__ mov(eax, Operand(esp, 2 * kPointerSize));
__ cmp(ecx, FullCodeGenerator::TOS_REG);
__ j(not_equal, &not_tos_eax);
__ j(not_equal, &not_tos_eax, Label::kNear);
__ ret(2 * kPointerSize); // Remove state, eax.
__ bind(&not_tos_eax);
@ -1577,19 +1577,19 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
// If the result was -1 it means that we couldn't optimize the
// function. Just return and continue in the unoptimized version.
NearLabel skip;
Label skip;
__ cmp(Operand(eax), Immediate(Smi::FromInt(-1)));
__ j(not_equal, &skip);
__ j(not_equal, &skip, Label::kNear);
__ ret(0);
// If we decide not to perform on-stack replacement we perform a
// stack guard check to enable interrupts.
__ bind(&stack_check);
NearLabel ok;
Label ok;
ExternalReference stack_limit =
ExternalReference::address_of_stack_limit(masm->isolate());
__ cmp(esp, Operand::StaticVariable(stack_limit));
__ j(above_equal, &ok, taken);
__ j(above_equal, &ok, taken, Label::kNear);
StackCheckStub stub;
__ TailCallStub(&stub);
__ Abort("Unreachable code: returned from tail call.");

File diff suppressed because it is too large Load Diff

View File

@ -237,11 +237,11 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
{ Comment cmnt(masm_, "[ Stack check");
PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
NearLabel ok;
Label ok;
ExternalReference stack_limit =
ExternalReference::address_of_stack_limit(isolate());
__ cmp(esp, Operand::StaticVariable(stack_limit));
__ j(above_equal, &ok, taken);
__ j(above_equal, &ok, taken, Label::kNear);
StackCheckStub stub;
__ CallStub(&stub);
__ bind(&ok);
@ -270,11 +270,11 @@ void FullCodeGenerator::ClearAccumulator() {
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
Comment cmnt(masm_, "[ Stack check");
NearLabel ok;
Label ok;
ExternalReference stack_limit =
ExternalReference::address_of_stack_limit(isolate());
__ cmp(esp, Operand::StaticVariable(stack_limit));
__ j(above_equal, &ok, taken);
__ j(above_equal, &ok, taken, Label::kNear);
StackCheckStub stub;
__ CallStub(&stub);
// Record a mapping of this PC offset to the OSR id. This is used to find
@ -471,10 +471,10 @@ void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
void FullCodeGenerator::AccumulatorValueContext::Plug(
Label* materialize_true,
Label* materialize_false) const {
NearLabel done;
Label done;
__ bind(materialize_true);
__ mov(result_register(), isolate()->factory()->true_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(materialize_false);
__ mov(result_register(), isolate()->factory()->false_value());
__ bind(&done);
@ -484,10 +484,10 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(
Label* materialize_true,
Label* materialize_false) const {
NearLabel done;
Label done;
__ bind(materialize_true);
__ push(Immediate(isolate()->factory()->true_value()));
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(materialize_false);
__ push(Immediate(isolate()->factory()->false_value()));
__ bind(&done);
@ -627,8 +627,8 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
// preparation to avoid preparing with the same AST id twice.
if (!context()->IsTest() || !info_->IsOptimizable()) return;
NearLabel skip;
if (should_normalize) __ jmp(&skip);
Label skip;
if (should_normalize) __ jmp(&skip, Label::kNear);
ForwardBailoutStack* current = forward_bailout_stack_;
while (current != NULL) {
@ -862,11 +862,11 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ j(equal, &exit);
// Convert the object to a JS object.
NearLabel convert, done_convert;
Label convert, done_convert;
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &convert);
__ j(zero, &convert, Label::kNear);
__ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
__ j(above_equal, &done_convert);
__ j(above_equal, &done_convert, Label::kNear);
__ bind(&convert);
__ push(eax);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
@ -903,9 +903,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ j(zero, &call_runtime);
// For all objects but the receiver, check that the cache is empty.
NearLabel check_prototype;
Label check_prototype;
__ cmp(ecx, Operand(eax));
__ j(equal, &check_prototype);
__ j(equal, &check_prototype, Label::kNear);
__ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
__ cmp(edx, isolate()->factory()->empty_fixed_array());
__ j(not_equal, &call_runtime);
@ -918,9 +918,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// The enum cache is valid. Load the map of the object being
// iterated over and use the cache for the iteration.
NearLabel use_cache;
Label use_cache;
__ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
__ jmp(&use_cache);
__ jmp(&use_cache, Label::kNear);
// Get the set of properties to enumerate.
__ bind(&call_runtime);
@ -930,10 +930,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// If we got a map from the runtime call, we can do a fast
// modification check. Otherwise, we got a fixed array, and we have
// to do a slow check.
NearLabel fixed_array;
Label fixed_array;
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
isolate()->factory()->meta_map());
__ j(not_equal, &fixed_array);
__ j(not_equal, &fixed_array, Label::kNear);
// We got a map in register eax. Get the enumeration cache from it.
__ bind(&use_cache);
@ -973,10 +973,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Check if the expected map still matches that of the enumerable.
// If not, we have to filter the key.
NearLabel update_each;
Label update_each;
__ mov(ecx, Operand(esp, 4 * kPointerSize));
__ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset));
__ j(equal, &update_each);
__ j(equal, &update_each, Label::kNear);
// Convert the entry to a string or null if it isn't a property
// anymore. If the property has been removed while iterating, we
@ -1084,7 +1084,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
if (s != NULL && s->is_eval_scope()) {
// Loop up the context chain. There is no frame effect so it is
// safe to use raw labels here.
NearLabel next, fast;
Label next, fast;
if (!context.is(temp)) {
__ mov(temp, context);
}
@ -1092,7 +1092,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
// Terminate at global context.
__ cmp(FieldOperand(temp, HeapObject::kMapOffset),
Immediate(isolate()->factory()->global_context_map()));
__ j(equal, &fast);
__ j(equal, &fast, Label::kNear);
// Check that extension is NULL.
__ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
__ j(not_equal, slow);
@ -1241,11 +1241,11 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
if (var->mode() == Variable::CONST) {
// Constants may be the hole value if they have not been initialized.
// Unhole them.
NearLabel done;
Label done;
MemOperand slot_operand = EmitSlotSearch(slot, eax);
__ mov(eax, slot_operand);
__ cmp(eax, isolate()->factory()->the_hole_value());
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
__ mov(eax, isolate()->factory()->undefined_value());
__ bind(&done);
context()->Plug(eax);
@ -1288,7 +1288,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
Comment cmnt(masm_, "[ RegExpLiteral");
NearLabel materialized;
Label materialized;
// Registers will be used as follows:
// edi = JS function.
// ecx = literals array.
@ -1300,7 +1300,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
__ mov(ebx, FieldOperand(ecx, literal_offset));
__ cmp(ebx, isolate()->factory()->undefined_value());
__ j(not_equal, &materialized);
__ j(not_equal, &materialized, Label::kNear);
// Create regexp literal using runtime function
// Result will be in eax.
@ -1657,7 +1657,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
Expression* right) {
// Do combined smi check of the operands. Left operand is on the
// stack. Right operand is in eax.
NearLabel done, smi_case, stub_call;
NearLabel smi_case;
Label done, stub_call;
__ pop(edx);
__ mov(ecx, eax);
__ or_(eax, Operand(edx));
@ -1668,7 +1669,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ mov(eax, ecx);
TypeRecordingBinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id());
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Smi case.
__ bind(&smi_case);
@ -1721,7 +1722,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ imul(eax, Operand(ecx));
__ j(overflow, &stub_call);
__ test(eax, Operand(eax));
__ j(not_zero, &done, taken);
__ j(not_zero, &done, taken, Label::kNear);
__ mov(ebx, edx);
__ or_(ebx, Operand(ecx));
__ j(negative, &stub_call);
@ -2843,13 +2844,13 @@ void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
VisitForAccumulatorValue(args->at(0)); // Load the object.
NearLabel done;
Label done;
// If the object is a smi return the object.
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
// If the object is not a value type, return the object.
__ CmpObjectType(eax, JS_VALUE_TYPE, ebx);
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
__ mov(eax, FieldOperand(eax, JSValue::kValueOffset));
__ bind(&done);
@ -2880,14 +2881,14 @@ void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
VisitForAccumulatorValue(args->at(1)); // Load the value.
__ pop(ebx); // eax = value. ebx = object.
NearLabel done;
Label done;
// If the object is a smi, return the value.
__ test(ebx, Immediate(kSmiTagMask));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
// If the object is not a value type, return the value.
__ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
// Store the value.
__ mov(FieldOperand(ebx, JSValue::kValueOffset), eax);
@ -3829,10 +3830,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
// Call ToNumber only if operand is not a smi.
NearLabel no_conversion;
Label no_conversion;
if (ShouldInlineSmiCase(expr->op())) {
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &no_conversion);
__ j(zero, &no_conversion, Label::kNear);
}
ToNumberStub convert_stub;
__ CallStub(&convert_stub);
@ -3859,7 +3860,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
// Inline smi case if we are in a loop.
NearLabel stub_call, done;
NearLabel done;
Label stub_call;
JumpPatchSite patch_site(masm_);
if (ShouldInlineSmiCase(expr->op())) {
@ -3868,7 +3870,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
} else {
__ sub(Operand(eax), Immediate(Smi::FromInt(1)));
}
__ j(overflow, &stub_call);
__ j(overflow, &stub_call, Label::kNear);
// We could eliminate this smi check if we split the code at
// the first smi check before calling ToNumber.
patch_site.EmitJumpIfSmi(eax, &done);

View File

@ -97,7 +97,6 @@ static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm,
}
// Helper function used to load a property from a dictionary backing
// storage. This function may fail to load a property even though it is
// in the dictionary, so code at miss_label must always call a backup
@ -749,7 +748,8 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// ecx: key, a smi.
// edi: receiver->elements, a FixedArray
// flags: compare (ecx, edx.length())
__ j(not_equal, &slow, not_taken); // do not leave holes in the array
// do not leave holes in the array:
__ j(not_equal, &slow, not_taken);
__ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
__ j(above_equal, &slow, not_taken);
// Add 1 to receiver->length, and go to fast array write.
@ -942,13 +942,13 @@ static void GenerateCallMiss(MacroAssembler* masm,
Label invoke, global;
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver
__ test(edx, Immediate(kSmiTagMask));
__ j(zero, &invoke, not_taken);
__ j(zero, &invoke, not_taken, Label::kNear);
__ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
__ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
__ cmp(ebx, JS_GLOBAL_OBJECT_TYPE);
__ j(equal, &global);
__ j(equal, &global, Label::kNear);
__ cmp(ebx, JS_BUILTINS_OBJECT_TYPE);
__ j(not_equal, &invoke);
__ j(not_equal, &invoke, Label::kNear);
// Patch the receiver on the stack.
__ bind(&global);

View File

@ -545,7 +545,7 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
__ mov(ebx, shared);
__ mov(eax, FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset));
__ sub(Operand(eax), Immediate(Smi::FromInt(1)));
__ j(not_zero, &no_deopt);
__ j(not_zero, &no_deopt, Label::kNear);
if (FLAG_trap_on_deopt) __ int3();
__ mov(eax, Immediate(Smi::FromInt(FLAG_deopt_every_n_times)));
__ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax);
@ -566,8 +566,8 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
__ jmp(entry, RelocInfo::RUNTIME_ENTRY);
} else {
if (FLAG_trap_on_deopt) {
NearLabel done;
__ j(NegateCondition(cc), &done);
Label done;
__ j(NegateCondition(cc), &done, Label::kNear);
__ int3();
__ jmp(entry, RelocInfo::RUNTIME_ENTRY);
__ bind(&done);
@ -787,21 +787,21 @@ void LCodeGen::DoModI(LModI* instr) {
if (divisor < 0) divisor = -divisor;
NearLabel positive_dividend, done;
Label positive_dividend, done;
__ test(dividend, Operand(dividend));
__ j(not_sign, &positive_dividend);
__ j(not_sign, &positive_dividend, Label::kNear);
__ neg(dividend);
__ and_(dividend, divisor - 1);
__ neg(dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
DeoptimizeIf(no_condition, instr->environment());
}
__ bind(&positive_dividend);
__ and_(dividend, divisor - 1);
__ bind(&done);
} else {
NearLabel done, remainder_eq_dividend, slow, do_subtraction, both_positive;
Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
Register left_reg = ToRegister(instr->InputAt(0));
Register right_reg = ToRegister(instr->InputAt(1));
Register result_reg = ToRegister(instr->result());
@ -818,11 +818,11 @@ void LCodeGen::DoModI(LModI* instr) {
}
__ test(left_reg, Operand(left_reg));
__ j(zero, &remainder_eq_dividend);
__ j(sign, &slow);
__ j(zero, &remainder_eq_dividend, Label::kNear);
__ j(sign, &slow, Label::kNear);
__ test(right_reg, Operand(right_reg));
__ j(not_sign, &both_positive);
__ j(not_sign, &both_positive, Label::kNear);
// The sign of the divisor doesn't matter.
__ neg(right_reg);
@ -830,16 +830,16 @@ void LCodeGen::DoModI(LModI* instr) {
// If the dividend is smaller than the nonnegative
// divisor, the dividend is the result.
__ cmp(left_reg, Operand(right_reg));
__ j(less, &remainder_eq_dividend);
__ j(less, &remainder_eq_dividend, Label::kNear);
// Check if the divisor is a PowerOfTwo integer.
Register scratch = ToRegister(instr->TempAt(0));
__ mov(scratch, right_reg);
__ sub(Operand(scratch), Immediate(1));
__ test(scratch, Operand(right_reg));
__ j(not_zero, &do_subtraction);
__ j(not_zero, &do_subtraction, Label::kNear);
__ and_(left_reg, Operand(scratch));
__ jmp(&remainder_eq_dividend);
__ jmp(&remainder_eq_dividend, Label::kNear);
__ bind(&do_subtraction);
const int kUnfolds = 3;
@ -850,7 +850,7 @@ void LCodeGen::DoModI(LModI* instr) {
__ sub(left_reg, Operand(right_reg));
// Check if the dividend is less than the divisor.
__ cmp(left_reg, Operand(right_reg));
__ j(less, &remainder_eq_dividend);
__ j(less, &remainder_eq_dividend, Label::kNear);
}
__ mov(left_reg, scratch);
@ -861,15 +861,15 @@ void LCodeGen::DoModI(LModI* instr) {
// Check for (0 % -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
NearLabel positive_left;
NearLabel done;
Label positive_left;
Label done;
__ test(left_reg, Operand(left_reg));
__ j(not_sign, &positive_left);
__ j(not_sign, &positive_left, Label::kNear);
__ idiv(right_reg);
// Test the remainder for 0, because then the result would be -0.
__ test(result_reg, Operand(result_reg));
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
DeoptimizeIf(no_condition, instr->environment());
__ bind(&positive_left);
@ -878,7 +878,7 @@ void LCodeGen::DoModI(LModI* instr) {
} else {
__ idiv(right_reg);
}
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&remainder_eq_dividend);
__ mov(result_reg, left_reg);
@ -906,9 +906,9 @@ void LCodeGen::DoDivI(LDivI* instr) {
// Check for (0 / -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
NearLabel left_not_zero;
Label left_not_zero;
__ test(left_reg, Operand(left_reg));
__ j(not_zero, &left_not_zero);
__ j(not_zero, &left_not_zero, Label::kNear);
__ test(right_reg, ToOperand(right));
DeoptimizeIf(sign, instr->environment());
__ bind(&left_not_zero);
@ -916,9 +916,9 @@ void LCodeGen::DoDivI(LDivI* instr) {
// Check for (-kMinInt / -1).
if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
NearLabel left_not_min_int;
Label left_not_min_int;
__ cmp(left_reg, kMinInt);
__ j(not_zero, &left_not_min_int);
__ j(not_zero, &left_not_min_int, Label::kNear);
__ cmp(right_reg, -1);
DeoptimizeIf(zero, instr->environment());
__ bind(&left_not_min_int);
@ -996,9 +996,9 @@ void LCodeGen::DoMulI(LMulI* instr) {
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Bail out if the result is supposed to be negative zero.
NearLabel done;
Label done;
__ test(left, Operand(left));
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
if (right->IsConstantOperand()) {
if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
DeoptimizeIf(no_condition, instr->environment());
@ -1203,14 +1203,14 @@ void LCodeGen::DoValueOf(LValueOf* instr) {
Register result = ToRegister(instr->result());
Register map = ToRegister(instr->TempAt(0));
ASSERT(input.is(result));
NearLabel done;
Label done;
// If the object is a smi return the object.
__ test(input, Immediate(kSmiTagMask));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
// If the object is not a value type, return the object.
__ CmpObjectType(input, JS_VALUE_TYPE, map);
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
__ mov(result, FieldOperand(input, JSValue::kValueOffset));
__ bind(&done);
@ -1368,10 +1368,10 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ j(zero, true_label);
// Test for double values. Zero is false.
NearLabel call_stub;
Label call_stub;
__ cmp(FieldOperand(reg, HeapObject::kMapOffset),
factory()->heap_number_map());
__ j(not_equal, &call_stub);
__ j(not_equal, &call_stub, Label::kNear);
__ fldz();
__ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
__ FCmp();
@ -1477,20 +1477,20 @@ void LCodeGen::DoCmpID(LCmpID* instr) {
LOperand* right = instr->InputAt(1);
LOperand* result = instr->result();
NearLabel unordered;
Label unordered;
if (instr->is_double()) {
// Don't base result on EFLAGS when a NaN is involved. Instead
// jump to the unordered case, which produces a false value.
__ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
__ j(parity_even, &unordered, not_taken);
__ j(parity_even, &unordered, not_taken, Label::kNear);
} else {
EmitCmpI(left, right);
}
NearLabel done;
Label done;
Condition cc = TokenToCondition(instr->op(), instr->is_double());
__ mov(ToRegister(result), factory()->true_value());
__ j(cc, &done);
__ j(cc, &done, Label::kNear);
__ bind(&unordered);
__ mov(ToRegister(result), factory()->false_value());
@ -1525,8 +1525,8 @@ void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
__ cmp(left, Operand(right));
__ mov(result, factory()->true_value());
NearLabel done;
__ j(equal, &done);
Label done;
__ j(equal, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
}
@ -1553,27 +1553,27 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
__ cmp(reg, factory()->null_value());
if (instr->is_strict()) {
__ mov(result, factory()->true_value());
NearLabel done;
__ j(equal, &done);
Label done;
__ j(equal, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
} else {
NearLabel true_value, false_value, done;
__ j(equal, &true_value);
Label true_value, false_value, done;
__ j(equal, &true_value, Label::kNear);
__ cmp(reg, factory()->undefined_value());
__ j(equal, &true_value);
__ j(equal, &true_value, Label::kNear);
__ test(reg, Immediate(kSmiTagMask));
__ j(zero, &false_value);
__ j(zero, &false_value, Label::kNear);
// Check for undetectable objects by looking in the bit field in
// the map. The object has already been smi checked.
Register scratch = result;
__ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
__ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
__ test(scratch, Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, &true_value);
__ j(not_zero, &true_value, Label::kNear);
__ bind(&false_value);
__ mov(result, factory()->false_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_value);
__ mov(result, factory()->true_value());
__ bind(&done);
@ -1684,8 +1684,8 @@ void LCodeGen::DoIsSmi(LIsSmi* instr) {
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
__ test(input, Immediate(kSmiTagMask));
__ mov(result, factory()->true_value());
NearLabel done;
__ j(zero, &done);
Label done;
__ j(zero, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
}
@ -1728,12 +1728,13 @@ void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
__ test(input, Immediate(kSmiTagMask));
NearLabel done, is_false;
__ j(zero, &is_false);
Label done, is_false;
__ j(zero, &is_false, Label::kNear);
__ CmpObjectType(input, TestType(instr->hydrogen()), result);
__ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
__ j(NegateCondition(BranchCondition(instr->hydrogen())),
&is_false, Label::kNear);
__ mov(result, factory()->true_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&is_false);
__ mov(result, factory()->false_value());
__ bind(&done);
@ -1778,8 +1779,8 @@ void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
__ mov(result, factory()->true_value());
__ test(FieldOperand(input, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask));
NearLabel done;
__ j(zero, &done);
Label done;
__ j(zero, &done, Label::kNear);
__ mov(result, factory()->false_value());
__ bind(&done);
}
@ -1861,16 +1862,16 @@ void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
ASSERT(input.is(result));
Register temp = ToRegister(instr->TempAt(0));
Handle<String> class_name = instr->hydrogen()->class_name();
NearLabel done;
Label done;
Label is_true, is_false;
EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input);
__ j(not_equal, &is_false);
__ j(not_equal, &is_false, Label::kNear);
__ bind(&is_true);
__ mov(result, factory()->true_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&is_false);
__ mov(result, factory()->false_value());
@ -1918,11 +1919,11 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
InstanceofStub stub(InstanceofStub::kArgsInRegisters);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED);
NearLabel true_value, done;
Label true_value, done;
__ test(eax, Operand(eax));
__ j(zero, &true_value);
__ j(zero, &true_value, Label::kNear);
__ mov(ToRegister(instr->result()), factory()->false_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_value);
__ mov(ToRegister(instr->result()), factory()->true_value());
__ bind(&done);
@ -1972,12 +1973,12 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// This is the inlined call site instanceof cache. The two occurences of the
// hole value will be patched to the last map/result pair generated by the
// instanceof stub.
NearLabel cache_miss;
Label cache_miss;
Register map = ToRegister(instr->TempAt(0));
__ mov(map, FieldOperand(object, HeapObject::kMapOffset));
__ bind(deferred->map_check()); // Label for calculating code patching.
__ cmp(map, factory()->the_hole_value()); // Patched to cached map.
__ j(not_equal, &cache_miss, not_taken);
__ j(not_equal, &cache_miss, not_taken, Label::kNear);
__ mov(eax, factory()->the_hole_value()); // Patched to either true or false.
__ jmp(&done);
@ -2069,11 +2070,11 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
if (op == Token::GT || op == Token::LTE) {
condition = ReverseCondition(condition);
}
NearLabel true_value, done;
Label true_value, done;
__ test(eax, Operand(eax));
__ j(condition, &true_value);
__ j(condition, &true_value, Label::kNear);
__ mov(ToRegister(instr->result()), factory()->false_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_value);
__ mov(ToRegister(instr->result()), factory()->true_value());
__ bind(&done);
@ -2239,23 +2240,23 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);
} else {
NearLabel done;
Label done;
for (int i = 0; i < map_count - 1; ++i) {
Handle<Map> map = instr->hydrogen()->types()->at(i);
NearLabel next;
Label next;
__ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
__ j(not_equal, &next);
__ j(not_equal, &next, Label::kNear);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&next);
}
Handle<Map> map = instr->hydrogen()->types()->last();
__ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
if (instr->hydrogen()->need_generic()) {
NearLabel generic;
__ j(not_equal, &generic);
Label generic;
__ j(not_equal, &generic, Label::kNear);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&generic);
__ mov(ecx, name);
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
@ -2290,10 +2291,10 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
DeoptimizeIf(not_equal, instr->environment());
// Check whether the function has an instance prototype.
NearLabel non_instance;
Label non_instance;
__ test_b(FieldOperand(result, Map::kBitFieldOffset),
1 << Map::kHasNonInstancePrototype);
__ j(not_zero, &non_instance);
__ j(not_zero, &non_instance, Label::kNear);
// Get the prototype or initial map from the function.
__ mov(result,
@ -2304,13 +2305,13 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
DeoptimizeIf(equal, instr->environment());
// If the function does not have an initial map, we're done.
NearLabel done;
Label done;
__ CmpObjectType(result, MAP_TYPE, temp);
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
// Get the prototype from the initial map.
__ mov(result, FieldOperand(result, Map::kPrototypeOffset));
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Non-instance prototype: Fetch prototype from constructor field
// in the function's map.
@ -2327,13 +2328,13 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
Register input = ToRegister(instr->InputAt(0));
__ mov(result, FieldOperand(input, JSObject::kElementsOffset));
if (FLAG_debug_code) {
NearLabel done;
Label done;
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
Immediate(factory()->fixed_array_map()));
__ j(equal, &done);
__ j(equal, &done, Label::kNear);
__ cmp(FieldOperand(result, HeapObject::kMapOffset),
Immediate(factory()->fixed_cow_array_map()));
__ j(equal, &done);
__ j(equal, &done, Label::kNear);
Register temp((result.is(eax)) ? ebx : eax);
__ push(temp);
__ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
@ -2453,16 +2454,16 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
Register result = ToRegister(instr->result());
// Check for arguments adapter frame.
NearLabel done, adapted;
Label done, adapted;
__ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
__ mov(result, Operand(result, StandardFrameConstants::kContextOffset));
__ cmp(Operand(result),
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
__ j(equal, &adapted);
__ j(equal, &adapted, Label::kNear);
// No arguments adaptor frame.
__ mov(result, Operand(ebp));
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Arguments adaptor frame present.
__ bind(&adapted);
@ -2478,12 +2479,12 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
Operand elem = ToOperand(instr->InputAt(0));
Register result = ToRegister(instr->result());
NearLabel done;
Label done;
// If no arguments adaptor frame the number of arguments is fixed.
__ cmp(ebp, elem);
__ mov(result, Immediate(scope()->num_parameters()));
__ j(equal, &done);
__ j(equal, &done, Label::kNear);
// Arguments adaptor frame present. Get argument length from there.
__ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
@ -2508,18 +2509,18 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
// If the receiver is null or undefined, we have to pass the global object
// as a receiver.
NearLabel global_object, receiver_ok;
Label global_object, receiver_ok;
__ 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));
DeoptimizeIf(equal, instr->environment());
__ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch);
DeoptimizeIf(below, instr->environment());
__ jmp(&receiver_ok);
__ jmp(&receiver_ok, Label::kNear);
__ bind(&global_object);
// TODO(kmillikin): We have a hydrogen value for the global object. See
@ -2540,10 +2541,10 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
// Loop through the arguments pushing them onto the execution
// stack.
NearLabel invoke, loop;
Label invoke, loop;
// length is a small non-negative integer, due to the test above.
__ test(length, Operand(length));
__ j(zero, &invoke);
__ j(zero, &invoke, Label::kNear);
__ bind(&loop);
__ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
__ dec(length);
@ -2895,20 +2896,20 @@ void LCodeGen::DoPower(LPower* instr) {
void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
ASSERT(instr->InputAt(0)->Equals(instr->result()));
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
NearLabel positive, done, zero, negative;
Label positive, done, zero;
__ xorps(xmm0, xmm0);
__ ucomisd(input_reg, xmm0);
__ j(above, &positive);
__ j(equal, &zero);
__ j(above, &positive, Label::kNear);
__ j(equal, &zero, Label::kNear);
ExternalReference nan = ExternalReference::address_of_nan();
__ movdbl(input_reg, Operand::StaticVariable(nan));
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&zero);
__ push(Immediate(0xFFF00000));
__ push(Immediate(0));
__ movdbl(input_reg, Operand(esp, 0));
__ add(Operand(esp), Immediate(kDoubleSize));
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&positive);
__ fldln2();
__ sub(Operand(esp), Immediate(kDoubleSize));
@ -3128,9 +3129,9 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
// instruction.
ASSERT(temp.is(eax));
__ mov(temp, ToRegister(instr->value()));
NearLabel done;
Label done;
__ test(temp, Immediate(0xFFFFFF00));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
__ setcc(negative, temp); // 1 if negative, 0 if positive.
__ dec_b(temp); // 0 if negative, 255 if positive.
__ bind(&done);
@ -3237,7 +3238,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
DeferredStringCharCodeAt* deferred =
new DeferredStringCharCodeAt(this, instr);
NearLabel flat_string, ascii_string, done;
Label flat_string, ascii_string, done;
// Fetch the instance type of the receiver into result register.
__ mov(result, FieldOperand(string, HeapObject::kMapOffset));
@ -3246,7 +3247,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
// We need special handling for non-flat strings.
STATIC_ASSERT(kSeqStringTag == 0);
__ test(result, Immediate(kStringRepresentationMask));
__ j(zero, &flat_string);
__ j(zero, &flat_string, Label::kNear);
// Handle non-flat strings.
__ test(result, Immediate(kIsConsStringMask));
@ -3273,7 +3274,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
__ bind(&flat_string);
STATIC_ASSERT(kAsciiStringTag != 0);
__ test(result, Immediate(kStringEncodingMask));
__ j(not_zero, &ascii_string);
__ j(not_zero, &ascii_string, Label::kNear);
// Two-byte string.
// Load the two-byte character code into the result register.
@ -3289,7 +3290,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
times_2,
SeqTwoByteString::kHeaderSize));
}
__ jmp(&done);
__ jmp(&done, Label::kNear);
// ASCII string.
// Load the byte into the result register.
@ -3450,13 +3451,13 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
// There was overflow, so bits 30 and 31 of the original integer
// disagree. Try to allocate a heap number in new space and store
// the value in there. If that fails, call the runtime system.
NearLabel done;
Label done;
__ SmiUntag(reg);
__ xor_(reg, 0x80000000);
__ cvtsi2sd(xmm0, Operand(reg));
if (FLAG_inline_new) {
__ AllocateHeapNumber(reg, tmp, no_reg, &slow);
__ jmp(&done);
__ jmp(&done, Label::kNear);
}
// Slow case: Call the runtime system to do the number allocation.
@ -3538,16 +3539,16 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
void LCodeGen::EmitNumberUntagD(Register input_reg,
XMMRegister result_reg,
LEnvironment* env) {
NearLabel load_smi, heap_number, done;
Label load_smi, heap_number, done;
// Smi check.
__ test(input_reg, Immediate(kSmiTagMask));
__ j(zero, &load_smi, not_taken);
__ j(zero, &load_smi, not_taken, Label::kNear);
// Heap number map check.
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
factory()->heap_number_map());
__ j(equal, &heap_number);
__ j(equal, &heap_number, Label::kNear);
__ cmp(input_reg, factory()->undefined_value());
DeoptimizeIf(not_equal, env);
@ -3555,12 +3556,12 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
// Convert undefined to NaN.
ExternalReference nan = ExternalReference::address_of_nan();
__ movdbl(result_reg, Operand::StaticVariable(nan));
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Heap number to XMM conversion.
__ bind(&heap_number);
__ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Smi to XMM conversion
__ bind(&load_smi);
@ -3582,7 +3583,7 @@ class DeferredTaggedToI: public LDeferredCode {
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
NearLabel done, heap_number;
Label done, heap_number;
Register input_reg = ToRegister(instr->InputAt(0));
// Heap number map check.
@ -3590,18 +3591,18 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
factory()->heap_number_map());
if (instr->truncating()) {
__ j(equal, &heap_number);
__ j(equal, &heap_number, Label::kNear);
// Check for undefined. Undefined is converted to zero for truncating
// conversions.
__ cmp(input_reg, factory()->undefined_value());
DeoptimizeIf(not_equal, instr->environment());
__ mov(input_reg, 0);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&heap_number);
if (CpuFeatures::IsSupported(SSE3)) {
CpuFeatures::Scope scope(SSE3);
NearLabel convert;
Label convert;
// Use more powerful conversion when sse3 is available.
// Load x87 register with heap number.
__ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
@ -3611,7 +3612,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
const uint32_t kTooBigExponent =
(HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
__ cmp(Operand(input_reg), Immediate(kTooBigExponent));
__ j(less, &convert);
__ j(less, &convert, Label::kNear);
// Pop FPU stack before deoptimizing.
__ ffree(0);
__ fincstp();
@ -3625,7 +3626,6 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
__ add(Operand(esp), Immediate(kDoubleSize));
} else {
NearLabel deopt;
XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
__ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ cvttsd2si(input_reg, Operand(xmm0));
@ -3712,8 +3712,8 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
if (CpuFeatures::IsSupported(SSE3)) {
// This will deoptimize if the exponent of the input in out of range.
CpuFeatures::Scope scope(SSE3);
NearLabel convert, done;
__ j(not_equal, &done);
Label convert, done;
__ j(not_equal, &done, Label::kNear);
__ sub(Operand(esp), Immediate(kDoubleSize));
__ movdbl(Operand(esp, 0), input_reg);
// Get exponent alone and check for too-big exponent.
@ -3722,7 +3722,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
const uint32_t kTooBigExponent =
(HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
__ cmp(Operand(result_reg), Immediate(kTooBigExponent));
__ j(less, &convert);
__ j(less, &convert, Label::kNear);
__ add(Operand(esp), Immediate(kDoubleSize));
DeoptimizeIf(no_condition, instr->environment());
__ bind(&convert);
@ -3733,13 +3733,13 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
__ add(Operand(esp), Immediate(kDoubleSize));
__ bind(&done);
} else {
NearLabel done;
Label done;
Register temp_reg = ToRegister(instr->TempAt(0));
XMMRegister xmm_scratch = xmm0;
// If cvttsd2si succeeded, we're done. Otherwise, we attempt
// manual conversion.
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
// Get high 32 bits of the input in result_reg and temp_reg.
__ pshufd(xmm_scratch, input_reg, 1);
@ -3789,7 +3789,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
__ bind(&done);
}
} else {
NearLabel done;
Label done;
__ cvttsd2si(result_reg, Operand(input_reg));
__ cvtsi2sd(xmm0, Operand(result_reg));
__ ucomisd(xmm0, input_reg);
@ -3799,7 +3799,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
// The integer converted back is equal to the original. We
// only have to test if we got -0 as an input.
__ test(result_reg, Operand(result_reg));
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
__ movmskpd(result_reg, input_reg);
// Bit 0 contains the sign of the double in input_reg.
// If input was positive, we are ok and return 0, otherwise
@ -3976,7 +3976,7 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
NearLabel materialized;
Label materialized;
// Registers will be used as follows:
// edi = JS function.
// ecx = literals array.
@ -3988,7 +3988,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
instr->hydrogen()->literal_index() * kPointerSize;
__ mov(ebx, FieldOperand(ecx, literal_offset));
__ cmp(ebx, factory()->undefined_value());
__ j(not_equal, &materialized);
__ j(not_equal, &materialized, Label::kNear);
// Create regexp literal using runtime function
// Result will be in eax.
@ -4064,16 +4064,16 @@ void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
Register result = ToRegister(instr->result());
Label true_label;
Label false_label;
NearLabel done;
Label done;
Condition final_branch_condition = EmitTypeofIs(&true_label,
&false_label,
input,
instr->type_literal());
__ j(final_branch_condition, &true_label);
__ j(final_branch_condition, &true_label, Label::kNear);
__ bind(&false_label);
__ mov(result, factory()->false_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_label);
__ mov(result, factory()->true_value());
@ -4167,15 +4167,14 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
Register result = ToRegister(instr->result());
NearLabel true_label;
NearLabel false_label;
NearLabel done;
Label true_label;
Label done;
EmitIsConstructCall(result);
__ j(equal, &true_label);
__ j(equal, &true_label, Label::kNear);
__ mov(result, factory()->false_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_label);
__ mov(result, factory()->true_value());
@ -4199,10 +4198,10 @@ void LCodeGen::EmitIsConstructCall(Register temp) {
__ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
// Skip the arguments adaptor frame if it exists.
NearLabel check_frame_marker;
Label check_frame_marker;
__ cmp(Operand(temp, StandardFrameConstants::kContextOffset),
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
__ j(not_equal, &check_frame_marker);
__ j(not_equal, &check_frame_marker, Label::kNear);
__ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
// Check the marker in the calling frame.
@ -4251,11 +4250,11 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
void LCodeGen::DoStackCheck(LStackCheck* instr) {
// Perform stack overflow check.
NearLabel done;
Label done;
ExternalReference stack_limit =
ExternalReference::address_of_stack_limit(isolate());
__ cmp(esp, Operand::StaticVariable(stack_limit));
__ j(above_equal, &done);
__ j(above_equal, &done, Label::kNear);
StackCheckStub stub;
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT);

View File

@ -484,9 +484,9 @@ void MacroAssembler::Throw(Register value) {
// not NULL. The frame pointer is NULL in the exception handler of
// a JS entry frame.
Set(esi, Immediate(0)); // Tentatively set context pointer to NULL.
NearLabel skip;
Label skip;
cmp(ebp, 0);
j(equal, &skip, not_taken);
j(equal, &skip, not_taken, Label::kNear);
mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
bind(&skip);
@ -511,12 +511,12 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
mov(esp, Operand::StaticVariable(handler_address));
// Unwind the handlers until the ENTRY handler is found.
NearLabel loop, done;
Label loop, done;
bind(&loop);
// Load the type of the current stack handler.
const int kStateOffset = StackHandlerConstants::kStateOffset;
cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY));
j(equal, &done);
j(equal, &done, Label::kNear);
// Fetch the next handler in the list.
const int kNextOffset = StackHandlerConstants::kNextOffset;
mov(esp, Operand(esp, kNextOffset));

View File

@ -971,9 +971,9 @@ void RegExpMacroAssemblerIA32::ReadStackPointerFromRegister(int reg) {
}
void RegExpMacroAssemblerIA32::SetCurrentPositionFromEnd(int by) {
NearLabel after_position;
Label after_position;
__ cmp(edi, -by * char_size());
__ j(greater_equal, &after_position);
__ j(greater_equal, &after_position, Label::kNear);
__ mov(edi, -by * char_size());
// On RegExp code entry (where this operation is used), the character before
// the current position is expected to be already loaded.

View File

@ -3511,9 +3511,9 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
switch (array_type) {
case kExternalPixelArray:
{ // Clamp the value to [0..255].
NearLabel done;
Label done;
__ test(ecx, Immediate(0xFFFFFF00));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
__ setcc(negative, ecx); // 1 if negative, 0 if positive.
__ dec_b(ecx); // 0 if negative, 255 if positive.
__ bind(&done);
@ -3594,9 +3594,9 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
switch (array_type) {
case kExternalPixelArray:
{ // Clamp the value to [0..255].
NearLabel done;
Label done;
__ test(ecx, Immediate(0xFFFFFF00));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
__ setcc(negative, ecx); // 1 if negative, 0 if positive.
__ dec_b(ecx); // 0 if negative, 255 if positive.
__ bind(&done);

View File

@ -458,6 +458,20 @@ void Assembler::bind_to(Label* L, int pos) {
int last_imm32 = pos - (current + sizeof(int32_t));
long_at_put(current, last_imm32);
}
while (L->is_near_linked()) {
int fixup_pos = L->near_link_pos();
int offset_to_next =
static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
ASSERT(offset_to_next <= 0);
int disp = pos - (fixup_pos + sizeof(int8_t));
ASSERT(is_int8(disp));
set_byte_at(fixup_pos, disp);
if (offset_to_next < 0) {
L->link_to(fixup_pos + offset_to_next, Label::kNear);
} else {
L->UnuseNear();
}
}
L->bind_to(pos);
}
@ -1214,7 +1228,7 @@ void Assembler::int3() {
}
void Assembler::j(Condition cc, Label* L) {
void Assembler::j(Condition cc, Label* L, Hint hint, Label::Distance distance) {
if (cc == always) {
jmp(L);
return;
@ -1223,6 +1237,7 @@ void Assembler::j(Condition cc, Label* L) {
}
EnsureSpace ensure_space(this);
ASSERT(is_uint4(cc));
if (FLAG_emit_branch_hints && hint != no_hint) emit(hint);
if (L->is_bound()) {
const int short_size = 2;
const int long_size = 6;
@ -1238,6 +1253,17 @@ void Assembler::j(Condition cc, Label* L) {
emit(0x80 | cc);
emitl(offs - long_size);
}
} else if (distance == Label::kNear) {
// 0111 tttn #8-bit disp
emit(0x70 | cc);
byte disp = 0x00;
if (L->is_near_linked()) {
int offset = L->near_link_pos() - pc_offset();
ASSERT(is_int8(offset));
disp = static_cast<byte>(offset & 0xFF);
}
L->link_to(pc_offset(), Label::kNear);
emit(disp);
} else if (L->is_linked()) {
// 0000 1111 1000 tttn #32-bit disp.
emit(0x0F);
@ -1287,7 +1313,7 @@ void Assembler::j(Condition cc, NearLabel* L, Hint hint) {
}
void Assembler::jmp(Label* L) {
void Assembler::jmp(Label* L, Label::Distance distance) {
EnsureSpace ensure_space(this);
const int short_size = sizeof(int8_t);
const int long_size = sizeof(int32_t);
@ -1303,7 +1329,17 @@ void Assembler::jmp(Label* L) {
emit(0xE9);
emitl(offs - long_size);
}
} else if (L->is_linked()) {
} else if (distance == Label::kNear) {
emit(0xEB);
byte disp = 0x00;
if (L->is_near_linked()) {
int offset = L->near_link_pos() - pc_offset();
ASSERT(is_int8(offset));
disp = static_cast<byte>(offset & 0xFF);
}
L->link_to(pc_offset(), Label::kNear);
emit(disp);
} else if (L->is_linked()) {
// 1110 1001 #32-bit disp.
emit(0xE9);
emitl(L->pos());

View File

@ -1178,6 +1178,7 @@ class Assembler : public AssemblerBase {
// but it may be bound only once.
void bind(Label* L); // binds an unbound label L to the current code position
// DEPRECATED. Use bind(Label*) with jmp(Label*, Label::kNear) instead.
void bind(NearLabel* L);
// Calls
@ -1202,7 +1203,8 @@ class Assembler : public AssemblerBase {
// Jumps
// Jump short or near relative.
// Use a 32-bit signed displacement.
void jmp(Label* L); // unconditional jump to L
// Unconditional jump to L
void jmp(Label* L, Label::Distance distance = Label::kFar);
void jmp(Handle<Code> target, RelocInfo::Mode rmode);
// Jump near absolute indirect (r64)
@ -1212,13 +1214,21 @@ class Assembler : public AssemblerBase {
void jmp(const Operand& src);
// Short jump
// DEPRECATED. Use jmp(L, Label::kNear) instead.
void jmp(NearLabel* L);
// Conditional jumps
void j(Condition cc, Label* L);
void j(Condition cc,
Label* L,
Hint hint,
Label::Distance distance = Label::kFar);
void j(Condition cc, Label* L, Label::Distance distance = Label::kFar) {
j(cc, L, no_hint, distance);
}
void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
// Conditional short jump
// DEPRECATED. Use jmp(L, Label::kNear) instead.
void j(Condition cc, NearLabel* L, Hint hint = no_hint);
// Floating-point operations

View File

@ -576,15 +576,15 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
__ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize));
// Switch on the state.
NearLabel not_no_registers, not_tos_rax;
Label not_no_registers, not_tos_rax;
__ cmpq(rcx, Immediate(FullCodeGenerator::NO_REGISTERS));
__ j(not_equal, &not_no_registers);
__ j(not_equal, &not_no_registers, Label::kNear);
__ ret(1 * kPointerSize); // Remove state.
__ bind(&not_no_registers);
__ movq(rax, Operand(rsp, 2 * kPointerSize));
__ cmpq(rcx, Immediate(FullCodeGenerator::TOS_REG));
__ j(not_equal, &not_tos_rax);
__ j(not_equal, &not_tos_rax, Label::kNear);
__ ret(2 * kPointerSize); // Remove state, rax.
__ bind(&not_tos_rax);
@ -1474,17 +1474,17 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
// If the result was -1 it means that we couldn't optimize the
// function. Just return and continue in the unoptimized version.
NearLabel skip;
Label skip;
__ SmiCompare(rax, Smi::FromInt(-1));
__ j(not_equal, &skip);
__ j(not_equal, &skip, Label::kNear);
__ ret(0);
// If we decide not to perform on-stack replacement we perform a
// stack guard check to enable interrupts.
__ bind(&stack_check);
NearLabel ok;
Label ok;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
__ j(above_equal, &ok);
__ j(above_equal, &ok, Label::kNear);
StackCheckStub stub;
__ TailCallStub(&stub);

View File

@ -40,15 +40,15 @@ namespace internal {
void ToNumberStub::Generate(MacroAssembler* masm) {
// The ToNumber stub takes one argument in eax.
NearLabel check_heap_number, call_builtin;
Label check_heap_number, call_builtin;
__ SmiTest(rax);
__ j(not_zero, &check_heap_number);
__ j(not_zero, &check_heap_number, Label::kNear);
__ Ret();
__ bind(&check_heap_number);
__ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &call_builtin);
__ j(not_equal, &call_builtin, Label::kNear);
__ Ret();
__ bind(&call_builtin);
@ -232,12 +232,12 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
void ToBooleanStub::Generate(MacroAssembler* masm) {
NearLabel false_result, true_result, not_string;
Label false_result, true_result, not_string;
__ movq(rax, Operand(rsp, 1 * kPointerSize));
// 'null' => false.
__ CompareRoot(rax, Heap::kNullValueRootIndex);
__ j(equal, &false_result);
__ j(equal, &false_result, Label::kNear);
// Get the map and type of the heap object.
// We don't use CmpObjectType because we manipulate the type field.
@ -247,28 +247,28 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
// Undetectable => false.
__ movzxbq(rbx, FieldOperand(rdx, Map::kBitFieldOffset));
__ and_(rbx, Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, &false_result);
__ j(not_zero, &false_result, Label::kNear);
// JavaScript object => true.
__ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE));
__ j(above_equal, &true_result);
__ j(above_equal, &true_result, Label::kNear);
// String value => false iff empty.
__ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
__ j(above_equal, &not_string);
__ j(above_equal, &not_string, Label::kNear);
__ movq(rdx, FieldOperand(rax, String::kLengthOffset));
__ SmiTest(rdx);
__ j(zero, &false_result);
__ jmp(&true_result);
__ j(zero, &false_result, Label::kNear);
__ jmp(&true_result, Label::kNear);
__ bind(&not_string);
__ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &true_result);
__ j(not_equal, &true_result, Label::kNear);
// HeapNumber => false iff +0, -0, or NaN.
// These three cases set the zero flag when compared to zero using ucomisd.
__ xorps(xmm0, xmm0);
__ ucomisd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
__ j(zero, &false_result);
__ j(zero, &false_result, Label::kNear);
// Fall through to |true_result|.
// Return 1/0 for true/false in rax.
@ -334,7 +334,7 @@ void IntegerConvert(MacroAssembler* masm,
// cvttsd2si (32-bit version) directly.
Register double_exponent = rbx;
Register double_value = rdi;
NearLabel done, exponent_63_plus;
Label done, exponent_63_plus;
// Get double and extract exponent.
__ movq(double_value, FieldOperand(source, HeapNumber::kValueOffset));
// Clear result preemptively, in case we need to return zero.
@ -347,17 +347,17 @@ void IntegerConvert(MacroAssembler* masm,
__ subl(double_exponent, Immediate(HeapNumber::kExponentBias));
// Check whether the exponent is too big for a 63 bit unsigned integer.
__ cmpl(double_exponent, Immediate(63));
__ j(above_equal, &exponent_63_plus);
__ j(above_equal, &exponent_63_plus, Label::kNear);
// Handle exponent range 0..62.
__ cvttsd2siq(result, xmm0);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&exponent_63_plus);
// Exponent negative or 63+.
__ cmpl(double_exponent, Immediate(83));
// If exponent negative or above 83, number contains no significant bits in
// the range 0..2^31, so result is zero, and rcx already holds zero.
__ j(above, &done);
__ j(above, &done, Label::kNear);
// Exponent in rage 63..83.
// Mantissa * 2^exponent contains bits in the range 2^0..2^31, namely
@ -1157,18 +1157,18 @@ void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
}
// Convert oddball arguments to numbers.
NearLabel check, done;
Label check, done;
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, &check);
__ j(not_equal, &check, Label::kNear);
if (Token::IsBitOp(op_)) {
__ xor_(rdx, rdx);
} else {
__ LoadRoot(rdx, Heap::kNanValueRootIndex);
}
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&check);
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
if (Token::IsBitOp(op_)) {
__ xor_(rax, rax);
} else {
@ -1277,7 +1277,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
const bool tagged = (argument_type_ == TAGGED);
if (tagged) {
NearLabel input_not_smi;
NearLabel loaded;
Label loaded;
// Test that rax is a number.
__ movq(rax, Operand(rsp, kPointerSize));
__ JumpIfNotSmi(rax, &input_not_smi);
@ -1291,7 +1291,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
__ movq(rdx, xmm1);
__ fld_d(Operand(rsp, 0));
__ addq(rsp, Immediate(kDoubleSize));
__ jmp(&loaded);
__ jmp(&loaded, Label::kNear);
__ bind(&input_not_smi);
// Check if input is a HeapNumber.
@ -1366,9 +1366,9 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
__ addl(rcx, rcx);
__ lea(rcx, Operand(rax, rcx, times_8, 0));
// Check if cache matches: Double value is stored in uint32_t[2] array.
NearLabel cache_miss;
Label cache_miss;
__ cmpq(rbx, Operand(rcx, 0));
__ j(not_equal, &cache_miss);
__ j(not_equal, &cache_miss, Label::kNear);
// Cache hit!
__ movq(rax, Operand(rcx, 2 * kIntSize));
if (tagged) {
@ -1476,8 +1476,8 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
__ j(below, &in_range);
// Check for infinity and NaN. Both return NaN for sin.
__ cmpl(rdi, Immediate(0x7ff));
NearLabel non_nan_result;
__ j(not_equal, &non_nan_result);
Label non_nan_result;
__ j(not_equal, &non_nan_result, Label::kNear);
// Input is +/-Infinity or NaN. Result is NaN.
__ fstp(0);
__ LoadRoot(kScratchRegister, Heap::kNanValueRootIndex);
@ -1505,7 +1505,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
// Compute st(0) % st(1)
{
NearLabel partial_remainder_loop;
Label partial_remainder_loop;
__ bind(&partial_remainder_loop);
__ fprem1();
__ fwait();
@ -1698,7 +1698,7 @@ void FloatingPointHelper::NumbersToSmis(MacroAssembler* masm,
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
NearLabel first_smi, check_second;
NearLabel first_smi;
__ JumpIfSmi(first, &first_smi);
__ cmpq(FieldOperand(first, HeapObject::kMapOffset), heap_number_map);
__ j(not_equal, on_not_smis);
@ -1714,7 +1714,6 @@ void FloatingPointHelper::NumbersToSmis(MacroAssembler* masm,
__ j(not_equal, on_not_smis);
__ Integer32ToSmi(first, smi_result);
__ bind(&check_second);
__ JumpIfSmi(second, (on_success != NULL) ? on_success : &done);
__ bind(&first_smi);
if (FLAG_debug_code) {
@ -1785,20 +1784,20 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movq(rdx, rax);
// Get absolute value of exponent.
NearLabel no_neg;
Label no_neg;
__ cmpl(rax, Immediate(0));
__ j(greater_equal, &no_neg);
__ j(greater_equal, &no_neg, Label::kNear);
__ negl(rax);
__ bind(&no_neg);
// Load xmm1 with 1.
__ movaps(xmm1, xmm3);
NearLabel while_true;
NearLabel no_multiply;
Label while_true;
Label no_multiply;
__ bind(&while_true);
__ shrl(rax, Immediate(1));
__ j(not_carry, &no_multiply);
__ j(not_carry, &no_multiply, Label::kNear);
__ mulsd(xmm1, xmm0);
__ bind(&no_multiply);
__ mulsd(xmm0, xmm0);
@ -1829,11 +1828,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ j(parity_even, &call_runtime);
NearLabel base_not_smi;
NearLabel handle_special_cases;
Label handle_special_cases;
__ JumpIfNotSmi(rdx, &base_not_smi);
__ SmiToInteger32(rdx, rdx);
__ cvtlsi2sd(xmm0, rdx);
__ jmp(&handle_special_cases);
__ jmp(&handle_special_cases, Label::kNear);
__ bind(&base_not_smi);
__ CompareRoot(FieldOperand(rdx, HeapObject::kMapOffset),
@ -1848,14 +1847,14 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// base is in xmm0 and exponent is in xmm1.
__ bind(&handle_special_cases);
NearLabel not_minus_half;
Label not_minus_half;
// Test for -0.5.
// Load xmm2 with -0.5.
__ movq(rcx, V8_UINT64_C(0xBFE0000000000000), RelocInfo::NONE);
__ movq(xmm2, rcx);
// xmm2 now has -0.5.
__ ucomisd(xmm2, xmm1);
__ j(not_equal, &not_minus_half);
__ j(not_equal, &not_minus_half, Label::kNear);
// Calculates reciprocal of square root.
// sqrtsd returns -0 when input is -0. ECMA spec requires +0.
@ -2174,7 +2173,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// rax: RegExp data (FixedArray)
// Check the representation and encoding of the subject string.
NearLabel seq_ascii_string, seq_two_byte_string, check_code;
Label seq_ascii_string, seq_two_byte_string, check_code;
__ movq(rdi, Operand(rsp, kSubjectOffset));
__ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
__ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
@ -2182,10 +2181,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ andb(rbx, Immediate(
kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask));
STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string);
__ j(zero, &seq_two_byte_string, Label::kNear);
// Any other flat string must be a flat ascii string.
__ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
__ j(zero, &seq_ascii_string);
__ j(zero, &seq_ascii_string, Label::kNear);
// Check for flat cons string.
// A flat cons string is a cons string where the second part is the empty
@ -2209,7 +2208,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
Immediate(kStringRepresentationMask | kStringEncodingMask));
STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string);
__ j(zero, &seq_two_byte_string, Label::kNear);
// Any other flat string must be ascii.
__ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
Immediate(kStringRepresentationMask));
@ -2220,7 +2219,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// rax: RegExp data (FixedArray)
__ movq(r11, FieldOperand(rax, JSRegExp::kDataAsciiCodeOffset));
__ Set(rcx, 1); // Type is ascii.
__ jmp(&check_code);
__ jmp(&check_code, Label::kNear);
__ bind(&seq_two_byte_string);
// rdi: subject string (flat two-byte)
@ -2306,13 +2305,13 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Argument 4: End of string data
// Argument 3: Start of string data
NearLabel setup_two_byte, setup_rest;
Label setup_two_byte, setup_rest;
__ testb(rcx, rcx); // Last use of rcx as encoding of subject string.
__ j(zero, &setup_two_byte);
__ j(zero, &setup_two_byte, Label::kNear);
__ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
__ lea(arg4, FieldOperand(rdi, rcx, times_1, SeqAsciiString::kHeaderSize));
__ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize));
__ jmp(&setup_rest);
__ jmp(&setup_rest, Label::kNear);
__ bind(&setup_two_byte);
__ SmiToInteger32(rcx, FieldOperand(rdi, String::kLengthOffset));
__ lea(arg4, FieldOperand(rdi, rcx, times_2, SeqTwoByteString::kHeaderSize));
@ -2337,10 +2336,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ LeaveApiExitFrame();
// Check the result.
NearLabel success;
Label success;
Label exception;
__ cmpl(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS));
__ j(equal, &success);
__ j(equal, &success, Label::kNear);
__ cmpl(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION));
__ j(equal, &exception);
__ cmpl(rax, Immediate(NativeRegExpMacroAssembler::FAILURE));
@ -2389,12 +2388,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// rbx: last_match_info backing store (FixedArray)
// rcx: offsets vector
// rdx: number of capture registers
NearLabel next_capture, done;
Label next_capture, done;
// Capture register counter starts from number of capture registers and
// counts down until wraping after zero.
__ bind(&next_capture);
__ subq(rdx, Immediate(1));
__ j(negative, &done);
__ j(negative, &done, Label::kNear);
// Read the value from the static offsets vector buffer and make it a smi.
__ movl(rdi, Operand(rcx, rdx, times_int_size, 0));
__ Integer32ToSmi(rdi, rdi);
@ -2427,8 +2426,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ movq(pending_exception_operand, rdx);
__ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
NearLabel termination_exception;
__ j(equal, &termination_exception);
Label termination_exception;
__ j(equal, &termination_exception, Label::kNear);
__ Throw(rax);
__ bind(&termination_exception);
@ -2671,16 +2670,16 @@ void CompareStub::Generate(MacroAssembler* masm) {
// Two identical objects are equal unless they are both NaN or undefined.
{
NearLabel not_identical;
Label not_identical;
__ cmpq(rax, rdx);
__ j(not_equal, &not_identical);
__ j(not_equal, &not_identical, Label::kNear);
if (cc_ != equal) {
// Check for undefined. undefined OP undefined is false even though
// undefined == undefined.
NearLabel check_for_nan;
Label check_for_nan;
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, &check_for_nan);
__ j(not_equal, &check_for_nan, Label::kNear);
__ Set(rax, NegativeComparisonResult(cc_));
__ ret(0);
__ bind(&check_for_nan);
@ -2695,15 +2694,15 @@ void CompareStub::Generate(MacroAssembler* masm) {
__ Set(rax, EQUAL);
__ ret(0);
} else {
NearLabel heap_number;
Label heap_number;
// If it's not a heap number, then return equal for (in)equality operator.
__ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
factory->heap_number_map());
__ j(equal, &heap_number);
__ j(equal, &heap_number, Label::kNear);
if (cc_ != equal) {
// Call runtime on identical JSObjects. Otherwise return equal.
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
__ j(above_equal, &not_identical);
__ j(above_equal, &not_identical, Label::kNear);
}
__ Set(rax, EQUAL);
__ ret(0);
@ -2759,9 +2758,9 @@ void CompareStub::Generate(MacroAssembler* masm) {
// If the first object is a JS object, we have done pointer comparison.
STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
NearLabel first_non_object;
Label first_non_object;
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
__ j(below, &first_non_object);
__ j(below, &first_non_object, Label::kNear);
// Return non-zero (eax (not rax) is not zero)
Label return_not_equal;
STATIC_ASSERT(kHeapObjectTag != 0);
@ -2788,14 +2787,14 @@ void CompareStub::Generate(MacroAssembler* masm) {
// Generate the number comparison code.
if (include_number_compare_) {
Label non_number_comparison;
NearLabel unordered;
Label unordered;
FloatingPointHelper::LoadSSE2UnknownOperands(masm, &non_number_comparison);
__ xorl(rax, rax);
__ xorl(rcx, rcx);
__ ucomisd(xmm0, xmm1);
// Don't base result on EFLAGS when a NaN is involved.
__ j(parity_even, &unordered);
__ j(parity_even, &unordered, Label::kNear);
// Return a result of -1, 0, or 1, based on EFLAGS.
__ setcc(above, rax);
__ setcc(below, rcx);
@ -2860,7 +2859,7 @@ void CompareStub::Generate(MacroAssembler* masm) {
// Not strict equality. Objects are unequal if
// they are both JSObjects and not undetectable,
// and their pointers are different.
NearLabel not_both_objects, return_unequal;
Label not_both_objects, return_unequal;
// At most one is a smi, so we can test for smi by adding the two.
// A smi plus a heap object has the low bit set, a heap object plus
// a heap object has the low bit clear.
@ -2868,17 +2867,17 @@ void CompareStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kSmiTagMask == 1);
__ lea(rcx, Operand(rax, rdx, times_1, 0));
__ testb(rcx, Immediate(kSmiTagMask));
__ j(not_zero, &not_both_objects);
__ j(not_zero, &not_both_objects, Label::kNear);
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
__ j(below, &not_both_objects);
__ j(below, &not_both_objects, Label::kNear);
__ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
__ j(below, &not_both_objects);
__ j(below, &not_both_objects, Label::kNear);
__ testb(FieldOperand(rbx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
__ j(zero, &return_unequal);
__ j(zero, &return_unequal, Label::kNear);
__ testb(FieldOperand(rcx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
__ j(zero, &return_unequal);
__ j(zero, &return_unequal, Label::kNear);
// The objects are both undetectable, so they both compare as the value
// undefined, and are equal.
__ Set(rax, EQUAL);
@ -3108,11 +3107,11 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Handling of failure.
__ bind(&failure_returned);
NearLabel retry;
Label retry;
// If the returned exception is RETRY_AFTER_GC continue at retry label
STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
__ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
__ j(zero, &retry);
__ j(zero, &retry, Label::kNear);
// Special handling of out of memory exceptions.
__ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE);
@ -3413,11 +3412,11 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
// real lookup and update the call site cache.
if (!HasCallSiteInlineCheck()) {
// Look up the function and the map in the instanceof cache.
NearLabel miss;
Label miss;
__ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
__ j(not_equal, &miss);
__ j(not_equal, &miss, Label::kNear);
__ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex);
__ j(not_equal, &miss);
__ j(not_equal, &miss, Label::kNear);
__ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
__ ret(2 * kPointerSize);
__ bind(&miss);
@ -3453,15 +3452,15 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset));
// Loop through the prototype chain looking for the function prototype.
NearLabel loop, is_instance, is_not_instance;
Label loop, is_instance, is_not_instance;
__ LoadRoot(kScratchRegister, Heap::kNullValueRootIndex);
__ bind(&loop);
__ cmpq(rcx, rbx);
__ j(equal, &is_instance);
__ j(equal, &is_instance, Label::kNear);
__ cmpq(rcx, kScratchRegister);
// The code at is_not_instance assumes that kScratchRegister contains a
// non-zero GCable value (the null object in this case).
__ j(equal, &is_not_instance);
__ j(equal, &is_not_instance, Label::kNear);
__ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
__ movq(rcx, FieldOperand(rcx, Map::kPrototypeOffset));
__ jmp(&loop);
@ -3826,10 +3825,10 @@ void StringAddStub::Generate(MacroAssembler* masm) {
// rax: first string
// rdx: second string
// Check if either of the strings are empty. In that case return the other.
NearLabel second_not_zero_length, both_not_zero_length;
Label second_not_zero_length, both_not_zero_length;
__ movq(rcx, FieldOperand(rdx, String::kLengthOffset));
__ SmiTest(rcx);
__ j(not_zero, &second_not_zero_length);
__ j(not_zero, &second_not_zero_length, Label::kNear);
// Second string is empty, result is first string which is already in rax.
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->string_add_native(), 1);
@ -3837,7 +3836,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
__ bind(&second_not_zero_length);
__ movq(rbx, FieldOperand(rax, String::kLengthOffset));
__ SmiTest(rbx);
__ j(not_zero, &both_not_zero_length);
__ j(not_zero, &both_not_zero_length, Label::kNear);
// First string is empty, result is second string which is in rdx.
__ movq(rax, rdx);
__ IncrementCounter(counters->string_add_native(), 1);
@ -4131,9 +4130,9 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
ASSERT(count.is(rcx)); // rep movs count
// Nothing to do for zero characters.
NearLabel done;
Label done;
__ testl(count, count);
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
// Make count the number of bytes to copy.
if (!ascii) {
@ -4142,9 +4141,9 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
}
// Don't enter the rep movs if there are less than 4 bytes to copy.
NearLabel last_bytes;
Label last_bytes;
__ testl(count, Immediate(~7));
__ j(zero, &last_bytes);
__ j(zero, &last_bytes, Label::kNear);
// Copy from edi to esi using rep movs instruction.
__ movl(kScratchRegister, count);
@ -4158,7 +4157,7 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
// Check if there are more bytes to copy.
__ bind(&last_bytes);
__ testl(count, count);
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
// Copy remaining characters.
Label loop;
@ -4186,10 +4185,10 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
// Make sure that both characters are not digits as such strings has a
// different hash algorithm. Don't try to look for these in the symbol table.
NearLabel not_array_index;
Label not_array_index;
__ leal(scratch, Operand(c1, -'0'));
__ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
__ j(above, &not_array_index);
__ j(above, &not_array_index, Label::kNear);
__ leal(scratch, Operand(c2, -'0'));
__ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
__ j(below_equal, not_found);
@ -4251,9 +4250,9 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
SymbolTable::kElementsStartOffset));
// If entry is undefined no string with this hash can be found.
NearLabel is_string;
Label is_string;
__ CmpObjectType(candidate, ODDBALL_TYPE, map);
__ j(not_equal, &is_string);
__ j(not_equal, &is_string, Label::kNear);
__ CompareRoot(candidate, Heap::kUndefinedValueRootIndex);
__ j(equal, not_found);
@ -4505,19 +4504,19 @@ void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm,
Register length = scratch1;
// Compare lengths.
NearLabel check_zero_length;
Label check_zero_length;
__ movq(length, FieldOperand(left, String::kLengthOffset));
__ SmiCompare(length, FieldOperand(right, String::kLengthOffset));
__ j(equal, &check_zero_length);
__ j(equal, &check_zero_length, Label::kNear);
__ Move(rax, Smi::FromInt(NOT_EQUAL));
__ ret(0);
// Check if the length is zero.
NearLabel compare_chars;
Label compare_chars;
__ bind(&check_zero_length);
STATIC_ASSERT(kSmiTag == 0);
__ SmiTest(length);
__ j(not_zero, &compare_chars);
__ j(not_zero, &compare_chars, Label::kNear);
__ Move(rax, Smi::FromInt(EQUAL));
__ ret(0);
@ -4557,8 +4556,8 @@ void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
FieldOperand(right, String::kLengthOffset));
// Register scratch4 now holds left.length - right.length.
const Register length_difference = scratch4;
NearLabel left_shorter;
__ j(less, &left_shorter);
Label left_shorter;
__ j(less, &left_shorter, Label::kNear);
// The right string isn't longer that the left one.
// Get the right string's length by subtracting the (non-negative) difference
// from the left string's length.
@ -4567,10 +4566,10 @@ void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
// Register scratch1 now holds Min(left.length, right.length).
const Register min_length = scratch1;
NearLabel compare_lengths;
Label compare_lengths;
// If min-length is zero, go directly to comparing lengths.
__ SmiTest(min_length);
__ j(zero, &compare_lengths);
__ j(zero, &compare_lengths, Label::kNear);
// Compare loop.
NearLabel result_not_equal;
@ -4581,16 +4580,16 @@ void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
// Compare lengths (precomputed).
__ bind(&compare_lengths);
__ SmiTest(length_difference);
__ j(not_zero, &result_not_equal);
__ j(not_zero, &result_not_equal, Label::kNear);
// Result is EQUAL.
__ Move(rax, Smi::FromInt(EQUAL));
__ ret(0);
NearLabel result_greater;
Label result_greater;
__ bind(&result_not_equal);
// Unequal comparison of left to right, either character or length.
__ j(greater, &result_greater);
__ j(greater, &result_greater, Label::kNear);
// Result is LESS.
__ Move(rax, Smi::FromInt(LESS));
@ -4622,7 +4621,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop(
Register index = length; // index = -length;
// Compare loop.
NearLabel loop;
Label loop;
__ bind(&loop);
__ movb(scratch, Operand(left, index, times_1, 0));
__ cmpb(scratch, Operand(right, index, times_1, 0));
@ -4644,9 +4643,9 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
__ movq(rax, Operand(rsp, 1 * kPointerSize)); // right
// Check for identity.
NearLabel not_same;
Label not_same;
__ cmpq(rdx, rax);
__ j(not_equal, &not_same);
__ j(not_equal, &not_same, Label::kNear);
__ Move(rax, Smi::FromInt(EQUAL));
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->string_compare_native(), 1);
@ -4681,9 +4680,9 @@ void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
// For equality we do not care about the sign of the result.
__ subq(rax, rdx);
} else {
NearLabel done;
Label done;
__ subq(rdx, rax);
__ j(no_overflow, &done);
__ j(no_overflow, &done, Label::kNear);
// Correct sign of result in case of overflow.
__ SmiNot(rdx, rdx);
__ bind(&done);
@ -4699,16 +4698,16 @@ void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) {
ASSERT(state_ == CompareIC::HEAP_NUMBERS);
NearLabel generic_stub;
NearLabel unordered;
NearLabel miss;
Label generic_stub;
Label unordered;
Label miss;
Condition either_smi = masm->CheckEitherSmi(rax, rdx);
__ j(either_smi, &generic_stub);
__ j(either_smi, &generic_stub, Label::kNear);
__ CmpObjectType(rax, HEAP_NUMBER_TYPE, rcx);
__ j(not_equal, &miss);
__ j(not_equal, &miss, Label::kNear);
__ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx);
__ j(not_equal, &miss);
__ j(not_equal, &miss, Label::kNear);
// Load left and right operand
__ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
@ -4718,7 +4717,7 @@ void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) {
__ ucomisd(xmm0, xmm1);
// Don't base result on EFLAGS when a NaN is involved.
__ j(parity_even, &unordered);
__ j(parity_even, &unordered, Label::kNear);
// Return a result of -1, 0, or 1, based on EFLAGS.
// Performing mov, because xor would destroy the flag register.
@ -4750,9 +4749,9 @@ void ICCompareStub::GenerateSymbols(MacroAssembler* masm) {
Register tmp2 = rbx;
// Check that both operands are heap objects.
NearLabel miss;
Label miss;
Condition cond = masm->CheckEitherSmi(left, right, tmp1);
__ j(cond, &miss);
__ j(cond, &miss, Label::kNear);
// Check that both operands are symbols.
__ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset));
@ -4762,15 +4761,15 @@ void ICCompareStub::GenerateSymbols(MacroAssembler* masm) {
STATIC_ASSERT(kSymbolTag != 0);
__ and_(tmp1, tmp2);
__ testb(tmp1, Immediate(kIsSymbolMask));
__ j(zero, &miss);
__ j(zero, &miss, Label::kNear);
// Symbols are compared by identity.
NearLabel done;
Label done;
__ cmpq(left, right);
// Make sure rax is non-zero. At this point input operands are
// guaranteed to be non-zero.
ASSERT(right.is(rax));
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
STATIC_ASSERT(EQUAL == 0);
STATIC_ASSERT(kSmiTag == 0);
__ Move(rax, Smi::FromInt(EQUAL));
@ -4811,9 +4810,9 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
__ j(not_zero, &miss);
// Fast check for identical strings.
NearLabel not_same;
Label not_same;
__ cmpq(left, right);
__ j(not_equal, &not_same);
__ j(not_equal, &not_same, Label::kNear);
STATIC_ASSERT(EQUAL == 0);
STATIC_ASSERT(kSmiTag == 0);
__ Move(rax, Smi::FromInt(EQUAL));
@ -4824,11 +4823,11 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
// Check that both strings are symbols. If they are, we're done
// because we already know they are not identical.
NearLabel do_compare;
Label do_compare;
STATIC_ASSERT(kSymbolTag != 0);
__ and_(tmp1, tmp2);
__ testb(tmp1, Immediate(kIsSymbolMask));
__ j(zero, &do_compare);
__ j(zero, &do_compare, Label::kNear);
// Make sure rax is non-zero. At this point input operands are
// guaranteed to be non-zero.
ASSERT(right.is(rax));
@ -4858,14 +4857,14 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
ASSERT(state_ == CompareIC::OBJECTS);
NearLabel miss;
Label miss;
Condition either_smi = masm->CheckEitherSmi(rdx, rax);
__ j(either_smi, &miss);
__ j(either_smi, &miss, Label::kNear);
__ CmpObjectType(rax, JS_OBJECT_TYPE, rcx);
__ j(not_equal, &miss, not_taken);
__ j(not_equal, &miss, not_taken, Label::kNear);
__ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx);
__ j(not_equal, &miss, not_taken);
__ j(not_equal, &miss, not_taken, Label::kNear);
ASSERT(GetCondition() == equal);
__ subq(rax, rdx);

View File

@ -239,9 +239,9 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
{ Comment cmnt(masm_, "[ Stack check");
PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
NearLabel ok;
Label ok;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
__ j(above_equal, &ok);
__ j(above_equal, &ok, Label::kNear);
StackCheckStub stub;
__ CallStub(&stub);
__ bind(&ok);
@ -270,9 +270,9 @@ void FullCodeGenerator::ClearAccumulator() {
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
Comment cmnt(masm_, "[ Stack check");
NearLabel ok;
Label ok;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
__ j(above_equal, &ok);
__ j(above_equal, &ok, Label::kNear);
StackCheckStub stub;
__ CallStub(&stub);
// Record a mapping of this PC offset to the OSR id. This is used to find
@ -485,10 +485,10 @@ void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
void FullCodeGenerator::AccumulatorValueContext::Plug(
Label* materialize_true,
Label* materialize_false) const {
NearLabel done;
Label done;
__ bind(materialize_true);
__ Move(result_register(), isolate()->factory()->true_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(materialize_false);
__ Move(result_register(), isolate()->factory()->false_value());
__ bind(&done);
@ -498,10 +498,10 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
void FullCodeGenerator::StackValueContext::Plug(
Label* materialize_true,
Label* materialize_false) const {
NearLabel done;
Label done;
__ bind(materialize_true);
__ Push(isolate()->factory()->true_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(materialize_false);
__ Push(isolate()->factory()->false_value());
__ bind(&done);
@ -638,8 +638,8 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
// preparation to avoid preparing with the same AST id twice.
if (!context()->IsTest() || !info_->IsOptimizable()) return;
NearLabel skip;
if (should_normalize) __ jmp(&skip);
Label skip;
if (should_normalize) __ jmp(&skip, Label::kNear);
ForwardBailoutStack* current = forward_bailout_stack_;
while (current != NULL) {
@ -918,9 +918,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
__ JumpIfSmi(rdx, &call_runtime);
// For all objects but the receiver, check that the cache is empty.
NearLabel check_prototype;
Label check_prototype;
__ cmpq(rcx, rax);
__ j(equal, &check_prototype);
__ j(equal, &check_prototype, Label::kNear);
__ movq(rdx, FieldOperand(rdx, DescriptorArray::kEnumCacheBridgeCacheOffset));
__ cmpq(rdx, empty_fixed_array_value);
__ j(not_equal, &call_runtime);
@ -933,9 +933,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// The enum cache is valid. Load the map of the object being
// iterated over and use the cache for the iteration.
NearLabel use_cache;
Label use_cache;
__ movq(rax, FieldOperand(rax, HeapObject::kMapOffset));
__ jmp(&use_cache);
__ jmp(&use_cache, Label::kNear);
// Get the set of properties to enumerate.
__ bind(&call_runtime);
@ -945,10 +945,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// If we got a map from the runtime call, we can do a fast
// modification check. Otherwise, we got a fixed array, and we have
// to do a slow check.
NearLabel fixed_array;
Label fixed_array;
__ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
Heap::kMetaMapRootIndex);
__ j(not_equal, &fixed_array);
__ j(not_equal, &fixed_array, Label::kNear);
// We got a map in register rax. Get the enumeration cache from it.
__ bind(&use_cache);
@ -992,10 +992,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Check if the expected map still matches that of the enumerable.
// If not, we have to filter the key.
NearLabel update_each;
Label update_each;
__ movq(rcx, Operand(rsp, 4 * kPointerSize));
__ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
__ j(equal, &update_each);
__ j(equal, &update_each, Label::kNear);
// Convert the entry to a string or null if it isn't a property
// anymore. If the property has been removed while iterating, we
@ -1103,7 +1103,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
if (s != NULL && s->is_eval_scope()) {
// Loop up the context chain. There is no frame effect so it is
// safe to use raw labels here.
NearLabel next, fast;
Label next, fast;
if (!context.is(temp)) {
__ movq(temp, context);
}
@ -1112,7 +1112,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
__ bind(&next);
// Terminate at global context.
__ cmpq(kScratchRegister, FieldOperand(temp, HeapObject::kMapOffset));
__ j(equal, &fast);
__ j(equal, &fast, Label::kNear);
// Check that extension is NULL.
__ cmpq(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
__ j(not_equal, slow);
@ -1261,11 +1261,11 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
if (var->mode() == Variable::CONST) {
// Constants may be the hole value if they have not been initialized.
// Unhole them.
NearLabel done;
Label done;
MemOperand slot_operand = EmitSlotSearch(slot, rax);
__ movq(rax, slot_operand);
__ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
__ bind(&done);
context()->Plug(rax);
@ -1671,7 +1671,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
// Do combined smi check of the operands. Left operand is on the
// stack (popped into rdx). Right operand is in rax but moved into
// rcx to make the shifts easier.
NearLabel done, stub_call, smi_case;
NearLabel stub_call, smi_case;
Label done;
__ pop(rdx);
__ movq(rcx, rax);
__ or_(rax, rdx);
@ -1682,7 +1683,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ movq(rax, rcx);
TypeRecordingBinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site, expr->id());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&smi_case);
switch (op) {
@ -2197,8 +2198,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// function and receiver and have the slow path jump around this
// code.
if (done.is_linked()) {
NearLabel call;
__ jmp(&call);
Label call;
__ jmp(&call, Label::kNear);
__ bind(&done);
// Push function.
__ push(rax);
@ -2639,7 +2640,7 @@ void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
ASSERT(args->length() == 0);
NearLabel exit;
Label exit;
// Get the number of formal parameters.
__ Move(rax, Smi::FromInt(scope()->num_parameters()));
@ -2647,7 +2648,7 @@ void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
__ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
__ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset),
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(not_equal, &exit);
__ j(not_equal, &exit, Label::kNear);
// Arguments adaptor case: Read the arguments length from the
// adaptor frame.
@ -3183,7 +3184,7 @@ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
__ movq(cache,
FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
NearLabel done, not_found;
Label done, not_found;
// tmp now holds finger offset as a smi.
ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
__ movq(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset));
@ -3193,12 +3194,12 @@ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
index.reg,
index.scale,
FixedArray::kHeaderSize));
__ j(not_equal, &not_found);
__ j(not_equal, &not_found, Label::kNear);
__ movq(rax, FieldOperand(cache,
index.reg,
index.scale,
FixedArray::kHeaderSize + kPointerSize));
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&not_found);
// Call runtime to perform the lookup.
@ -3222,25 +3223,25 @@ void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
VisitForAccumulatorValue(args->at(1));
__ pop(left);
NearLabel done, fail, ok;
Label done, fail, ok;
__ cmpq(left, right);
__ j(equal, &ok);
__ j(equal, &ok, Label::kNear);
// Fail if either is a non-HeapObject.
Condition either_smi = masm()->CheckEitherSmi(left, right, tmp);
__ j(either_smi, &fail);
__ j(zero, &fail);
__ j(either_smi, &fail, Label::kNear);
__ j(zero, &fail, Label::kNear);
__ movq(tmp, FieldOperand(left, HeapObject::kMapOffset));
__ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset),
Immediate(JS_REGEXP_TYPE));
__ j(not_equal, &fail);
__ j(not_equal, &fail, Label::kNear);
__ cmpq(tmp, FieldOperand(right, HeapObject::kMapOffset));
__ j(not_equal, &fail);
__ j(not_equal, &fail, Label::kNear);
__ movq(tmp, FieldOperand(left, JSRegExp::kDataOffset));
__ cmpq(tmp, FieldOperand(right, JSRegExp::kDataOffset));
__ j(equal, &ok);
__ j(equal, &ok, Label::kNear);
__ bind(&fail);
__ Move(rax, isolate()->factory()->false_value());
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&ok);
__ Move(rax, isolate()->factory()->true_value());
__ bind(&done);
@ -3808,10 +3809,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
// Call ToNumber only if operand is not a smi.
NearLabel no_conversion;
Label no_conversion;
Condition is_smi;
is_smi = masm_->CheckSmi(rax);
__ j(is_smi, &no_conversion);
__ j(is_smi, &no_conversion, Label::kNear);
ToNumberStub convert_stub;
__ CallStub(&convert_stub);
__ bind(&no_conversion);
@ -3837,7 +3838,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
// Inline smi case if we are in a loop.
NearLabel stub_call, done;
NearLabel done;
Label stub_call;
JumpPatchSite patch_site(masm_);
if (ShouldInlineSmiCase(expr->op())) {
@ -3846,7 +3848,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
} else {
__ SmiSubConstant(rax, rax, Smi::FromInt(1));
}
__ j(overflow, &stub_call);
__ j(overflow, &stub_call, Label::kNear);
// We could eliminate this smi check if we split the code at
// the first smi check before calling ToNumber.
patch_site.EmitJumpIfSmi(rax, &done);

View File

@ -785,21 +785,21 @@ void LCodeGen::DoModI(LModI* instr) {
if (divisor < 0) divisor = -divisor;
NearLabel positive_dividend, done;
Label positive_dividend, done;
__ testl(dividend, dividend);
__ j(not_sign, &positive_dividend);
__ j(not_sign, &positive_dividend, Label::kNear);
__ negl(dividend);
__ andl(dividend, Immediate(divisor - 1));
__ negl(dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
DeoptimizeIf(no_condition, instr->environment());
}
__ bind(&positive_dividend);
__ andl(dividend, Immediate(divisor - 1));
__ bind(&done);
} else {
NearLabel done, remainder_eq_dividend, slow, do_subtraction, both_positive;
Label done, remainder_eq_dividend, slow, do_subtraction, both_positive;
Register left_reg = ToRegister(instr->InputAt(0));
Register right_reg = ToRegister(instr->InputAt(1));
Register result_reg = ToRegister(instr->result());
@ -816,11 +816,11 @@ void LCodeGen::DoModI(LModI* instr) {
}
__ testl(left_reg, left_reg);
__ j(zero, &remainder_eq_dividend);
__ j(sign, &slow);
__ j(zero, &remainder_eq_dividend, Label::kNear);
__ j(sign, &slow, Label::kNear);
__ testl(right_reg, right_reg);
__ j(not_sign, &both_positive);
__ j(not_sign, &both_positive, Label::kNear);
// The sign of the divisor doesn't matter.
__ neg(right_reg);
@ -828,16 +828,16 @@ void LCodeGen::DoModI(LModI* instr) {
// If the dividend is smaller than the nonnegative
// divisor, the dividend is the result.
__ cmpl(left_reg, right_reg);
__ j(less, &remainder_eq_dividend);
__ j(less, &remainder_eq_dividend, Label::kNear);
// Check if the divisor is a PowerOfTwo integer.
Register scratch = ToRegister(instr->TempAt(0));
__ movl(scratch, right_reg);
__ subl(scratch, Immediate(1));
__ testl(scratch, right_reg);
__ j(not_zero, &do_subtraction);
__ j(not_zero, &do_subtraction, Label::kNear);
__ andl(left_reg, scratch);
__ jmp(&remainder_eq_dividend);
__ jmp(&remainder_eq_dividend, Label::kNear);
__ bind(&do_subtraction);
const int kUnfolds = 3;
@ -848,7 +848,7 @@ void LCodeGen::DoModI(LModI* instr) {
__ subl(left_reg, right_reg);
// Check if the dividend is less than the divisor.
__ cmpl(left_reg, right_reg);
__ j(less, &remainder_eq_dividend);
__ j(less, &remainder_eq_dividend, Label::kNear);
}
__ movl(left_reg, scratch);
@ -860,15 +860,15 @@ void LCodeGen::DoModI(LModI* instr) {
// Check for (0 % -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
NearLabel positive_left;
NearLabel done;
Label positive_left;
Label done;
__ testl(left_reg, left_reg);
__ j(not_sign, &positive_left);
__ j(not_sign, &positive_left, Label::kNear);
__ idivl(right_reg);
// Test the remainder for 0, because then the result would be -0.
__ testl(result_reg, result_reg);
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
DeoptimizeIf(no_condition, instr->environment());
__ bind(&positive_left);
@ -877,7 +877,7 @@ void LCodeGen::DoModI(LModI* instr) {
} else {
__ idivl(right_reg);
}
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&remainder_eq_dividend);
__ movl(result_reg, left_reg);
@ -905,9 +905,9 @@ void LCodeGen::DoDivI(LDivI* instr) {
// Check for (0 / -x) that will produce negative zero.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
NearLabel left_not_zero;
Label left_not_zero;
__ testl(left_reg, left_reg);
__ j(not_zero, &left_not_zero);
__ j(not_zero, &left_not_zero, Label::kNear);
__ testl(right_reg, right_reg);
DeoptimizeIf(sign, instr->environment());
__ bind(&left_not_zero);
@ -915,9 +915,9 @@ void LCodeGen::DoDivI(LDivI* instr) {
// Check for (-kMinInt / -1).
if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
NearLabel left_not_min_int;
Label left_not_min_int;
__ cmpl(left_reg, Immediate(kMinInt));
__ j(not_zero, &left_not_min_int);
__ j(not_zero, &left_not_min_int, Label::kNear);
__ cmpl(right_reg, Immediate(-1));
DeoptimizeIf(zero, instr->environment());
__ bind(&left_not_min_int);
@ -996,9 +996,9 @@ void LCodeGen::DoMulI(LMulI* instr) {
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Bail out if the result is supposed to be negative zero.
NearLabel done;
Label done;
__ testl(left, left);
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
if (right->IsConstantOperand()) {
if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
DeoptimizeIf(no_condition, instr->environment());
@ -1367,10 +1367,10 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ JumpIfSmi(reg, true_label);
// Test for double values. Plus/minus zero and NaN are false.
NearLabel call_stub;
Label call_stub;
__ CompareRoot(FieldOperand(reg, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &call_stub);
__ j(not_equal, &call_stub, Label::kNear);
// HeapNumber => false iff +0, -0, or NaN. These three cases set the
// zero flag when compared to zero using ucomisd.
@ -1484,20 +1484,20 @@ void LCodeGen::DoCmpID(LCmpID* instr) {
LOperand* right = instr->InputAt(1);
LOperand* result = instr->result();
NearLabel unordered;
Label unordered;
if (instr->is_double()) {
// Don't base result on EFLAGS when a NaN is involved. Instead
// jump to the unordered case, which produces a false value.
__ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
__ j(parity_even, &unordered);
__ j(parity_even, &unordered, Label::kNear);
} else {
EmitCmpI(left, right);
}
NearLabel done;
Label done;
Condition cc = TokenToCondition(instr->op(), instr->is_double());
__ LoadRoot(ToRegister(result), Heap::kTrueValueRootIndex);
__ j(cc, &done);
__ j(cc, &done, Label::kNear);
__ bind(&unordered);
__ LoadRoot(ToRegister(result), Heap::kFalseValueRootIndex);
@ -1530,11 +1530,11 @@ void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
Register right = ToRegister(instr->InputAt(1));
Register result = ToRegister(instr->result());
NearLabel different, done;
Label different, done;
__ cmpq(left, right);
__ j(not_equal, &different);
__ j(not_equal, &different, Label::kNear);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&different);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
__ bind(&done);
@ -1568,16 +1568,17 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
if (instr->is_strict()) {
ASSERT(Heap::kTrueValueRootIndex >= 0);
__ movl(result, Immediate(Heap::kTrueValueRootIndex));
NearLabel load;
__ j(equal, &load);
Label load;
__ j(equal, &load, Label::kNear);
__ Set(result, Heap::kFalseValueRootIndex);
__ bind(&load);
__ LoadRootIndexed(result, result, 0);
} else {
NearLabel true_value, false_value, done;
__ j(equal, &true_value);
NearLabel false_value;
Label true_value, done;
__ j(equal, &true_value, Label::kNear);
__ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
__ j(equal, &true_value);
__ j(equal, &true_value, Label::kNear);
__ JumpIfSmi(reg, &false_value);
// Check for undetectable objects by looking in the bit field in
// the map. The object has already been smi checked.
@ -1585,10 +1586,10 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
__ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
__ testb(FieldOperand(scratch, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, &true_value);
__ j(not_zero, &true_value, Label::kNear);
__ bind(&false_value);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_value);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
__ bind(&done);
@ -1749,12 +1750,13 @@ void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
ASSERT(instr->hydrogen()->value()->representation().IsTagged());
__ testl(input, Immediate(kSmiTagMask));
NearLabel done, is_false;
Label done, is_false;
__ j(zero, &is_false);
__ CmpObjectType(input, TestType(instr->hydrogen()), result);
__ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
__ j(NegateCondition(BranchCondition(instr->hydrogen())),
&is_false, Label::kNear);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&is_false);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
__ bind(&done);
@ -1798,8 +1800,8 @@ void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
__ LoadRoot(result, Heap::kTrueValueRootIndex);
__ testl(FieldOperand(input, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask));
NearLabel done;
__ j(zero, &done);
Label done;
__ j(zero, &done, Label::kNear);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
__ bind(&done);
}
@ -1878,7 +1880,7 @@ void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
ASSERT(input.is(result));
Register temp = ToRegister(instr->TempAt(0));
Handle<String> class_name = instr->hydrogen()->class_name();
NearLabel done;
Label done;
Label is_true, is_false;
EmitClassOfTest(&is_true, &is_false, class_name, input, temp);
@ -1887,7 +1889,7 @@ void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
__ bind(&is_true);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&is_false);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
@ -1927,11 +1929,11 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
__ push(ToRegister(instr->InputAt(0)));
__ push(ToRegister(instr->InputAt(1)));
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
NearLabel true_value, done;
Label true_value, done;
__ testq(rax, rax);
__ j(zero, &true_value);
__ j(zero, &true_value, Label::kNear);
__ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_value);
__ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
__ bind(&done);
@ -1981,7 +1983,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// This is the inlined call site instanceof cache. The two occurences of the
// hole value will be patched to the last map/result pair generated by the
// instanceof stub.
NearLabel cache_miss;
Label cache_miss;
// Use a temp register to avoid memory operands with variable lengths.
Register map = ToRegister(instr->TempAt(0));
__ movq(map, FieldOperand(object, HeapObject::kMapOffset));
@ -1989,7 +1991,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
__ movq(kScratchRegister, factory()->the_hole_value(),
RelocInfo::EMBEDDED_OBJECT);
__ cmpq(map, kScratchRegister); // Patched to cached map.
__ j(not_equal, &cache_miss);
__ j(not_equal, &cache_miss, Label::kNear);
// Patched to load either true or false.
__ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
#ifdef DEBUG
@ -2004,7 +2006,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
// before calling the deferred code.
__ bind(&cache_miss); // Null is not an instance of anything.
__ CompareRoot(object, Heap::kNullValueRootIndex);
__ j(equal, &false_result);
__ j(equal, &false_result, Label::kNear);
// String values are not instances of anything.
__ JumpIfNotString(object, kScratchRegister, deferred->entry());
@ -2071,11 +2073,11 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
if (op == Token::GT || op == Token::LTE) {
condition = ReverseCondition(condition);
}
NearLabel true_value, done;
Label true_value, done;
__ testq(rax, rax);
__ j(condition, &true_value);
__ j(condition, &true_value, Label::kNear);
__ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_value);
__ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
__ bind(&done);
@ -2248,23 +2250,23 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else {
NearLabel done;
Label done;
for (int i = 0; i < map_count - 1; ++i) {
Handle<Map> map = instr->hydrogen()->types()->at(i);
NearLabel next;
Label next;
__ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
__ j(not_equal, &next);
__ j(not_equal, &next, Label::kNear);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&next);
}
Handle<Map> map = instr->hydrogen()->types()->last();
__ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
if (instr->hydrogen()->need_generic()) {
NearLabel generic;
__ j(not_equal, &generic);
Label generic;
__ j(not_equal, &generic, Label::kNear);
EmitLoadFieldOrConstantFunction(result, object, map, name);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&generic);
__ Move(rcx, instr->hydrogen()->name());
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
@ -2297,10 +2299,10 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
DeoptimizeIf(not_equal, instr->environment());
// Check whether the function has an instance prototype.
NearLabel non_instance;
Label non_instance;
__ testb(FieldOperand(result, Map::kBitFieldOffset),
Immediate(1 << Map::kHasNonInstancePrototype));
__ j(not_zero, &non_instance);
__ j(not_zero, &non_instance, Label::kNear);
// Get the prototype or initial map from the function.
__ movq(result,
@ -2311,13 +2313,13 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
DeoptimizeIf(equal, instr->environment());
// If the function does not have an initial map, we're done.
NearLabel done;
Label done;
__ CmpObjectType(result, MAP_TYPE, kScratchRegister);
__ j(not_equal, &done);
__ j(not_equal, &done, Label::kNear);
// Get the prototype from the initial map.
__ movq(result, FieldOperand(result, Map::kPrototypeOffset));
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Non-instance prototype: Fetch prototype from constructor field
// in the function's map.
@ -2334,13 +2336,13 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
Register input = ToRegister(instr->InputAt(0));
__ movq(result, FieldOperand(input, JSObject::kElementsOffset));
if (FLAG_debug_code) {
NearLabel done;
Label done;
__ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
Heap::kFixedArrayMapRootIndex);
__ j(equal, &done);
__ j(equal, &done, Label::kNear);
__ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
Heap::kFixedCOWArrayMapRootIndex);
__ j(equal, &done);
__ j(equal, &done, Label::kNear);
Register temp((result.is(rax)) ? rbx : rax);
__ push(temp);
__ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
@ -2462,15 +2464,15 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
Register result = ToRegister(instr->result());
// Check for arguments adapter frame.
NearLabel done, adapted;
Label done, adapted;
__ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
__ Cmp(Operand(result, StandardFrameConstants::kContextOffset),
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(equal, &adapted);
__ j(equal, &adapted, Label::kNear);
// No arguments adaptor frame.
__ movq(result, rbp);
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Arguments adaptor frame present.
__ bind(&adapted);
@ -2485,7 +2487,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
Register result = ToRegister(instr->result());
NearLabel done;
Label done;
// If no arguments adaptor frame the number of arguments is fixed.
if (instr->InputAt(0)->IsRegister()) {
@ -2494,7 +2496,7 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
__ cmpq(rbp, ToOperand(instr->InputAt(0)));
}
__ movl(result, Immediate(scope()->num_parameters()));
__ j(equal, &done);
__ j(equal, &done, Label::kNear);
// Arguments adaptor frame present. Get argument length from there.
__ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
@ -2518,18 +2520,18 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
// If the receiver is null or undefined, we have to pass the global object
// as a receiver.
NearLabel global_object, receiver_ok;
Label global_object, receiver_ok;
__ CompareRoot(receiver, Heap::kNullValueRootIndex);
__ j(equal, &global_object);
__ j(equal, &global_object, Label::kNear);
__ CompareRoot(receiver, Heap::kUndefinedValueRootIndex);
__ j(equal, &global_object);
__ j(equal, &global_object, Label::kNear);
// The receiver should be a JS object.
Condition is_smi = __ CheckSmi(receiver);
DeoptimizeIf(is_smi, instr->environment());
__ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, kScratchRegister);
DeoptimizeIf(below, instr->environment());
__ jmp(&receiver_ok);
__ jmp(&receiver_ok, Label::kNear);
__ bind(&global_object);
// TODO(kmillikin): We have a hydrogen value for the global object. See
@ -2550,10 +2552,10 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
// Loop through the arguments pushing them onto the execution
// stack.
NearLabel invoke, loop;
Label invoke, loop;
// length is a small non-negative integer, due to the test above.
__ testl(length, length);
__ j(zero, &invoke);
__ j(zero, &invoke, Label::kNear);
__ bind(&loop);
__ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
__ decl(length);
@ -2800,9 +2802,10 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
// xmm_scratch = 0.5
__ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE);
__ movq(xmm_scratch, kScratchRegister);
NearLabel below_half;
Label below_half;
__ ucomisd(xmm_scratch, input_reg);
__ j(above, &below_half); // If input_reg is NaN, this doesn't jump.
// If input_reg is NaN, this doesn't jump.
__ j(above, &below_half, Label::kNear);
// input = input + 0.5
// This addition might give a result that isn't the correct for
// rounding, due to loss of precision, but only for a number that's
@ -3109,9 +3112,9 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
switch (array_type) {
case kExternalPixelArray:
{ // Clamp the value to [0..255].
NearLabel done;
Label done;
__ testl(value, Immediate(0xFFFFFF00));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
__ setcc(negative, value); // 1 if negative, 0 if positive.
__ decb(value); // 0 if negative, 255 if positive.
__ bind(&done);
@ -3234,7 +3237,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
DeferredStringCharCodeAt* deferred =
new DeferredStringCharCodeAt(this, instr);
NearLabel flat_string, ascii_string, done;
Label flat_string, ascii_string, done;
// Fetch the instance type of the receiver into result register.
__ movq(result, FieldOperand(string, HeapObject::kMapOffset));
@ -3243,7 +3246,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
// We need special handling for non-sequential strings.
STATIC_ASSERT(kSeqStringTag == 0);
__ testb(result, Immediate(kStringRepresentationMask));
__ j(zero, &flat_string);
__ j(zero, &flat_string, Label::kNear);
// Handle cons strings and go to deferred code for the rest.
__ testb(result, Immediate(kIsConsStringMask));
@ -3270,7 +3273,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
__ bind(&flat_string);
STATIC_ASSERT(kAsciiStringTag != 0);
__ testb(result, Immediate(kStringEncodingMask));
__ j(not_zero, &ascii_string);
__ j(not_zero, &ascii_string, Label::kNear);
// Two-byte string.
// Load the two-byte character code into the result register.
@ -3286,7 +3289,7 @@ void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
times_2,
SeqTwoByteString::kHeaderSize));
}
__ jmp(&done);
__ jmp(&done, Label::kNear);
// ASCII string.
// Load the byte into the result register.
@ -3476,7 +3479,8 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
void LCodeGen::EmitNumberUntagD(Register input_reg,
XMMRegister result_reg,
LEnvironment* env) {
NearLabel load_smi, heap_number, done;
NearLabel load_smi;
Label heap_number, done;
// Smi check.
__ JumpIfSmi(input_reg, &load_smi);
@ -3484,7 +3488,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
// Heap number map check.
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
__ j(equal, &heap_number);
__ j(equal, &heap_number, Label::kNear);
__ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
DeoptimizeIf(not_equal, env);
@ -3492,12 +3496,12 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
// Convert undefined to NaN. Compute NaN as 0/0.
__ xorps(result_reg, result_reg);
__ divsd(result_reg, result_reg);
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Heap number to XMM conversion.
__ bind(&heap_number);
__ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ jmp(&done);
__ jmp(&done, Label::kNear);
// Smi to XMM conversion
__ bind(&load_smi);
@ -3518,7 +3522,7 @@ class DeferredTaggedToI: public LDeferredCode {
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
NearLabel done, heap_number;
Label done, heap_number;
Register input_reg = ToRegister(instr->InputAt(0));
// Heap number map check.
@ -3526,13 +3530,13 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
Heap::kHeapNumberMapRootIndex);
if (instr->truncating()) {
__ j(equal, &heap_number);
__ j(equal, &heap_number, Label::kNear);
// Check for undefined. Undefined is converted to zero for truncating
// conversions.
__ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
DeoptimizeIf(not_equal, instr->environment());
__ Set(input_reg, 0);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&heap_number);
@ -3613,11 +3617,11 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
DeoptimizeIf(not_equal, instr->environment());
DeoptimizeIf(parity_even, instr->environment()); // NaN.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
NearLabel done;
Label done;
// The integer converted back is equal to the original. We
// only have to test if we got -0 as an input.
__ testl(result_reg, result_reg);
__ j(not_zero, &done);
__ j(not_zero, &done, Label::kNear);
__ movmskpd(result_reg, input_reg);
// Bit 0 contains the sign of the double in input_reg.
// If input was positive, we are ok and return 0, otherwise
@ -3785,7 +3789,7 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
NearLabel materialized;
Label materialized;
// Registers will be used as follows:
// rdi = JS function.
// rcx = literals array.
@ -3797,7 +3801,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
instr->hydrogen()->literal_index() * kPointerSize;
__ movq(rbx, FieldOperand(rcx, literal_offset));
__ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, &materialized);
__ j(not_equal, &materialized, Label::kNear);
// Create regexp literal using runtime function
// Result will be in rax.
@ -3869,7 +3873,7 @@ void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
Register result = ToRegister(instr->result());
Label true_label;
Label false_label;
NearLabel done;
Label done;
Condition final_branch_condition = EmitTypeofIs(&true_label,
&false_label,
@ -3878,7 +3882,7 @@ void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
__ j(final_branch_condition, &true_label);
__ bind(&false_label);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_label);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
@ -3980,15 +3984,14 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
Register result = ToRegister(instr->result());
NearLabel true_label;
NearLabel false_label;
NearLabel done;
Label true_label;
Label done;
EmitIsConstructCall(result);
__ j(equal, &true_label);
__ j(equal, &true_label, Label::kNear);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
__ jmp(&done);
__ jmp(&done, Label::kNear);
__ bind(&true_label);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
@ -4013,10 +4016,10 @@ void LCodeGen::EmitIsConstructCall(Register temp) {
__ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
// Skip the arguments adaptor frame if it exists.
NearLabel check_frame_marker;
Label check_frame_marker;
__ Cmp(Operand(temp, StandardFrameConstants::kContextOffset),
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(not_equal, &check_frame_marker);
__ j(not_equal, &check_frame_marker, Label::kNear);
__ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
// Check the marker in the calling frame.
@ -4080,9 +4083,9 @@ void LCodeGen::DoIn(LIn* instr) {
void LCodeGen::DoStackCheck(LStackCheck* instr) {
// Perform stack overflow check.
NearLabel done;
Label done;
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
__ j(above_equal, &done);
__ j(above_equal, &done, Label::kNear);
StackCheckStub stub;
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);

View File

@ -344,13 +344,13 @@ void MacroAssembler::Assert(Condition cc, const char* msg) {
void MacroAssembler::AssertFastElements(Register elements) {
if (emit_debug_code()) {
NearLabel ok;
Label ok;
CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
Heap::kFixedArrayMapRootIndex);
j(equal, &ok);
j(equal, &ok, Label::kNear);
CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
Heap::kFixedCOWArrayMapRootIndex);
j(equal, &ok);
j(equal, &ok, Label::kNear);
Abort("JSObject with fast elements map has slow elements");
bind(&ok);
}
@ -358,8 +358,8 @@ void MacroAssembler::AssertFastElements(Register elements) {
void MacroAssembler::Check(Condition cc, const char* msg) {
NearLabel L;
j(cc, &L);
Label L;
j(cc, &L, Label::kNear);
Abort(msg);
// will not return here
bind(&L);
@ -371,9 +371,9 @@ void MacroAssembler::CheckStackAlignment() {
int frame_alignment_mask = frame_alignment - 1;
if (frame_alignment > kPointerSize) {
ASSERT(IsPowerOf2(frame_alignment));
NearLabel alignment_as_expected;
Label alignment_as_expected;
testq(rsp, Immediate(frame_alignment_mask));
j(zero, &alignment_as_expected);
j(zero, &alignment_as_expected, Label::kNear);
// Abort if stack is not aligned.
int3();
bind(&alignment_as_expected);
@ -384,9 +384,9 @@ void MacroAssembler::CheckStackAlignment() {
void MacroAssembler::NegativeZeroTest(Register result,
Register op,
Label* then_label) {
NearLabel ok;
Label ok;
testl(result, result);
j(not_zero, &ok);
j(not_zero, &ok, Label::kNear);
testl(op, op);
j(sign, then_label);
bind(&ok);
@ -832,8 +832,8 @@ void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) {
if (allow_stub_calls()) {
Assert(equal, "Uninitialized kSmiConstantRegister");
} else {
NearLabel ok;
j(equal, &ok);
Label ok;
j(equal, &ok, Label::kNear);
int3();
bind(&ok);
}
@ -895,8 +895,8 @@ void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
if (emit_debug_code()) {
testb(dst, Immediate(0x01));
NearLabel ok;
j(zero, &ok);
Label ok;
j(zero, &ok, Label::kNear);
if (allow_stub_calls()) {
Abort("Integer32ToSmiField writing to non-smi location");
} else {
@ -1397,7 +1397,6 @@ void MacroAssembler::SmiShiftLeft(Register dst,
Register src1,
Register src2) {
ASSERT(!dst.is(rcx));
NearLabel result_ok;
// Untag shift amount.
if (!dst.is(src1)) {
movq(dst, src1);
@ -1782,9 +1781,9 @@ void MacroAssembler::Throw(Register value) {
// Before returning we restore the context from the frame pointer if not NULL.
// The frame pointer is NULL in the exception handler of a JS entry frame.
Set(rsi, 0); // Tentatively set context pointer to NULL
NearLabel skip;
Label skip;
cmpq(rbp, Immediate(0));
j(equal, &skip);
j(equal, &skip, Label::kNear);
movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
bind(&skip);
ret(0);
@ -1802,12 +1801,12 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
Load(rsp, handler_address);
// Unwind the handlers until the ENTRY handler is found.
NearLabel loop, done;
Label loop, done;
bind(&loop);
// Load the type of the current stack handler.
const int kStateOffset = StackHandlerConstants::kStateOffset;
cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY));
j(equal, &done);
j(equal, &done, Label::kNear);
// Fetch the next handler in the list.
const int kNextOffset = StackHandlerConstants::kNextOffset;
movq(rsp, Operand(rsp, kNextOffset));
@ -1899,9 +1898,9 @@ void MacroAssembler::CheckMap(Register obj,
void MacroAssembler::AbortIfNotNumber(Register object) {
NearLabel ok;
Label ok;
Condition is_smi = CheckSmi(object);
j(is_smi, &ok);
j(is_smi, &ok, Label::kNear);
Cmp(FieldOperand(object, HeapObject::kMapOffset),
isolate()->factory()->heap_number_map());
Assert(equal, "Operand not a number");
@ -1910,7 +1909,6 @@ void MacroAssembler::AbortIfNotNumber(Register object) {
void MacroAssembler::AbortIfSmi(Register object) {
NearLabel ok;
Condition is_smi = CheckSmi(object);
Assert(NegateCondition(is_smi), "Operand is a smi");
}
@ -1973,10 +1971,10 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
j(not_equal, miss);
// Make sure that the function has an instance prototype.
NearLabel non_instance;
Label non_instance;
testb(FieldOperand(result, Map::kBitFieldOffset),
Immediate(1 << Map::kHasNonInstancePrototype));
j(not_zero, &non_instance);
j(not_zero, &non_instance, Label::kNear);
// Get the prototype or initial map from the function.
movq(result,
@ -1989,13 +1987,13 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
j(equal, miss);
// If the function does not have an initial map, we're done.
NearLabel done;
Label done;
CmpObjectType(result, MAP_TYPE, kScratchRegister);
j(not_equal, &done);
j(not_equal, &done, Label::kNear);
// Get the prototype from the initial map.
movq(result, FieldOperand(result, Map::kPrototypeOffset));
jmp(&done);
jmp(&done, Label::kNear);
// Non-instance prototype: Fetch prototype from constructor field
// in initial map.

View File

@ -1369,21 +1369,22 @@ void MacroAssembler::SmiMul(Register dst,
ASSERT(!src2.is(kScratchRegister));
if (dst.is(src1)) {
NearLabel failure, zero_correct_result;
Label failure, zero_correct_result;
movq(kScratchRegister, src1); // Create backup for later testing.
SmiToInteger64(dst, src1);
imul(dst, src2);
j(overflow, &failure);
j(overflow, &failure, Label::kNear);
// Check for negative zero result. If product is zero, and one
// argument is negative, go to slow case.
NearLabel correct_result;
Label correct_result;
testq(dst, dst);
j(not_zero, &correct_result);
j(not_zero, &correct_result, Label::kNear);
movq(dst, kScratchRegister);
xor_(dst, src2);
j(positive, &zero_correct_result); // Result was positive zero.
// Result was positive zero.
j(positive, &zero_correct_result, Label::kNear);
bind(&failure); // Reused failure exit, restores src1.
movq(src1, kScratchRegister);
@ -1399,9 +1400,9 @@ void MacroAssembler::SmiMul(Register dst,
j(overflow, on_not_smi_result);
// Check for negative zero result. If product is zero, and one
// argument is negative, go to slow case.
NearLabel correct_result;
Label correct_result;
testq(dst, dst);
j(not_zero, &correct_result);
j(not_zero, &correct_result, Label::kNear);
// One of src1 and src2 is zero, the check whether the other is
// negative.
movq(kScratchRegister, src1);
@ -1516,7 +1517,6 @@ void MacroAssembler::SmiDiv(Register dst,
ASSERT(!src1.is(rdx));
// Check for 0 divisor (result is +/-Infinity).
NearLabel positive_divisor;
testq(src2, src2);
j(zero, on_not_smi_result);
@ -1531,12 +1531,12 @@ void MacroAssembler::SmiDiv(Register dst,
// We overshoot a little and go to slow case if we divide min-value
// by any negative value, not just -1.
NearLabel safe_div;
Label safe_div;
testl(rax, Immediate(0x7fffffff));
j(not_zero, &safe_div);
j(not_zero, &safe_div, Label::kNear);
testq(src2, src2);
if (src1.is(rax)) {
j(positive, &safe_div);
j(positive, &safe_div, Label::kNear);
movq(src1, kScratchRegister);
jmp(on_not_smi_result);
} else {
@ -1552,8 +1552,8 @@ void MacroAssembler::SmiDiv(Register dst,
// Check that the remainder is zero.
testl(rdx, rdx);
if (src1.is(rax)) {
NearLabel smi_result;
j(zero, &smi_result);
Label smi_result;
j(zero, &smi_result, Label::kNear);
movq(src1, kScratchRegister);
jmp(on_not_smi_result);
bind(&smi_result);
@ -1590,11 +1590,11 @@ void MacroAssembler::SmiMod(Register dst,
SmiToInteger32(src2, src2);
// Test for the edge case of dividing Smi::kMinValue by -1 (will overflow).
NearLabel safe_div;
Label safe_div;
cmpl(rax, Immediate(Smi::kMinValue));
j(not_equal, &safe_div);
j(not_equal, &safe_div, Label::kNear);
cmpl(src2, Immediate(-1));
j(not_equal, &safe_div);
j(not_equal, &safe_div, Label::kNear);
// Retag inputs and go slow case.
Integer32ToSmi(src2, src2);
if (src1.is(rax)) {
@ -1613,9 +1613,9 @@ void MacroAssembler::SmiMod(Register dst,
}
// Check for a negative zero result. If the result is zero, and the
// dividend is negative, go slow to return a floating point negative zero.
NearLabel smi_result;
Label smi_result;
testl(rdx, rdx);
j(not_zero, &smi_result);
j(not_zero, &smi_result, Label::kNear);
testq(src1, src1);
j(negative, on_not_smi_result);
bind(&smi_result);
@ -1652,7 +1652,6 @@ void MacroAssembler::SmiShiftLogicalRight(Register dst,
ASSERT(!dst.is(rcx));
// dst and src1 can be the same, because the one case that bails out
// is a shift by 0, which leaves dst, and therefore src1, unchanged.
NearLabel result_ok;
if (src1.is(rcx) || src2.is(rcx)) {
movq(kScratchRegister, rcx);
}
@ -1665,8 +1664,8 @@ void MacroAssembler::SmiShiftLogicalRight(Register dst,
shl(dst, Immediate(kSmiShift));
testq(dst, dst);
if (src1.is(rcx) || src2.is(rcx)) {
NearLabel positive_result;
j(positive, &positive_result);
Label positive_result;
j(positive, &positive_result, Label::kNear);
if (src1.is(rcx)) {
movq(src1, kScratchRegister);
} else {
@ -1938,7 +1937,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
InvokeFlag flag,
const CallWrapper& call_wrapper) {
bool definitely_matches = false;
NearLabel invoke;
Label invoke;
if (expected.is_immediate()) {
ASSERT(actual.is_immediate());
if (expected.immediate() == actual.immediate()) {
@ -1962,14 +1961,14 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
// case when we invoke function values without going through the
// IC mechanism.
cmpq(expected.reg(), Immediate(actual.immediate()));
j(equal, &invoke);
j(equal, &invoke, Label::kNear);
ASSERT(expected.reg().is(rbx));
Set(rax, actual.immediate());
} else if (!expected.reg().is(actual.reg())) {
// Both expected and actual are in (different) registers. This
// is the case when we invoke functions using call and apply.
cmpq(expected.reg(), actual.reg());
j(equal, &invoke);
j(equal, &invoke, Label::kNear);
ASSERT(actual.reg().is(rax));
ASSERT(expected.reg().is(rbx));
}

View File

@ -1065,9 +1065,9 @@ void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) {
void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) {
NearLabel after_position;
Label after_position;
__ cmpq(rdi, Immediate(-by * char_size()));
__ j(greater_equal, &after_position);
__ j(greater_equal, &after_position, Label::kNear);
__ movq(rdi, Immediate(-by * char_size()));
// On RegExp code entry (where this operation is used), the character before
// the current position is expected to be already loaded.

View File

@ -3300,9 +3300,9 @@ MaybeObject* ExternalArrayStubCompiler::CompileKeyedStoreStub(
switch (array_type) {
case kExternalPixelArray:
{ // Clamp the value to [0..255].
NearLabel done;
Label done;
__ testl(rdx, Immediate(0xFFFFFF00));
__ j(zero, &done);
__ j(zero, &done, Label::kNear);
__ setcc(negative, rdx); // 1 if negative, 0 if positive.
__ decb(rdx); // 0 if negative, 255 if positive.
__ bind(&done);