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

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

Issue 119078: Add multiplication and division to x64 assembler. Add emit_modrm() function. (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 | « no previous file | 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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 ScaleFactor scale, 263 ScaleFactor scale,
264 int32_t disp); 264 int32_t disp);
265 265
266 private: 266 private:
267 byte rex_; 267 byte rex_;
268 byte buf_[10]; 268 byte buf_[10];
269 // The number of bytes in buf_. 269 // The number of bytes in buf_.
270 unsigned int len_; 270 unsigned int len_;
271 RelocInfo::Mode rmode_; 271 RelocInfo::Mode rmode_;
272 272
273 // Set the ModRM byte without an encoded 'reg' register. The 273 // Set the ModR/M byte without an encoded 'reg' register. The
274 // register is encoded later as part of the emit_operand operation. 274 // register is encoded later as part of the emit_operand operation.
275 // set_modrm can be called before or after set_sib and set_disp*. 275 // set_modrm can be called before or after set_sib and set_disp*.
276 inline void set_modrm(int mod, Register rm); 276 inline void set_modrm(int mod, Register rm);
277 277
278 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. 278 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
279 inline void set_sib(ScaleFactor scale, Register index, Register base); 279 inline void set_sib(ScaleFactor scale, Register index, Register base);
280 280
281 // Adds operand displacement fields (offsets added to the memory address). 281 // Adds operand displacement fields (offsets added to the memory address).
282 // Needs to be called after set_sib, not before it. 282 // Needs to be called after set_sib, not before it.
283 inline void set_disp8(int disp); 283 inline void set_disp8(int disp);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 void push(Label* label, RelocInfo::Mode relocation_mode); 410 void push(Label* label, RelocInfo::Mode relocation_mode);
411 411
412 void pop(Register dst); 412 void pop(Register dst);
413 void pop(const Operand& dst); 413 void pop(const Operand& dst);
414 414
415 void enter(Immediate size); 415 void enter(Immediate size);
416 void leave(); 416 void leave();
417 417
418 // Moves 418 // Moves
419 void movb(Register dst, const Operand& src); 419 void movb(Register dst, const Operand& src);
420 void movb(const Operand& dst, int8_t imm8); 420 void movb(Register dst, Immediate imm);
421 void movb(const Operand& dst, Register src); 421 void movb(const Operand& dst, Register src);
422 422
423 void movl(Register dst, Register src); 423 void movl(Register dst, Register src);
424 void movl(Register dst, const Operand& src); 424 void movl(Register dst, const Operand& src);
425 void movl(const Operand& dst, Register src); 425 void movl(const Operand& dst, Register src);
426 // Load a 32-bit immediate value, zero-extended to 64 bits. 426 // Load a 32-bit immediate value, zero-extended to 64 bits.
427 void movl(Register dst, Immediate imm32); 427 void movl(Register dst, Immediate imm32);
428 428
429 void movq(Register dst, int32_t imm32); 429 void movq(Register dst, int32_t imm32);
430 void movq(Register dst, const Operand& src); 430 void movq(Register dst, const Operand& src);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 void cmpw(const Operand& op, Immediate imm16); 531 void cmpw(const Operand& op, Immediate imm16);
532 532
533 void dec_b(Register dst); 533 void dec_b(Register dst);
534 534
535 void dec(Register dst); 535 void dec(Register dst);
536 void dec(const Operand& dst); 536 void dec(const Operand& dst);
537 537
538 // Sign-extends rax into rdx:rax. 538 // Sign-extends rax into rdx:rax.
539 void cqo(); 539 void cqo();
540 540
541 // Divide rdx:rax by src. Quotient in rax, remainder in rdx.
541 void idiv(Register src); 542 void idiv(Register src);
542 543
544 void imul(Register dst, Register src);
543 void imul(Register dst, const Operand& src); 545 void imul(Register dst, const Operand& src);
544 void imul(Register dst, Register src, int32_t imm32); 546 // Performs the operation dst = src * imm.
547 void imul(Register dst, Register src, Immediate imm);
545 548
546 void inc(Register dst); 549 void inc(Register dst);
547 void inc(const Operand& dst); 550 void inc(const Operand& dst);
548 551
549 void lea(Register dst, const Operand& src); 552 void lea(Register dst, const Operand& src);
550 553
554 // Multiply rax by src, put the result in rdx:rax.
551 void mul(Register src); 555 void mul(Register src);
552 556
553 void neg(Register dst); 557 void neg(Register dst);
554 void neg(const Operand& dst); 558 void neg(const Operand& dst);
555 559
556 void not_(Register dst); 560 void not_(Register dst);
557 void not_(const Operand& dst); 561 void not_(const Operand& dst);
558 562
559 void or_(Register dst, Register src) { 563 void or_(Register dst, Register src) {
560 arithmetic_op(0x0B, dst, src); 564 arithmetic_op(0x0B, dst, src);
(...skipping 11 matching lines...) Expand all
572 immediate_arithmetic_op(0x1, dst, src); 576 immediate_arithmetic_op(0x1, dst, src);
573 } 577 }
574 578
575 void or_(const Operand& dst, Immediate src) { 579 void or_(const Operand& dst, Immediate src) {
576 immediate_arithmetic_op(0x1, dst, src); 580 immediate_arithmetic_op(0x1, dst, src);
577 } 581 }
578 582
579 583
580 void rcl(Register dst, uint8_t imm8); 584 void rcl(Register dst, uint8_t imm8);
581 585
582 void sbb(Register dst, const Operand& src); 586 // Shifts dst:src left by cl bits, affecting only dst.
587 void shld(Register dst, Register src);
583 588
584 void shld(Register dst, const Operand& src); 589 // Shifts src:dst right by cl bits, affecting only dst.
585 590 void shrd(Register dst, Register src);
586 void shrd(Register dst, const Operand& src);
587 591
588 // Shifts dst right, duplicating sign bit, by shift_amount bits. 592 // Shifts dst right, duplicating sign bit, by shift_amount bits.
589 // Shifting by 1 is handled efficiently. 593 // Shifting by 1 is handled efficiently.
590 void sar(Register dst, Immediate shift_amount) { 594 void sar(Register dst, Immediate shift_amount) {
591 shift(dst, shift_amount, 0x7); 595 shift(dst, shift_amount, 0x7);
592 } 596 }
593 597
594 // Shifts dst right, duplicating sign bit, by cl % 64 bits. 598 // Shifts dst right, duplicating sign bit, by cl % 64 bits.
595 void sar(Register dst) { 599 void sar(Register dst) {
596 shift(dst, 0x7); 600 shift(dst, 0x7);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 } 633 }
630 634
631 void sub(const Operand& dst, Immediate src) { 635 void sub(const Operand& dst, Immediate src) {
632 immediate_arithmetic_op(0x5, dst, src); 636 immediate_arithmetic_op(0x5, dst, src);
633 } 637 }
634 638
635 void testb(Register reg, Immediate mask); 639 void testb(Register reg, Immediate mask);
636 void testb(const Operand& op, Immediate mask); 640 void testb(const Operand& op, Immediate mask);
637 void testl(Register reg, Immediate mask); 641 void testl(Register reg, Immediate mask);
638 void testl(const Operand& op, Immediate mask); 642 void testl(const Operand& op, Immediate mask);
643 void testq(const Operand& op, Register reg);
644 void testq(Register dst, Register src);
639 645
640 void xor_(Register dst, Register src) { 646 void xor_(Register dst, Register src) {
641 arithmetic_op(0x33, dst, src); 647 arithmetic_op(0x33, dst, src);
642 } 648 }
643 649
644 void xor_(Register dst, const Operand& src) { 650 void xor_(Register dst, const Operand& src) {
645 arithmetic_op(0x33, dst, src); 651 arithmetic_op(0x33, dst, src);
646 } 652 }
647 653
648 void xor_(const Operand& dst, Register src) { 654 void xor_(const Operand& dst, Register src) {
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 // register is used for REX.B, and the high bit of op's index register 897 // register is used for REX.B, and the high bit of op's index register
892 // is used for REX.X. REX.W is cleared. 898 // is used for REX.X. REX.W is cleared.
893 inline void emit_rex_32(Register reg, const Operand& op); 899 inline void emit_rex_32(Register reg, const Operand& op);
894 900
895 // High bit of rm_reg goes to REX.B. 901 // High bit of rm_reg goes to REX.B.
896 // REX.W, REX.R and REX.X are clear. 902 // REX.W, REX.R and REX.X are clear.
897 inline void emit_rex_32(Register rm_reg); 903 inline void emit_rex_32(Register rm_reg);
898 904
899 // High bit of base goes to REX.B and high bit of index to REX.X. 905 // High bit of base goes to REX.B and high bit of index to REX.X.
900 // REX.W and REX.R are clear. 906 // REX.W and REX.R are clear.
901 inline void emit_rex_32(const Operand &); 907 inline void emit_rex_32(const Operand& op);
902 908
903 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 909 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
904 // REX.W is cleared. If no REX bits are set, no byte is emitted. 910 // REX.W is cleared. If no REX bits are set, no byte is emitted.
905 inline void emit_optional_rex_32(Register reg, Register rm_reg); 911 inline void emit_optional_rex_32(Register reg, Register rm_reg);
906 912
907 // The high bit of reg is used for REX.R, the high bit of op's base 913 // The high bit of reg is used for REX.R, the high bit of op's base
908 // register is used for REX.B, and the high bit of op's index register 914 // register is used for REX.B, and the high bit of op's index register
909 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing 915 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
910 // is emitted. 916 // is emitted.
911 inline void emit_optional_rex_32(Register reg, const Operand& op); 917 inline void emit_optional_rex_32(Register reg, const Operand& op);
912 918
913 // Optionally do as emit_rex_32(Register) if the register number has 919 // Optionally do as emit_rex_32(Register) if the register number has
914 // the high bit set. 920 // the high bit set.
915 inline void emit_optional_rex_32(Register rm_reg); 921 inline void emit_optional_rex_32(Register rm_reg);
916 922
917 // Optionally do as emit_rex_32(const Operand&) if the operand register 923 // Optionally do as emit_rex_32(const Operand&) if the operand register
918 // numbers have a high bit set. 924 // numbers have a high bit set.
919 inline void emit_optional_rex_32(const Operand& op); 925 inline void emit_optional_rex_32(const Operand& op);
920 926
921 927
922 // Emit the Mod/RM byte, and optionally the SIB byte and 928 // Emit the ModR/M byte, and optionally the SIB byte and
923 // 1- or 4-byte offset for a memory operand. Also encodes 929 // 1- or 4-byte offset for a memory operand. Also encodes
924 // the second operand of the operation, a register or operation 930 // the second operand of the operation, a register or operation
925 // subcode, into the Mod/RM byte. 931 // subcode, into the reg field of the ModR/M byte.
926 void emit_operand(Register reg, const Operand& adr) { 932 void emit_operand(Register reg, const Operand& adr) {
927 emit_operand(reg.code() & 0x07, adr); 933 emit_operand(reg.code() & 0x07, adr);
928 } 934 }
929 935
930 // Emit the Mod/RM byte, and optionally the SIB byte and 936 // Emit the ModR/M byte, and optionally the SIB byte and
931 // 1- or 4-byte offset for a memory operand. Also used to encode 937 // 1- or 4-byte offset for a memory operand. Also used to encode
932 // a three-byte opcode extension into the Mod/RM byte. 938 // a three-bit opcode extension into the ModR/M byte.
933 void emit_operand(int rm, const Operand& adr); 939 void emit_operand(int rm, const Operand& adr);
934 940
941 // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
942 void emit_modrm(Register reg, Register rm_reg) {
943 emit(0xC0 | (reg.code() & 0x7) << 3 | (rm_reg.code() & 0x7));
944 }
945
946 // Emit a ModR/M byte with an operation subcode in the reg field and
947 // a register in the rm_reg field.
948 void emit_modrm(int code, Register rm_reg) {
949 ASSERT((code & ~0x7) == 0);
950 emit(0xC0 | (code & 0x7) << 3 | (rm_reg.code() & 0x7));
951 }
952
935 // Emit the code-object-relative offset of the label's position 953 // Emit the code-object-relative offset of the label's position
936 inline void emit_code_relative_offset(Label* label); 954 inline void emit_code_relative_offset(Label* label);
937 955
938 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, 956 // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
939 // AND, OR, XOR, or CMP. The encodings of these operations are all 957 // AND, OR, XOR, or CMP. The encodings of these operations are all
940 // similar, differing just in the opcode or in the reg field of the 958 // similar, differing just in the opcode or in the reg field of the
941 // Mod/RM byte. 959 // ModR/M byte.
942 void arithmetic_op(byte opcode, Register dst, Register src); 960 void arithmetic_op(byte opcode, Register dst, Register src);
943 void arithmetic_op(byte opcode, Register reg, const Operand& op); 961 void arithmetic_op(byte opcode, Register reg, const Operand& op);
944 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); 962 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
945 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); 963 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
946 // Emit machine code for a shift operation. 964 // Emit machine code for a shift operation.
947 void shift(Register dst, Immediate shift_amount, int subcode); 965 void shift(Register dst, Immediate shift_amount, int subcode);
948 // Shift dst by cl % 64 bits. 966 // Shift dst by cl % 64 bits.
949 void shift(Register dst, int subcode); 967 void shift(Register dst, int subcode);
950 968
951 void emit_farith(int b1, int b2, int i); 969 void emit_farith(int b1, int b2, int i);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 private: 1026 private:
1009 Assembler* assembler_; 1027 Assembler* assembler_;
1010 #ifdef DEBUG 1028 #ifdef DEBUG
1011 int space_before_; 1029 int space_before_;
1012 #endif 1030 #endif
1013 }; 1031 };
1014 1032
1015 } } // namespace v8::internal 1033 } } // namespace v8::internal
1016 1034
1017 #endif // V8_X64_ASSEMBLER_X64_H_ 1035 #endif // V8_X64_ASSEMBLER_X64_H_
OLDNEW
« no previous file with comments | « no previous file | src/x64/assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698