Index: src/ia32/assembler-ia32.cc |
=================================================================== |
--- src/ia32/assembler-ia32.cc (revision 5449) |
+++ src/ia32/assembler-ia32.cc (working copy) |
@@ -1511,40 +1511,27 @@ |
} |
-void Assembler::link_to(Label* L, Label* appendix) { |
+void Assembler::bind(Label* L) { |
EnsureSpace ensure_space(this); |
last_pc_ = NULL; |
- if (appendix->is_linked()) { |
- if (L->is_linked()) { |
- // Append appendix to L's list. |
- Label p; |
- Label q = *L; |
- do { |
- p = q; |
- Displacement disp = disp_at(&q); |
- disp.next(&q); |
- } while (q.is_linked()); |
- Displacement disp = disp_at(&p); |
- disp.link_to(appendix); |
- disp_at_put(&p, disp); |
- p.Unuse(); // to avoid assertion failure in ~Label |
- } else { |
- // L is empty, simply use appendix. |
- *L = *appendix; |
- } |
- } |
- appendix->Unuse(); // appendix should not be used anymore |
+ ASSERT(!L->is_bound()); // label can only be bound once |
+ bind_to(L, pc_offset()); |
} |
-void Assembler::bind(Label* L) { |
- EnsureSpace ensure_space(this); |
+void Assembler::bind(NearLabel* L) { |
+ ASSERT(!L->is_bound()); |
last_pc_ = NULL; |
- ASSERT(!L->is_bound()); // label can only be bound once |
- bind_to(L, pc_offset()); |
+ while (L->unresolved_branches_ > 0) { |
+ int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1]; |
+ int disp = pc_offset() - branch_pos; |
+ ASSERT(is_int8(disp)); |
+ set_byte_at(branch_pos - sizeof(int8_t), disp); |
+ L->unresolved_branches_--; |
+ } |
+ L->bind_to(pc_offset()); |
} |
- |
void Assembler::call(Label* L) { |
EnsureSpace ensure_space(this); |
last_pc_ = pc_; |
@@ -1641,7 +1628,25 @@ |
} |
+void Assembler::jmp(NearLabel* L) { |
+ EnsureSpace ensure_space(this); |
+ last_pc_ = pc_; |
+ if (L->is_bound()) { |
+ const int short_size = 2; |
+ int offs = L->pos() - pc_offset(); |
+ ASSERT(offs <= 0); |
+ ASSERT(is_int8(offs - short_size)); |
+ // 1110 1011 #8-bit disp. |
+ EMIT(0xEB); |
+ EMIT((offs - short_size) & 0xFF); |
+ } else { |
+ EMIT(0xEB); |
+ EMIT(0x00); // The displacement will be resolved later. |
+ L->link_to(pc_offset()); |
+ } |
+} |
+ |
void Assembler::j(Condition cc, Label* L, Hint hint) { |
EnsureSpace ensure_space(this); |
last_pc_ = pc_; |
@@ -1696,6 +1701,27 @@ |
} |
+void Assembler::j(Condition cc, NearLabel* L, Hint hint) { |
+ EnsureSpace ensure_space(this); |
+ last_pc_ = pc_; |
+ ASSERT(0 <= cc && cc < 16); |
+ if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); |
+ if (L->is_bound()) { |
+ const int short_size = 2; |
+ int offs = L->pos() - pc_offset(); |
+ ASSERT(offs <= 0); |
+ ASSERT(is_int8(offs - short_size)); |
+ // 0111 tttn #8-bit disp |
+ EMIT(0x70 | cc); |
+ EMIT((offs - short_size) & 0xFF); |
+ } else { |
+ EMIT(0x70 | cc); |
+ EMIT(0x00); // The displacement will be resolved later. |
+ L->link_to(pc_offset()); |
+ } |
+} |
+ |
+ |
// FPU instructions. |
void Assembler::fld(int i) { |