OLD | NEW |
---|---|
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 } | 182 } |
183 | 183 |
184 void Assembler::RecordPosition(int a) { | 184 void Assembler::RecordPosition(int a) { |
185 UNIMPLEMENTED(); | 185 UNIMPLEMENTED(); |
186 } | 186 } |
187 | 187 |
188 void Assembler::RecordStatementPosition(int a) { | 188 void Assembler::RecordStatementPosition(int a) { |
189 UNIMPLEMENTED(); | 189 UNIMPLEMENTED(); |
190 } | 190 } |
191 | 191 |
192 void Assembler::bind(Label* a) { | 192 |
193 UNIMPLEMENTED(); | 193 void Assembler::bind_to(Label* L, int pos) { |
194 ASSERT(!L->is_bound()); // Label may only be bound once. | |
195 last_pc_ = NULL; | |
196 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. | |
197 if (L->is_linked()) { | |
198 int current = L->pos(); | |
199 int next = long_at(current); | |
200 while (next != current) { | |
201 // relative address, relative to point after address | |
202 int imm32 = pos - (current + sizeof(int32_t)); | |
203 long_at_put(current, imm32); | |
204 current = next; | |
205 next = long_at(next); | |
206 } | |
207 // Fix up last fixup on linked list. | |
208 int last_imm32 = pos - (current + sizeof(int32_t)); | |
209 long_at_put(current, last_imm32); | |
210 } | |
211 L->bind_to(pos); | |
194 } | 212 } |
195 | 213 |
214 | |
215 void Assembler::bind(Label* L) { | |
216 bind_to(L, pc_offset()); | |
217 } | |
218 | |
219 | |
196 void Assembler::GrowBuffer() { | 220 void Assembler::GrowBuffer() { |
197 ASSERT(overflow()); // should not call this otherwise | 221 ASSERT(overflow()); // should not call this otherwise |
198 if (!own_buffer_) FATAL("external code buffer is too small"); | 222 if (!own_buffer_) FATAL("external code buffer is too small"); |
199 | 223 |
200 // compute new buffer size | 224 // compute new buffer size |
201 CodeDesc desc; // the new buffer | 225 CodeDesc desc; // the new buffer |
202 if (buffer_size_ < 4*KB) { | 226 if (buffer_size_ < 4*KB) { |
203 desc.buffer_size = 4*KB; | 227 desc.buffer_size = 4*KB; |
204 } else { | 228 } else { |
205 desc.buffer_size = 2*buffer_size_; | 229 desc.buffer_size = 2*buffer_size_; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 | 292 |
269 // Emit updated ModRM byte containing the given register. | 293 // Emit updated ModRM byte containing the given register. |
270 pc_[0] = (adr.buf_[0] & ~0x38) | ((reg.code() && 0x7) << 3); | 294 pc_[0] = (adr.buf_[0] & ~0x38) | ((reg.code() && 0x7) << 3); |
271 | 295 |
272 // Emit the rest of the encoded operand. | 296 // Emit the rest of the encoded operand. |
273 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; | 297 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; |
274 pc_ += length; | 298 pc_ += length; |
275 } | 299 } |
276 | 300 |
277 | 301 |
302 // Assembler Instruction implementations | |
303 | |
278 void Assembler::add(Register dst, const Operand& src) { | 304 void Assembler::add(Register dst, const Operand& src) { |
279 EnsureSpace ensure_space(this); | 305 EnsureSpace ensure_space(this); |
280 last_pc_ = pc_; | 306 last_pc_ = pc_; |
281 emit_rex_64(dst, src); | 307 emit_rex_64(dst, src); |
282 EMIT(0x03); | 308 EMIT(0x03); |
283 emit_operand(dst, src); | 309 emit_operand(dst, src); |
284 } | 310 } |
285 | 311 |
286 | 312 |
287 void Assembler::add(Register dst, Register src) { | 313 void Assembler::add(Register dst, Register src) { |
288 EnsureSpace ensure_space(this); | 314 EnsureSpace ensure_space(this); |
289 last_pc_ = pc_; | 315 last_pc_ = pc_; |
290 emit_rex_64(dst, src); | 316 emit_rex_64(dst, src); |
291 EMIT(0x03); | 317 EMIT(0x03); |
292 EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7)); | 318 EMIT(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); |
Lasse Reichstein
2009/05/26 12:14:41
Was this incorrect before?
William Hesse
2009/05/26 15:15:32
Yes it was. Cases with two register operands shou
| |
319 } | |
320 | |
321 | |
322 void Assembler::call(Label* L) { | |
323 EnsureSpace ensure_space(this); | |
324 last_pc_ = pc_; | |
325 // 1110 1000 #32-bit disp | |
326 EMIT(0xE8); | |
327 if (L->is_bound()) { | |
328 int offset = L->pos() - pc_offset() - sizeof(int32_t); | |
329 ASSERT(offset <= 0); | |
330 emit(offset); | |
331 } else if (L->is_linked()) { | |
332 emit(L->pos()); | |
333 L->link_to(pc_offset() - sizeof(int32_t)); | |
334 } else { | |
335 ASSERT(L->is_unused()); | |
336 int32_t current = pc_offset(); | |
337 emit(current); | |
338 L->link_to(current); | |
339 } | |
293 } | 340 } |
294 | 341 |
295 | 342 |
296 void Assembler::dec(Register dst) { | 343 void Assembler::dec(Register dst) { |
297 EnsureSpace ensure_space(this); | 344 EnsureSpace ensure_space(this); |
298 last_pc_ = pc_; | 345 last_pc_ = pc_; |
299 emit_rex_64(rcx, dst); | 346 emit_rex_64(rcx, dst); |
300 EMIT(0xFF); | 347 EMIT(0xFF); |
301 EMIT(0xC8 | (dst.code() & 0x7)); | 348 EMIT(0xC8 | (dst.code() & 0x7)); |
302 } | 349 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 } | 383 } |
337 | 384 |
338 | 385 |
339 void Assembler::int3() { | 386 void Assembler::int3() { |
340 EnsureSpace ensure_space(this); | 387 EnsureSpace ensure_space(this); |
341 last_pc_ = pc_; | 388 last_pc_ = pc_; |
342 EMIT(0xCC); | 389 EMIT(0xCC); |
343 } | 390 } |
344 | 391 |
345 | 392 |
393 void Assembler::j(Condition cc, Label* L) { | |
394 EnsureSpace ensure_space(this); | |
395 last_pc_ = pc_; | |
396 ASSERT(0 <= cc && cc < 16); | |
397 if (L->is_bound()) { | |
398 const int short_size = 2; | |
399 const int long_size = 6; | |
400 int offs = L->pos() - pc_offset(); | |
401 ASSERT(offs <= 0); | |
402 if (is_int8(offs - short_size)) { | |
403 // 0111 tttn #8-bit disp | |
404 EMIT(0x70 | cc); | |
405 EMIT((offs - short_size) & 0xFF); | |
406 } else { | |
407 // 0000 1111 1000 tttn #32-bit disp | |
408 EMIT(0x0F); | |
409 EMIT(0x80 | cc); | |
410 emit(offs - long_size); | |
411 } | |
412 } else if (L->is_linked()) { | |
413 // 0000 1111 1000 tttn #32-bit disp | |
414 EMIT(0x0F); | |
415 EMIT(0x80 | cc); | |
416 emit(L->pos()); | |
417 L->link_to(pc_offset() - sizeof(int32_t)); | |
418 } else { | |
419 ASSERT(L->is_unused()); | |
420 EMIT(0x0F); | |
421 EMIT(0x80 | cc); | |
422 int32_t current = pc_offset(); | |
423 emit(current); | |
424 L->link_to(current); | |
425 } | |
426 } | |
427 | |
428 | |
429 void Assembler::jmp(Label* L) { | |
430 EnsureSpace ensure_space(this); | |
431 last_pc_ = pc_; | |
432 if (L->is_bound()) { | |
433 int offs = L->pos() - pc_offset() - 1; | |
434 ASSERT(offs <= 0); | |
435 if (is_int8(offs - sizeof(int8_t))) { | |
436 // 1110 1011 #8-bit disp | |
437 EMIT(0xEB); | |
438 EMIT((offs - sizeof(int8_t)) & 0xFF); | |
439 } else { | |
440 // 1110 1001 #32-bit disp | |
441 EMIT(0xE9); | |
442 emit(offs - sizeof(int32_t)); | |
443 } | |
444 } else if (L->is_linked()) { | |
445 // 1110 1001 #32-bit disp | |
446 EMIT(0xE9); | |
447 emit(L->pos()); | |
448 L->link_to(pc_offset() - sizeof(int32_t)); | |
449 } else { | |
450 // 1110 1001 #32-bit disp | |
451 ASSERT(L->is_unused()); | |
452 EMIT(0xE9); | |
453 int32_t current = pc_offset(); | |
454 emit(current); | |
455 L->link_to(current); | |
456 } | |
457 } | |
458 | |
459 | |
346 void Assembler::mov(Register dst, const Operand& src) { | 460 void Assembler::mov(Register dst, const Operand& src) { |
347 EnsureSpace ensure_space(this); | 461 EnsureSpace ensure_space(this); |
348 last_pc_ = pc_; | 462 last_pc_ = pc_; |
349 emit_rex_64(dst, src); | 463 emit_rex_64(dst, src); |
350 EMIT(0x8B); | 464 EMIT(0x8B); |
351 emit_operand(dst, src); | 465 emit_operand(dst, src); |
352 } | 466 } |
353 | 467 |
354 | 468 |
355 void Assembler::mov(Register dst, Register src) { | 469 void Assembler::mov(Register dst, Register src) { |
356 EnsureSpace ensure_space(this); | 470 EnsureSpace ensure_space(this); |
357 last_pc_ = pc_; | 471 last_pc_ = pc_; |
358 emit_rex_64(dst, src); | 472 emit_rex_64(dst, src); |
359 EMIT(0x89); | 473 EMIT(0x8B); |
360 EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7)); | 474 EMIT(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); |
361 } | 475 } |
362 | 476 |
363 | 477 |
364 void Assembler::nop() { | 478 void Assembler::nop() { |
365 EnsureSpace ensure_space(this); | 479 EnsureSpace ensure_space(this); |
366 last_pc_ = pc_; | 480 last_pc_ = pc_; |
367 EMIT(0x90); | 481 EMIT(0x90); |
368 } | 482 } |
369 | 483 |
370 void Assembler::pop(Register dst) { | 484 void Assembler::pop(Register dst) { |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
702 UNIMPLEMENTED(); | 816 UNIMPLEMENTED(); |
703 return NULL; | 817 return NULL; |
704 } | 818 } |
705 | 819 |
706 byte* JavaScriptFrame::GetCallerStackPointer() const { | 820 byte* JavaScriptFrame::GetCallerStackPointer() const { |
707 UNIMPLEMENTED(); | 821 UNIMPLEMENTED(); |
708 return NULL; | 822 return NULL; |
709 } | 823 } |
710 | 824 |
711 } } // namespace v8::internal | 825 } } // namespace v8::internal |
OLD | NEW |