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

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

Issue 115816: Add immediate operands and arithmetic operations to the x64 assembler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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/memory.h ('k') | src/x64/assembler-x64.cc » ('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 (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 // 3) By not using an enum, we are possibly preventing the compiler from 56 // 3) By not using an enum, we are possibly preventing the compiler from
57 // doing certain constant folds, which may significantly reduce the 57 // doing certain constant folds, which may significantly reduce the
58 // code generated for some assembly instructions (because they boil down 58 // code generated for some assembly instructions (because they boil down
59 // to a few constants). If this is a problem, we could change the code 59 // to a few constants). If this is a problem, we could change the code
60 // such that we use an enum in optimized mode, and the struct in debug 60 // such that we use an enum in optimized mode, and the struct in debug
61 // mode. This way we get the compile-time error checking in debug mode 61 // mode. This way we get the compile-time error checking in debug mode
62 // and best performance in optimized code. 62 // and best performance in optimized code.
63 // 63 //
64 64
65 struct Register { 65 struct Register {
66 static Register toRegister(int code) {
67 Register r = {code};
68 return r;
69 }
66 bool is_valid() const { return 0 <= code_ && code_ < 16; } 70 bool is_valid() const { return 0 <= code_ && code_ < 16; }
67 bool is(Register reg) const { return code_ == reg.code_; } 71 bool is(Register reg) const { return code_ == reg.code_; }
68 // The byte-register distinction of ai32 has dissapeared. 72 // The byte-register distinction of ai32 has dissapeared.
69 bool is_byte_register() const { return false; } 73 bool is_byte_register() const { return false; }
70 int code() const { 74 int code() const {
71 ASSERT(is_valid()); 75 ASSERT(is_valid());
72 return code_; 76 return code_;
73 } 77 }
74 int bit() const { 78 int bit() const {
75 UNIMPLEMENTED(); 79 UNIMPLEMENTED();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 ? no_hint 204 ? no_hint
201 : ((hint == not_taken) ? taken : not_taken); 205 : ((hint == not_taken) ? taken : not_taken);
202 } 206 }
203 207
204 208
205 // ----------------------------------------------------------------------------- 209 // -----------------------------------------------------------------------------
206 // Machine instruction Immediates 210 // Machine instruction Immediates
207 211
208 class Immediate BASE_EMBEDDED { 212 class Immediate BASE_EMBEDDED {
209 public: 213 public:
210 inline explicit Immediate(int64_t x); 214 explicit Immediate(int32_t value) : value_(value) {}
211 inline explicit Immediate(const char* s);
212 inline explicit Immediate(const ExternalReference& ext);
213 inline explicit Immediate(Handle<Object> handle);
214 inline explicit Immediate(Smi* value); 215 inline explicit Immediate(Smi* value);
215 216
216 static Immediate CodeRelativeOffset(Label* label) {
217 return Immediate(label);
218 }
219
220 bool is_zero() const { return x_ == 0 && rmode_ == RelocInfo::NONE; }
221 bool is_int8() const {
222 return -128 <= x_ && x_ < 128 && rmode_ == RelocInfo::NONE;
223 }
224 bool is_int16() const {
225 return -32768 <= x_ && x_ < 32768 && rmode_ == RelocInfo::NONE;
226 }
227 bool is_int32() const {
228 return V8_INT64_C(-2147483648) <= x_
229 && x_ < V8_INT64_C(2147483648)
230 && rmode_ == RelocInfo::NONE;
231 }
232
233 private: 217 private:
234 inline explicit Immediate(Label* value) { UNIMPLEMENTED(); } 218 int32_t value_;
235
236 int64_t x_;
237 RelocInfo::Mode rmode_;
238 219
239 friend class Assembler; 220 friend class Assembler;
240 }; 221 };
241 222
242 223
243 // ----------------------------------------------------------------------------- 224 // -----------------------------------------------------------------------------
244 // Machine instruction Operands 225 // Machine instruction Operands
245 226
246 enum ScaleFactor { 227 enum ScaleFactor {
247 times_1 = 0, 228 times_1 = 0,
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 void push(const Operand& src); 396 void push(const Operand& src);
416 void push(Label* label, RelocInfo::Mode relocation_mode); 397 void push(Label* label, RelocInfo::Mode relocation_mode);
417 398
418 void pop(Register dst); 399 void pop(Register dst);
419 void pop(const Operand& dst); 400 void pop(const Operand& dst);
420 401
421 void enter(const Immediate& size); 402 void enter(const Immediate& size);
422 void leave(); 403 void leave();
423 404
424 // Moves 405 // Moves
425 void mov_b(Register dst, const Operand& src); 406 void movb(Register dst, const Operand& src);
426 void mov_b(const Operand& dst, int8_t imm8); 407 void movb(const Operand& dst, int8_t imm8);
427 void mov_b(const Operand& dst, Register src); 408 void movb(const Operand& dst, Register src);
428 409
429 void mov_w(Register dst, const Operand& src); 410 void movq(Register dst, int32_t imm32);
430 void mov_w(const Operand& dst, Register src); 411 void movq(Register dst, Immediate x);
412 void movq(Register dst, const Operand& src);
413 void movq(Register dst, Register src);
414 void movq(const Operand& dst, const Immediate& x);
415 void movq(const Operand& dst, Register src);
431 416
432 void mov(Register dst, int32_t imm32); 417 // New x64 instructions to load a 64-bit immediate into a register.
433 void mov(Register dst, const Immediate& x); 418 // All 64-bit immediates must have a relocation mode.
434 void mov(Register dst, Handle<Object> handle); 419 void movq(Register dst, void* ptr, RelocInfo::Mode rmode);
435 void mov(Register dst, const Operand& src); 420 void movq(Register dst, int64_t value, RelocInfo::Mode rmode);
436 void mov(Register dst, Register src); 421 void movq(Register dst, const char* s, RelocInfo::Mode rmode);
437 void mov(const Operand& dst, const Immediate& x); 422 void movq(Register dst, const ExternalReference& ext, RelocInfo::Mode rmode);
438 void mov(const Operand& dst, Handle<Object> handle); 423 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode);
439 void mov(const Operand& dst, Register src); 424
425 // New x64 instruction to load from an immediate 64-bit pointer into RAX.
426 void load_rax(void* ptr, RelocInfo::Mode rmode);
440 427
441 void movsx_b(Register dst, const Operand& src); 428 void movsx_b(Register dst, const Operand& src);
442 429
443 void movsx_w(Register dst, const Operand& src); 430 void movsx_w(Register dst, const Operand& src);
444 431
445 void movzx_b(Register dst, const Operand& src); 432 void movzx_b(Register dst, const Operand& src);
446 433
447 void movzx_w(Register dst, const Operand& src); 434 void movzx_w(Register dst, const Operand& src);
448 435
449 // Conditional moves 436 // Conditional moves
450 void cmov(Condition cc, Register dst, int32_t imm32); 437 void cmov(Condition cc, Register dst, int32_t imm32);
451 void cmov(Condition cc, Register dst, Handle<Object> handle); 438 void cmov(Condition cc, Register dst, Handle<Object> handle);
452 void cmov(Condition cc, Register dst, const Operand& src); 439 void cmov(Condition cc, Register dst, const Operand& src);
453 440
454 // Exchange two registers 441 // Exchange two registers
455 void xchg(Register dst, Register src); 442 void xchg(Register dst, Register src);
456 443
457 // Arithmetics 444 // Arithmetics
458 void adc(Register dst, int32_t imm32); 445 void add(Register dst, Register src) {
459 void adc(Register dst, const Operand& src); 446 arithmetic_op(0x03, dst, src);
447 }
460 448
461 void add(Register dst, Register src); 449 void add(Register dst, const Operand& src) {
462 void add(Register dst, const Operand& src); 450 arithmetic_op(0x03, dst, src);
463 void add(const Operand& dst, const Immediate& x); 451 }
452
453 void add(const Operand& dst, Register src) {
454 arithmetic_op(0x01, src, dst);
455 }
456
457 void add(Register dst, Immediate src) {
458 immediate_arithmetic_op(0x0, dst, src);
459 }
460
461 void add(const Operand& dst, Immediate src) {
462 immediate_arithmetic_op(0x0, dst, src);
463 }
464
465 void cmp(Register dst, Register src) {
466 arithmetic_op(0x3B, dst, src);
467 }
468
469 void cmp(Register dst, const Operand& src) {
470 arithmetic_op(0x3B, dst, src);
471 }
472
473 void cmp(const Operand& dst, Register src) {
474 arithmetic_op(0x39, src, dst);
475 }
476
477 void cmp(Register dst, Immediate src) {
478 immediate_arithmetic_op(0x7, dst, src);
479 }
480
481 void cmp(const Operand& dst, Immediate src) {
482 immediate_arithmetic_op(0x7, dst, src);
483 }
484
464 485
465 void and_(Register dst, int32_t imm32); 486 void and_(Register dst, int32_t imm32);
466 void and_(Register dst, const Operand& src); 487 void and_(Register dst, const Operand& src);
467 void and_(const Operand& src, Register dst); 488 void and_(const Operand& src, Register dst);
468 void and_(const Operand& dst, const Immediate& x); 489 void and_(const Operand& dst, const Immediate& x);
469 490
470 void cmpb(const Operand& op, int8_t imm8); 491 void cmpb(const Operand& op, int8_t imm8);
471 void cmpb_al(const Operand& op); 492 void cmpb_al(const Operand& op);
472 void cmpw_ax(const Operand& op); 493 void cmpw_ax(const Operand& op);
473 void cmpw(const Operand& op, Immediate imm16); 494 void cmpw(const Operand& op, Immediate imm16);
474 void cmp(Register reg, int32_t imm32);
475 void cmp(Register reg, Handle<Object> handle);
476 void cmp(Register reg, const Operand& op);
477 void cmp(const Operand& op, const Immediate& imm);
478 495
479 void dec_b(Register dst); 496 void dec_b(Register dst);
480 497
481 void dec(Register dst); 498 void dec(Register dst);
482 void dec(const Operand& dst); 499 void dec(const Operand& dst);
483 500
484 void cdq(); 501 void cdq();
485 502
486 void idiv(Register src); 503 void idiv(Register src);
487 504
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 byte byte_at(int pos) { return buffer_[pos]; } 726 byte byte_at(int pos) { return buffer_[pos]; }
710 uint32_t long_at(int pos) { 727 uint32_t long_at(int pos) {
711 return *reinterpret_cast<uint32_t*>(addr_at(pos)); 728 return *reinterpret_cast<uint32_t*>(addr_at(pos));
712 } 729 }
713 void long_at_put(int pos, uint32_t x) { 730 void long_at_put(int pos, uint32_t x) {
714 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 731 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
715 } 732 }
716 733
717 // code emission 734 // code emission
718 void GrowBuffer(); 735 void GrowBuffer();
719 inline void emit(uint32_t x); 736 inline void emitl(uint32_t x);
720 inline void emit(Handle<Object> handle); 737 inline void emit(Handle<Object> handle);
721 inline void emit(uint32_t x, RelocInfo::Mode rmode); 738 inline void emitq(uint64_t x, RelocInfo::Mode rmode);
722 inline void emit(const Immediate& x); 739 void emit(Immediate x) { emitl(x.value_); }
723 inline void emit_w(const Immediate& x);
724 740
725 // Emits a REX prefix that encodes a 64-bit operand size and 741 // Emits a REX prefix that encodes a 64-bit operand size and
726 // the top bit of both register codes. 742 // the top bit of both register codes.
743 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
744 // REX.W is set.
727 inline void emit_rex_64(Register reg, Register rm_reg); 745 inline void emit_rex_64(Register reg, Register rm_reg);
728 746
729 // Emits a REX prefix that encodes a 64-bit operand size and 747 // Emits a REX prefix that encodes a 64-bit operand size and
730 // the top bit of the destination, index, and base register codes. 748 // the top bit of the destination, index, and base register codes.
749 // The high bit of reg is used for REX.R, the high bit of op's base
750 // register is used for REX.B, and the high bit of op's index register
751 // is used for REX.X. REX.W is set.
731 inline void emit_rex_64(Register reg, const Operand& op); 752 inline void emit_rex_64(Register reg, const Operand& op);
732 753
733 // Emit the code-object-relative offset of the label's position 754 // Emit the code-object-relative offset of the label's position
734 inline void emit_code_relative_offset(Label* label); 755 inline void emit_code_relative_offset(Label* label);
735 756
736 // instruction generation 757 // instruction generation
737 void emit_arith_b(int op1, int op2, Register dst, int imm8); 758 void emit_arith_b(int op1, int op2, Register dst, int imm8);
738 759
739 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) 760 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
740 // with a given destination expression and an immediate operand. It attempts 761 // with a given destination expression and an immediate operand. It attempts
741 // to use the shortest encoding possible. 762 // to use the shortest encoding possible.
742 // sel specifies the /n in the modrm byte (see the Intel PRM). 763 // sel specifies the /n in the modrm byte (see the Intel PRM).
764 void arithmetic_op(byte opcode, Register dst, Register src);
765 void arithmetic_op(byte opcode, Register reg, const Operand& op);
766 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
767 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
768
743 void emit_arith(int sel, Operand dst, const Immediate& x); 769 void emit_arith(int sel, Operand dst, const Immediate& x);
744 770
745 void emit_operand(Register reg, const Operand& adr); 771 void emit_operand(Register reg, const Operand& adr);
746 772
747 void emit_farith(int b1, int b2, int i); 773 void emit_farith(int b1, int b2, int i);
748 774
749 // labels 775 // labels
750 void print(Label* L); 776 void print(Label* L);
751 void bind_to(Label* L, int pos); 777 void bind_to(Label* L, int pos);
752 void link_to(Label* L, Label* appendix); 778 void link_to(Label* L, Label* appendix);
753 779
754 // record reloc info for current pc_ 780 // record reloc info for current pc_
755 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 781 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0) {
782 UNIMPLEMENTED();
783 }
756 784
757 friend class CodePatcher; 785 friend class CodePatcher;
758 friend class EnsureSpace; 786 friend class EnsureSpace;
759 787
760 // Code buffer: 788 // Code buffer:
761 // The buffer into which code and relocation info are generated. 789 // The buffer into which code and relocation info are generated.
762 byte* buffer_; 790 byte* buffer_;
763 int buffer_size_; 791 int buffer_size_;
764 // True if the assembler owns the buffer, false if buffer is external. 792 // True if the assembler owns the buffer, false if buffer is external.
765 bool own_buffer_; 793 bool own_buffer_;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 private: 832 private:
805 Assembler* assembler_; 833 Assembler* assembler_;
806 #ifdef DEBUG 834 #ifdef DEBUG
807 int space_before_; 835 int space_before_;
808 #endif 836 #endif
809 }; 837 };
810 838
811 } } // namespace v8::internal 839 } } // namespace v8::internal
812 840
813 #endif // V8_X64_ASSEMBLER_X64_H_ 841 #endif // V8_X64_ASSEMBLER_X64_H_
OLDNEW
« no previous file with comments | « src/memory.h ('k') | src/x64/assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698