OLD | NEW |
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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 no_condition = -1, | 111 no_condition = -1, |
112 | 112 |
113 overflow = 0, | 113 overflow = 0, |
114 no_overflow = 1, | 114 no_overflow = 1, |
115 below = 2, | 115 below = 2, |
116 above_equal = 3, | 116 above_equal = 3, |
117 equal = 4, | 117 equal = 4, |
118 not_equal = 5, | 118 not_equal = 5, |
119 below_equal = 6, | 119 below_equal = 6, |
120 above = 7, | 120 above = 7, |
121 sign = 8, | 121 negative = 8, |
122 not_sign = 9, | 122 positive = 9, |
123 parity_even = 10, | 123 parity_even = 10, |
124 parity_odd = 11, | 124 parity_odd = 11, |
125 less = 12, | 125 less = 12, |
126 greater_equal = 13, | 126 greater_equal = 13, |
127 less_equal = 14, | 127 less_equal = 14, |
128 greater = 15, | 128 greater = 15, |
129 | 129 |
130 // aliases | 130 // aliases |
| 131 carry = below, |
| 132 not_carry = above_equal, |
131 zero = equal, | 133 zero = equal, |
132 not_zero = not_equal, | 134 not_zero = not_equal, |
133 negative = sign, | 135 sign = negative, |
134 positive = not_sign | 136 not_sign = positive |
135 }; | 137 }; |
136 | 138 |
137 | 139 |
138 // Returns the equivalent of !cc. | 140 // Returns the equivalent of !cc. |
139 // Negation of the default no_condition (-1) results in a non-default | 141 // Negation of the default no_condition (-1) results in a non-default |
140 // no_condition value (-2). As long as tests for no_condition check | 142 // no_condition value (-2). As long as tests for no_condition check |
141 // for condition < 0, this will work as expected. | 143 // for condition < 0, this will work as expected. |
142 inline Condition NegateCondition(Condition cc); | 144 inline Condition NegateCondition(Condition cc); |
143 | 145 |
144 // Corresponds to transposing the operands of a comparison. | 146 // Corresponds to transposing the operands of a comparison. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 // | 278 // |
277 // next field: position of next displacement in the chain (0 = end of list) | 279 // next field: position of next displacement in the chain (0 = end of list) |
278 // type field: instruction type | 280 // type field: instruction type |
279 // | 281 // |
280 // A next value of null (0) indicates the end of a chain (note that there can | 282 // A next value of null (0) indicates the end of a chain (note that there can |
281 // be no displacement at position zero, because there is always at least one | 283 // be no displacement at position zero, because there is always at least one |
282 // instruction byte before the displacement). | 284 // instruction byte before the displacement). |
283 // | 285 // |
284 // Displacement _data field layout | 286 // Displacement _data field layout |
285 // | 287 // |
286 // |31.....1| ......0| | 288 // |31.....2|1......0| |
287 // [ next | type | | 289 // [ next | type | |
288 | 290 |
289 class Displacement BASE_EMBEDDED { | 291 class Displacement BASE_EMBEDDED { |
290 public: | 292 public: |
291 enum Type { | 293 enum Type { |
292 UNCONDITIONAL_JUMP, | 294 UNCONDITIONAL_JUMP, |
| 295 CODE_RELATIVE, |
293 OTHER | 296 OTHER |
294 }; | 297 }; |
295 | 298 |
296 int data() const { return data_; } | 299 int data() const { return data_; } |
297 Type type() const { return TypeField::decode(data_); } | 300 Type type() const { return TypeField::decode(data_); } |
298 void next(Label* L) const { | 301 void next(Label* L) const { |
299 int n = NextField::decode(data_); | 302 int n = NextField::decode(data_); |
300 n > 0 ? L->link_to(n) : L->Unuse(); | 303 n > 0 ? L->link_to(n) : L->Unuse(); |
301 } | 304 } |
302 void link_to(Label* L) { init(L, type()); } | 305 void link_to(Label* L) { init(L, type()); } |
303 | 306 |
304 explicit Displacement(int data) { data_ = data; } | 307 explicit Displacement(int data) { data_ = data; } |
305 | 308 |
306 Displacement(Label* L, Type type) { init(L, type); } | 309 Displacement(Label* L, Type type) { init(L, type); } |
307 | 310 |
308 void print() { | 311 void print() { |
309 PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"), | 312 PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"), |
310 NextField::decode(data_)); | 313 NextField::decode(data_)); |
311 } | 314 } |
312 | 315 |
313 private: | 316 private: |
314 int data_; | 317 int data_; |
315 | 318 |
316 class TypeField: public BitField<Type, 0, 1> {}; | 319 class TypeField: public BitField<Type, 0, 2> {}; |
317 class NextField: public BitField<int, 1, 32-1> {}; | 320 class NextField: public BitField<int, 2, 32-2> {}; |
318 | 321 |
319 void init(Label* L, Type type); | 322 void init(Label* L, Type type); |
320 }; | 323 }; |
321 | 324 |
322 | 325 |
323 | 326 |
324 // CpuFeatures keeps track of which features are supported by the target CPU. | 327 // CpuFeatures keeps track of which features are supported by the target CPU. |
325 // Supported features must be enabled by a Scope before use. | 328 // Supported features must be enabled by a Scope before use. |
326 // Example: | 329 // Example: |
327 // if (CpuFeatures::IsSupported(SSE2)) { | 330 // if (CpuFeatures::IsSupported(SSE2)) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 // Stack | 436 // Stack |
434 void pushad(); | 437 void pushad(); |
435 void popad(); | 438 void popad(); |
436 | 439 |
437 void pushfd(); | 440 void pushfd(); |
438 void popfd(); | 441 void popfd(); |
439 | 442 |
440 void push(const Immediate& x); | 443 void push(const Immediate& x); |
441 void push(Register src); | 444 void push(Register src); |
442 void push(const Operand& src); | 445 void push(const Operand& src); |
| 446 void push(Label* label, RelocInfo::Mode relocation_mode); |
443 | 447 |
444 void pop(Register dst); | 448 void pop(Register dst); |
445 void pop(const Operand& dst); | 449 void pop(const Operand& dst); |
446 | 450 |
| 451 void enter(const Immediate& size); |
| 452 void leave(); |
| 453 |
447 // Moves | 454 // Moves |
448 void mov_b(Register dst, const Operand& src); | 455 void mov_b(Register dst, const Operand& src); |
449 void mov_b(const Operand& dst, int8_t imm8); | 456 void mov_b(const Operand& dst, int8_t imm8); |
450 void mov_b(const Operand& dst, Register src); | 457 void mov_b(const Operand& dst, Register src); |
451 | 458 |
452 void mov_w(Register dst, const Operand& src); | 459 void mov_w(Register dst, const Operand& src); |
453 void mov_w(const Operand& dst, Register src); | 460 void mov_w(const Operand& dst, Register src); |
454 | 461 |
455 void mov(Register dst, int32_t imm32); | 462 void mov(Register dst, int32_t imm32); |
456 void mov(Register dst, const Immediate& x); | 463 void mov(Register dst, const Immediate& x); |
(...skipping 27 matching lines...) Expand all Loading... |
484 void and_(Register dst, int32_t imm32); | 491 void and_(Register dst, int32_t imm32); |
485 void and_(Register dst, const Operand& src); | 492 void and_(Register dst, const Operand& src); |
486 void and_(const Operand& src, Register dst); | 493 void and_(const Operand& src, Register dst); |
487 void and_(const Operand& dst, const Immediate& x); | 494 void and_(const Operand& dst, const Immediate& x); |
488 | 495 |
489 void cmp(Register reg, int32_t imm32); | 496 void cmp(Register reg, int32_t imm32); |
490 void cmp(Register reg, Handle<Object> handle); | 497 void cmp(Register reg, Handle<Object> handle); |
491 void cmp(Register reg, const Operand& op); | 498 void cmp(Register reg, const Operand& op); |
492 void cmp(const Operand& op, const Immediate& imm); | 499 void cmp(const Operand& op, const Immediate& imm); |
493 | 500 |
| 501 void rep_cmpsb(); |
| 502 void rep_cmpsw(); |
| 503 |
494 void dec_b(Register dst); | 504 void dec_b(Register dst); |
495 | 505 |
496 void dec(Register dst); | 506 void dec(Register dst); |
497 void dec(const Operand& dst); | 507 void dec(const Operand& dst); |
498 | 508 |
499 void cdq(); | 509 void cdq(); |
500 | 510 |
501 void idiv(Register src); | 511 void idiv(Register src); |
502 | 512 |
503 void imul(Register dst, const Operand& src); | 513 void imul(Register dst, const Operand& src); |
(...skipping 24 matching lines...) Expand all Loading... |
528 | 538 |
529 void shld(Register dst, const Operand& src); | 539 void shld(Register dst, const Operand& src); |
530 | 540 |
531 void shl(Register dst, uint8_t imm8); | 541 void shl(Register dst, uint8_t imm8); |
532 void shl(Register dst); | 542 void shl(Register dst); |
533 | 543 |
534 void shrd(Register dst, const Operand& src); | 544 void shrd(Register dst, const Operand& src); |
535 | 545 |
536 void shr(Register dst, uint8_t imm8); | 546 void shr(Register dst, uint8_t imm8); |
537 void shr(Register dst); | 547 void shr(Register dst); |
| 548 void shr_cl(Register dst); |
538 | 549 |
539 void sub(const Operand& dst, const Immediate& x); | 550 void sub(const Operand& dst, const Immediate& x); |
540 void sub(Register dst, const Operand& src); | 551 void sub(Register dst, const Operand& src); |
541 void sub(const Operand& dst, Register src); | 552 void sub(const Operand& dst, Register src); |
542 | 553 |
543 void test(Register reg, const Immediate& imm); | 554 void test(Register reg, const Immediate& imm); |
544 void test(Register reg, const Operand& op); | 555 void test(Register reg, const Operand& op); |
545 void test(const Operand& op, const Immediate& imm); | 556 void test(const Operand& op, const Immediate& imm); |
546 | 557 |
547 void xor_(Register dst, int32_t imm32); | 558 void xor_(Register dst, int32_t imm32); |
548 void xor_(Register dst, const Operand& src); | 559 void xor_(Register dst, const Operand& src); |
549 void xor_(const Operand& src, Register dst); | 560 void xor_(const Operand& src, Register dst); |
550 void xor_(const Operand& dst, const Immediate& x); | 561 void xor_(const Operand& dst, const Immediate& x); |
551 | 562 |
552 // Bit operations. | 563 // Bit operations. |
| 564 void bt(const Operand& dst, Register src); |
553 void bts(const Operand& dst, Register src); | 565 void bts(const Operand& dst, Register src); |
554 | 566 |
555 // Miscellaneous | 567 // Miscellaneous |
556 void hlt(); | 568 void hlt(); |
557 void int3(); | 569 void int3(); |
558 void nop(); | 570 void nop(); |
559 void rdtsc(); | 571 void rdtsc(); |
560 void ret(int imm16); | 572 void ret(int imm16); |
561 void leave(); | |
562 | 573 |
563 // Label operations & relative jumps (PPUM Appendix D) | 574 // Label operations & relative jumps (PPUM Appendix D) |
564 // | 575 // |
565 // Takes a branch opcode (cc) and a label (L) and generates | 576 // Takes a branch opcode (cc) and a label (L) and generates |
566 // either a backward branch or a forward branch and links it | 577 // either a backward branch or a forward branch and links it |
567 // to the label fixup chain. Usage: | 578 // to the label fixup chain. Usage: |
568 // | 579 // |
569 // Label L; // unbound label | 580 // Label L; // unbound label |
570 // j(cc, &L); // forward branch to unbound label | 581 // j(cc, &L); // forward branch to unbound label |
571 // bind(&L); // bind label to the current pc | 582 // bind(&L); // bind label to the current pc |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 void long_at_put(int pos, uint32_t x) { | 752 void long_at_put(int pos, uint32_t x) { |
742 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; | 753 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; |
743 } | 754 } |
744 | 755 |
745 // code emission | 756 // code emission |
746 void GrowBuffer(); | 757 void GrowBuffer(); |
747 inline void emit(uint32_t x); | 758 inline void emit(uint32_t x); |
748 inline void emit(Handle<Object> handle); | 759 inline void emit(Handle<Object> handle); |
749 inline void emit(uint32_t x, RelocInfo::Mode rmode); | 760 inline void emit(uint32_t x, RelocInfo::Mode rmode); |
750 inline void emit(const Immediate& x); | 761 inline void emit(const Immediate& x); |
| 762 inline void emit_w(const Immediate& x); |
751 | 763 |
752 // instruction generation | 764 // instruction generation |
753 void emit_arith_b(int op1, int op2, Register dst, int imm8); | 765 void emit_arith_b(int op1, int op2, Register dst, int imm8); |
754 | 766 |
755 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) | 767 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) |
756 // with a given destination expression and an immediate operand. It attempts | 768 // with a given destination expression and an immediate operand. It attempts |
757 // to use the shortest encoding possible. | 769 // to use the shortest encoding possible. |
758 // sel specifies the /n in the modrm byte (see the Intel PRM). | 770 // sel specifies the /n in the modrm byte (see the Intel PRM). |
759 void emit_arith(int sel, Operand dst, const Immediate& x); | 771 void emit_arith(int sel, Operand dst, const Immediate& x); |
760 | 772 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 private: | 815 private: |
804 Assembler* assembler_; | 816 Assembler* assembler_; |
805 #ifdef DEBUG | 817 #ifdef DEBUG |
806 int space_before_; | 818 int space_before_; |
807 #endif | 819 #endif |
808 }; | 820 }; |
809 | 821 |
810 } } // namespace v8::internal | 822 } } // namespace v8::internal |
811 | 823 |
812 #endif // V8_ASSEMBLER_IA32_H_ | 824 #endif // V8_ASSEMBLER_IA32_H_ |
OLD | NEW |