Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: src/x64/assembler-x64.cc

Issue 115857: Add more arithmetic to x64 assembler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 uint64_t CpuFeatures::supported_ = 0; 75 uint64_t CpuFeatures::supported_ = 0;
76 uint64_t CpuFeatures::enabled_ = 0; 76 uint64_t CpuFeatures::enabled_ = 0;
77 77
78 void CpuFeatures::Probe() { 78 void CpuFeatures::Probe() {
79 // TODO(X64): UNIMPLEMENTED 79 // TODO(X64): UNIMPLEMENTED
80 } 80 }
81 81
82 // ----------------------------------------------------------------------------- 82 // -----------------------------------------------------------------------------
83 // Implementation of Assembler 83 // Implementation of Assembler
84 84
85 // Emit a single byte. Must always be inlined.
86 #define EMIT(x) \
87 *pc_++ = (x)
88
89 #ifdef GENERATED_CODE_COVERAGE 85 #ifdef GENERATED_CODE_COVERAGE
90 static void InitCoverageLog(); 86 static void InitCoverageLog();
91 #endif 87 #endif
92 88
93 byte* Assembler::spare_buffer_ = NULL; 89 byte* Assembler::spare_buffer_ = NULL;
94 90
95 Assembler::Assembler(void* buffer, int buffer_size) { 91 Assembler::Assembler(void* buffer, int buffer_size) {
96 if (buffer == NULL) { 92 if (buffer == NULL) {
97 // do our own buffer management 93 // do our own buffer management
98 if (buffer_size <= kMinimalBufferSize) { 94 if (buffer_size <= kMinimalBufferSize) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 pc_ += length; 294 pc_ += length;
299 } 295 }
300 296
301 297
302 // Assembler Instruction implementations 298 // Assembler Instruction implementations
303 299
304 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { 300 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
305 EnsureSpace ensure_space(this); 301 EnsureSpace ensure_space(this);
306 last_pc_ = pc_; 302 last_pc_ = pc_;
307 emit_rex_64(reg, op); 303 emit_rex_64(reg, op);
308 EMIT(opcode); 304 emit(opcode);
309 emit_operand(reg, op); 305 emit_operand(reg, op);
310 } 306 }
311 307
312 308
313 void Assembler::arithmetic_op(byte opcode, Register dst, Register src) { 309 void Assembler::arithmetic_op(byte opcode, Register dst, Register src) {
314 EnsureSpace ensure_space(this); 310 EnsureSpace ensure_space(this);
315 last_pc_ = pc_; 311 last_pc_ = pc_;
316 emit_rex_64(dst, src); 312 emit_rex_64(dst, src);
317 EMIT(opcode); 313 emit(opcode);
318 EMIT(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); 314 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
319 } 315 }
320 316
321 void Assembler::immediate_arithmetic_op(byte subcode, 317 void Assembler::immediate_arithmetic_op(byte subcode,
322 Register dst, 318 Register dst,
323 Immediate src) { 319 Immediate src) {
324 EnsureSpace ensure_space(this); 320 EnsureSpace ensure_space(this);
325 last_pc_ = pc_; 321 last_pc_ = pc_;
326 emit_rex_64(rax, dst); 322 emit_rex_64(rax, dst);
327 if (is_int8(src.value_)) { 323 if (is_int8(src.value_)) {
328 EMIT(0x83); 324 emit(0x83);
329 EMIT(0xC0 | (subcode << 3) | (dst.code() & 0x7)); 325 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
330 EMIT(src.value_); 326 emit(src.value_);
331 } else { 327 } else {
332 EMIT(0x81); 328 emit(0x81);
333 EMIT(0xC0 | (subcode << 3) | (dst.code() & 0x7)); 329 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
334 emitl(src.value_); 330 emitl(src.value_);
335 } 331 }
336 } 332 }
337 333
338 void Assembler::immediate_arithmetic_op(byte subcode, 334 void Assembler::immediate_arithmetic_op(byte subcode,
339 const Operand& dst, 335 const Operand& dst,
340 Immediate src) { 336 Immediate src) {
341 EnsureSpace ensure_space(this); 337 EnsureSpace ensure_space(this);
342 last_pc_ = pc_; 338 last_pc_ = pc_;
343 emit_rex_64(rax, dst); 339 emit_rex_64(rax, dst);
344 if (is_int8(src.value_)) { 340 if (is_int8(src.value_)) {
345 EMIT(0x83); 341 emit(0x83);
346 emit_operand(Register::toRegister(subcode), dst); 342 emit_operand(Register::toRegister(subcode), dst);
347 EMIT(src.value_); 343 emit(src.value_);
348 } else { 344 } else {
349 EMIT(0x81); 345 emit(0x81);
350 emit_operand(Register::toRegister(subcode), dst); 346 emit_operand(Register::toRegister(subcode), dst);
351 emitl(src.value_); 347 emitl(src.value_);
352 } 348 }
353 } 349 }
354 350
355 351
356 void Assembler::call(Label* L) { 352 void Assembler::call(Label* L) {
357 EnsureSpace ensure_space(this); 353 EnsureSpace ensure_space(this);
358 last_pc_ = pc_; 354 last_pc_ = pc_;
359 // 1110 1000 #32-bit disp 355 // 1110 1000 #32-bit disp
360 EMIT(0xE8); 356 emit(0xE8);
361 if (L->is_bound()) { 357 if (L->is_bound()) {
362 int offset = L->pos() - pc_offset() - sizeof(int32_t); 358 int offset = L->pos() - pc_offset() - sizeof(int32_t);
363 ASSERT(offset <= 0); 359 ASSERT(offset <= 0);
364 emitl(offset); 360 emitl(offset);
365 } else if (L->is_linked()) { 361 } else if (L->is_linked()) {
366 emitl(L->pos()); 362 emitl(L->pos());
367 L->link_to(pc_offset() - sizeof(int32_t)); 363 L->link_to(pc_offset() - sizeof(int32_t));
368 } else { 364 } else {
369 ASSERT(L->is_unused()); 365 ASSERT(L->is_unused());
370 int32_t current = pc_offset(); 366 int32_t current = pc_offset();
371 emitl(current); 367 emitl(current);
372 L->link_to(current); 368 L->link_to(current);
373 } 369 }
374 } 370 }
375 371
376 372
377 void Assembler::dec(Register dst) { 373 void Assembler::dec(Register dst) {
378 EnsureSpace ensure_space(this); 374 EnsureSpace ensure_space(this);
379 last_pc_ = pc_; 375 last_pc_ = pc_;
380 emit_rex_64(rcx, dst); 376 emit_rex_64(rcx, dst);
381 EMIT(0xFF); 377 emit(0xFF);
382 EMIT(0xC8 | (dst.code() & 0x7)); 378 emit(0xC8 | (dst.code() & 0x7));
383 } 379 }
384 380
385 381
386 void Assembler::dec(const Operand& dst) { 382 void Assembler::dec(const Operand& dst) {
387 EnsureSpace ensure_space(this); 383 EnsureSpace ensure_space(this);
388 last_pc_ = pc_; 384 last_pc_ = pc_;
389 emit_rex_64(rax, dst); 385 emit_rex_64(rax, dst);
390 EMIT(0xFF); 386 emit(0xFF);
391 emit_operand(rcx, dst); 387 emit_operand(rcx, dst);
392 } 388 }
393 389
394 390
395 void Assembler::hlt() { 391 void Assembler::hlt() {
396 EnsureSpace ensure_space(this); 392 EnsureSpace ensure_space(this);
397 last_pc_ = pc_; 393 last_pc_ = pc_;
398 EMIT(0xF4); 394 emit(0xF4);
399 } 395 }
400 396
401 397
402 void Assembler::inc(Register dst) { 398 void Assembler::inc(Register dst) {
403 EnsureSpace ensure_space(this); 399 EnsureSpace ensure_space(this);
404 last_pc_ = pc_; 400 last_pc_ = pc_;
405 emit_rex_64(rax, dst); 401 emit_rex_64(rax, dst);
406 EMIT(0xFF); 402 emit(0xFF);
407 EMIT(0xC0 | (dst.code() & 0x7)); 403 emit(0xC0 | (dst.code() & 0x7));
408 } 404 }
409 405
410 406
411 void Assembler::inc(const Operand& dst) { 407 void Assembler::inc(const Operand& dst) {
412 EnsureSpace ensure_space(this); 408 EnsureSpace ensure_space(this);
413 last_pc_ = pc_; 409 last_pc_ = pc_;
414 emit_rex_64(rax, dst); 410 emit_rex_64(rax, dst);
415 EMIT(0xFF); 411 emit(0xFF);
416 emit_operand(rax, dst); 412 emit_operand(rax, dst);
417 } 413 }
418 414
419 415
420 void Assembler::int3() { 416 void Assembler::int3() {
421 EnsureSpace ensure_space(this); 417 EnsureSpace ensure_space(this);
422 last_pc_ = pc_; 418 last_pc_ = pc_;
423 EMIT(0xCC); 419 emit(0xCC);
424 } 420 }
425 421
426 422
427 void Assembler::j(Condition cc, Label* L) { 423 void Assembler::j(Condition cc, Label* L) {
428 EnsureSpace ensure_space(this); 424 EnsureSpace ensure_space(this);
429 last_pc_ = pc_; 425 last_pc_ = pc_;
430 ASSERT(0 <= cc && cc < 16); 426 ASSERT(0 <= cc && cc < 16);
431 if (L->is_bound()) { 427 if (L->is_bound()) {
432 const int short_size = 2; 428 const int short_size = 2;
433 const int long_size = 6; 429 const int long_size = 6;
434 int offs = L->pos() - pc_offset(); 430 int offs = L->pos() - pc_offset();
435 ASSERT(offs <= 0); 431 ASSERT(offs <= 0);
436 if (is_int8(offs - short_size)) { 432 if (is_int8(offs - short_size)) {
437 // 0111 tttn #8-bit disp 433 // 0111 tttn #8-bit disp
438 EMIT(0x70 | cc); 434 emit(0x70 | cc);
439 EMIT((offs - short_size) & 0xFF); 435 emit((offs - short_size) & 0xFF);
440 } else { 436 } else {
441 // 0000 1111 1000 tttn #32-bit disp 437 // 0000 1111 1000 tttn #32-bit disp
442 EMIT(0x0F); 438 emit(0x0F);
443 EMIT(0x80 | cc); 439 emit(0x80 | cc);
444 emitl(offs - long_size); 440 emitl(offs - long_size);
445 } 441 }
446 } else if (L->is_linked()) { 442 } else if (L->is_linked()) {
447 // 0000 1111 1000 tttn #32-bit disp 443 // 0000 1111 1000 tttn #32-bit disp
448 EMIT(0x0F); 444 emit(0x0F);
449 EMIT(0x80 | cc); 445 emit(0x80 | cc);
450 emitl(L->pos()); 446 emitl(L->pos());
451 L->link_to(pc_offset() - sizeof(int32_t)); 447 L->link_to(pc_offset() - sizeof(int32_t));
452 } else { 448 } else {
453 ASSERT(L->is_unused()); 449 ASSERT(L->is_unused());
454 EMIT(0x0F); 450 emit(0x0F);
455 EMIT(0x80 | cc); 451 emit(0x80 | cc);
456 int32_t current = pc_offset(); 452 int32_t current = pc_offset();
457 emitl(current); 453 emitl(current);
458 L->link_to(current); 454 L->link_to(current);
459 } 455 }
460 } 456 }
461 457
462 458
463 void Assembler::jmp(Label* L) { 459 void Assembler::jmp(Label* L) {
464 EnsureSpace ensure_space(this); 460 EnsureSpace ensure_space(this);
465 last_pc_ = pc_; 461 last_pc_ = pc_;
466 if (L->is_bound()) { 462 if (L->is_bound()) {
467 int offs = L->pos() - pc_offset() - 1; 463 int offs = L->pos() - pc_offset() - 1;
468 ASSERT(offs <= 0); 464 ASSERT(offs <= 0);
469 if (is_int8(offs - sizeof(int8_t))) { 465 if (is_int8(offs - sizeof(int8_t))) {
470 // 1110 1011 #8-bit disp 466 // 1110 1011 #8-bit disp
471 EMIT(0xEB); 467 emit(0xEB);
472 EMIT((offs - sizeof(int8_t)) & 0xFF); 468 emit((offs - sizeof(int8_t)) & 0xFF);
473 } else { 469 } else {
474 // 1110 1001 #32-bit disp 470 // 1110 1001 #32-bit disp
475 EMIT(0xE9); 471 emit(0xE9);
476 emitl(offs - sizeof(int32_t)); 472 emitl(offs - sizeof(int32_t));
477 } 473 }
478 } else if (L->is_linked()) { 474 } else if (L->is_linked()) {
479 // 1110 1001 #32-bit disp 475 // 1110 1001 #32-bit disp
480 EMIT(0xE9); 476 emit(0xE9);
481 emitl(L->pos()); 477 emitl(L->pos());
482 L->link_to(pc_offset() - sizeof(int32_t)); 478 L->link_to(pc_offset() - sizeof(int32_t));
483 } else { 479 } else {
484 // 1110 1001 #32-bit disp 480 // 1110 1001 #32-bit disp
485 ASSERT(L->is_unused()); 481 ASSERT(L->is_unused());
486 EMIT(0xE9); 482 emit(0xE9);
487 int32_t current = pc_offset(); 483 int32_t current = pc_offset();
488 emitl(current); 484 emitl(current);
489 L->link_to(current); 485 L->link_to(current);
490 } 486 }
491 } 487 }
492 488
493 489
494 void Assembler::movq(Register dst, const Operand& src) { 490 void Assembler::movq(Register dst, const Operand& src) {
495 EnsureSpace ensure_space(this); 491 EnsureSpace ensure_space(this);
496 last_pc_ = pc_; 492 last_pc_ = pc_;
497 emit_rex_64(dst, src); 493 emit_rex_64(dst, src);
498 EMIT(0x8B); 494 emit(0x8B);
499 emit_operand(dst, src); 495 emit_operand(dst, src);
500 } 496 }
501 497
502 498
503 void Assembler::movq(Register dst, Register src) { 499 void Assembler::movq(Register dst, Register src) {
504 EnsureSpace ensure_space(this); 500 EnsureSpace ensure_space(this);
505 last_pc_ = pc_; 501 last_pc_ = pc_;
506 emit_rex_64(dst, src); 502 emit_rex_64(dst, src);
507 EMIT(0x8B); 503 emit(0x8B);
508 EMIT(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); 504 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
509 } 505 }
510 506
511 507
512 void Assembler::movq(Register dst, Immediate value) { 508 void Assembler::movq(Register dst, Immediate value) {
513 EnsureSpace ensure_space(this); 509 EnsureSpace ensure_space(this);
514 last_pc_ = pc_; 510 last_pc_ = pc_;
515 emit_rex_64(rax, dst); 511 emit_rex_64(rax, dst);
516 EMIT(0xC7); 512 emit(0xC7);
517 EMIT(0xC0 | (dst.code() & 0x7)); 513 emit(0xC0 | (dst.code() & 0x7));
518 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. 514 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
519 } 515 }
520 516
521 517
522 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { 518 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
523 EnsureSpace ensure_space(this); 519 EnsureSpace ensure_space(this);
524 last_pc_ = pc_; 520 last_pc_ = pc_;
525 emit_rex_64(rax, dst); 521 emit_rex_64(rax, dst);
526 EMIT(0xB8 | (dst.code() & 0x7)); 522 emit(0xB8 | (dst.code() & 0x7));
527 emitq(value, rmode); 523 emitq(value, rmode);
528 } 524 }
529 525
530 526
531 void Assembler::nop() { 527 void Assembler::nop() {
532 EnsureSpace ensure_space(this); 528 EnsureSpace ensure_space(this);
533 last_pc_ = pc_; 529 last_pc_ = pc_;
534 EMIT(0x90); 530 emit(0x90);
535 } 531 }
536 532
537 533
538 void Assembler::pop(Register dst) { 534 void Assembler::pop(Register dst) {
539 EnsureSpace ensure_space(this); 535 EnsureSpace ensure_space(this);
540 last_pc_ = pc_; 536 last_pc_ = pc_;
541 if (dst.code() & 0x8) { 537 if (dst.code() & 0x8) {
542 emit_rex_64(rax, dst); 538 emit_rex_64(rax, dst);
543 } 539 }
544 EMIT(0x58 | (dst.code() & 0x7)); 540 emit(0x58 | (dst.code() & 0x7));
545 } 541 }
546 542
547 543
548 void Assembler::pop(const Operand& dst) { 544 void Assembler::pop(const Operand& dst) {
549 EnsureSpace ensure_space(this); 545 EnsureSpace ensure_space(this);
550 last_pc_ = pc_; 546 last_pc_ = pc_;
551 emit_rex_64(rax, dst); // Could be omitted in some cases. 547 emit_rex_64(rax, dst); // Could be omitted in some cases.
552 EMIT(0x8F); 548 emit(0x8F);
553 emit_operand(rax, dst); 549 emit_operand(rax, dst);
554 } 550 }
555 551
556 552
557 void Assembler::push(Register src) { 553 void Assembler::push(Register src) {
558 EnsureSpace ensure_space(this); 554 EnsureSpace ensure_space(this);
559 last_pc_ = pc_; 555 last_pc_ = pc_;
560 if (src.code() & 0x8) { 556 if (src.code() & 0x8) {
561 emit_rex_64(rax, src); 557 emit_rex_64(rax, src);
562 } 558 }
563 EMIT(0x50 | (src.code() & 0x7)); 559 emit(0x50 | (src.code() & 0x7));
564 } 560 }
565 561
566 562
567 void Assembler::push(const Operand& src) { 563 void Assembler::push(const Operand& src) {
568 EnsureSpace ensure_space(this); 564 EnsureSpace ensure_space(this);
569 last_pc_ = pc_; 565 last_pc_ = pc_;
570 emit_rex_64(rsi, src); // Could be omitted in some cases. 566 emit_rex_64(rsi, src); // Could be omitted in some cases.
571 EMIT(0xFF); 567 emit(0xFF);
572 emit_operand(rsi, src); 568 emit_operand(rsi, src);
573 } 569 }
574 570
575 571
576 void Assembler::ret(int imm16) { 572 void Assembler::ret(int imm16) {
577 EnsureSpace ensure_space(this); 573 EnsureSpace ensure_space(this);
578 last_pc_ = pc_; 574 last_pc_ = pc_;
579 ASSERT(is_uint16(imm16)); 575 ASSERT(is_uint16(imm16));
580 if (imm16 == 0) { 576 if (imm16 == 0) {
581 EMIT(0xC3); 577 emit(0xC3);
582 } else { 578 } else {
583 EMIT(0xC2); 579 emit(0xC2);
584 EMIT(imm16 & 0xFF); 580 emit(imm16 & 0xFF);
585 EMIT((imm16 >> 8) & 0xFF); 581 emit((imm16 >> 8) & 0xFF);
586 } 582 }
587 } 583 }
588 584
589 } } // namespace v8::internal 585 } } // namespace v8::internal
590 586
591 587
592 // TODO(x64): Implement and move these to their correct cc-files: 588 // TODO(x64): Implement and move these to their correct cc-files:
593 #include "ast.h" 589 #include "ast.h"
594 #include "bootstrapper.h" 590 #include "bootstrapper.h"
595 #include "codegen-inl.h" 591 #include "codegen-inl.h"
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 UNIMPLEMENTED(); 856 UNIMPLEMENTED();
861 return NULL; 857 return NULL;
862 } 858 }
863 859
864 byte* JavaScriptFrame::GetCallerStackPointer() const { 860 byte* JavaScriptFrame::GetCallerStackPointer() const {
865 UNIMPLEMENTED(); 861 UNIMPLEMENTED();
866 return NULL; 862 return NULL;
867 } 863 }
868 864
869 } } // namespace v8::internal 865 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698