| 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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 ScaleFactor scale, | 264 ScaleFactor scale, |
| 265 const ExternalReference& arr) { | 265 const ExternalReference& arr) { |
| 266 return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), | 266 return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), |
| 267 RelocInfo::EXTERNAL_REFERENCE); | 267 RelocInfo::EXTERNAL_REFERENCE); |
| 268 } | 268 } |
| 269 | 269 |
| 270 // Returns true if this Operand is a wrapper for the specified register. | 270 // Returns true if this Operand is a wrapper for the specified register. |
| 271 bool is_reg(Register reg) const; | 271 bool is_reg(Register reg) const; |
| 272 | 272 |
| 273 private: | 273 private: |
| 274 // Mutable because reg in ModR/M byte is set by Assembler via set_reg(). | 274 byte buf_[6]; |
| 275 mutable byte buf_[6]; | |
| 276 // The number of bytes in buf_. | 275 // The number of bytes in buf_. |
| 277 unsigned int len_; | 276 unsigned int len_; |
| 278 // Only valid if len_ > 4. | 277 // Only valid if len_ > 4. |
| 279 RelocInfo::Mode rmode_; | 278 RelocInfo::Mode rmode_; |
| 280 | 279 |
| 281 inline void set_modrm(int mod, // reg == 0 | 280 // Set the ModRM byte without an encoded 'reg' register. The |
| 282 Register rm); | 281 // register is encoded later as part of the emit_operand operation. |
| 282 inline void set_modrm(int mod, Register rm); |
| 283 |
| 283 inline void set_sib(ScaleFactor scale, Register index, Register base); | 284 inline void set_sib(ScaleFactor scale, Register index, Register base); |
| 284 inline void set_disp8(int8_t disp); | 285 inline void set_disp8(int8_t disp); |
| 285 inline void set_dispr(int32_t disp, RelocInfo::Mode rmode); | 286 inline void set_dispr(int32_t disp, RelocInfo::Mode rmode); |
| 286 inline void set_reg(Register reg) const; | |
| 287 | 287 |
| 288 friend class Assembler; | 288 friend class Assembler; |
| 289 }; | 289 }; |
| 290 | 290 |
| 291 | 291 |
| 292 // ----------------------------------------------------------------------------- | 292 // ----------------------------------------------------------------------------- |
| 293 // A Displacement describes the 32bit immediate field of an instruction which | 293 // A Displacement describes the 32bit immediate field of an instruction which |
| 294 // may be used together with a Label in order to refer to a yet unknown code | 294 // may be used together with a Label in order to refer to a yet unknown code |
| 295 // position. Displacements stored in the instruction stream are used to describe | 295 // position. Displacements stored in the instruction stream are used to describe |
| 296 // the instruction and to chain a list of instructions using the same Label. | 296 // the instruction and to chain a list of instructions using the same Label. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 // | 409 // |
| 410 // If the provided buffer is not NULL, the assembler uses the provided buffer | 410 // If the provided buffer is not NULL, the assembler uses the provided buffer |
| 411 // for code generation and assumes its size to be buffer_size. If the buffer | 411 // for code generation and assumes its size to be buffer_size. If the buffer |
| 412 // is too small, a fatal error occurs. No deallocation of the buffer is done | 412 // is too small, a fatal error occurs. No deallocation of the buffer is done |
| 413 // upon destruction of the assembler. | 413 // upon destruction of the assembler. |
| 414 Assembler(void* buffer, int buffer_size); | 414 Assembler(void* buffer, int buffer_size); |
| 415 ~Assembler(); | 415 ~Assembler(); |
| 416 | 416 |
| 417 // GetCode emits any pending (non-emitted) code and fills the descriptor | 417 // GetCode emits any pending (non-emitted) code and fills the descriptor |
| 418 // desc. GetCode() is idempotent; it returns the same result if no other | 418 // desc. GetCode() is idempotent; it returns the same result if no other |
| 419 // Assembler functions are invoked inbetween GetCode() calls. | 419 // Assembler functions are invoked in between GetCode() calls. |
| 420 void GetCode(CodeDesc* desc); | 420 void GetCode(CodeDesc* desc); |
| 421 | 421 |
| 422 // Read/Modify the code target in the branch/call instruction at pc. | 422 // Read/Modify the code target in the branch/call instruction at pc. |
| 423 inline static Address target_address_at(Address pc); | 423 inline static Address target_address_at(Address pc); |
| 424 inline static void set_target_address_at(Address pc, Address target); | 424 inline static void set_target_address_at(Address pc, Address target); |
| 425 | 425 |
| 426 // Distance between the address of the code target in the call instruction | 426 // Distance between the address of the code target in the call instruction |
| 427 // and the return address | 427 // and the return address |
| 428 static const int kTargetAddrToReturnAddrDist = kPointerSize; | 428 static const int kTargetAddrToReturnAddrDist = kPointerSize; |
| 429 | 429 |
| 430 | 430 |
| 431 // --------------------------------------------------------------------------- | 431 // --------------------------------------------------------------------------- |
| 432 // Code generation | 432 // Code generation |
| 433 // | 433 // |
| 434 // - function names correspond one-to-one to ia32 instruction mnemonics | 434 // - function names correspond one-to-one to ia32 instruction mnemonics |
| 435 // - unless specified otherwise, instructions operate on 32bit operands | 435 // - unless specified otherwise, instructions operate on 32bit operands |
| 436 // - instructions on 8bit (byte) operands/registers have a trailing '_b' | 436 // - instructions on 8bit (byte) operands/registers have a trailing '_b' |
| 437 // - instructions on 16bit (word) operands/registers have a trailing '_w' | 437 // - instructions on 16bit (word) operands/registers have a trailing '_w' |
| 438 // - naming conflicts with C++ keywords are resolved via a trailing '_' | 438 // - naming conflicts with C++ keywords are resolved via a trailing '_' |
| 439 | 439 |
| 440 // NOTE ON INTERFACE: Currently, the interface is not very consistent | 440 // NOTE ON INTERFACE: Currently, the interface is not very consistent |
| 441 // in the sense that some operations (e.g. mov()) can be called in more | 441 // in the sense that some operations (e.g. mov()) can be called in more |
| 442 // the one way to generate the same instruction: The Register argument | 442 // the one way to generate the same instruction: The Register argument |
| 443 // can in some cases be replaced with an Operand(Register) argument. | 443 // can in some cases be replaced with an Operand(Register) argument. |
| 444 // This should be cleaned up and made more othogonal. The questions | 444 // This should be cleaned up and made more orthogonal. The questions |
| 445 // is: should we always use Operands instead of Registers where an | 445 // is: should we always use Operands instead of Registers where an |
| 446 // Operand is possible, or should we have a Register (overloaded) form | 446 // Operand is possible, or should we have a Register (overloaded) form |
| 447 // instead? We must be carefull to make sure that the selected instruction | 447 // instead? We must be careful to make sure that the selected instruction |
| 448 // is obvious from the parameters to avoid hard-to-find code generation | 448 // is obvious from the parameters to avoid hard-to-find code generation |
| 449 // bugs. | 449 // bugs. |
| 450 | 450 |
| 451 // Insert the smallest number of nop instructions | 451 // Insert the smallest number of nop instructions |
| 452 // possible to align the pc offset to a multiple | 452 // possible to align the pc offset to a multiple |
| 453 // of m. m must be a power of 2. | 453 // of m. m must be a power of 2. |
| 454 void Align(int m); | 454 void Align(int m); |
| 455 | 455 |
| 456 // Stack | 456 // Stack |
| 457 void pushad(); | 457 void pushad(); |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 private: | 845 private: |
| 846 Assembler* assembler_; | 846 Assembler* assembler_; |
| 847 #ifdef DEBUG | 847 #ifdef DEBUG |
| 848 int space_before_; | 848 int space_before_; |
| 849 #endif | 849 #endif |
| 850 }; | 850 }; |
| 851 | 851 |
| 852 } } // namespace v8::internal | 852 } } // namespace v8::internal |
| 853 | 853 |
| 854 #endif // V8_ASSEMBLER_IA32_H_ | 854 #endif // V8_ASSEMBLER_IA32_H_ |
| OLD | NEW |