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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 enum ScaleFactor { | 246 enum ScaleFactor { |
247 times_1 = 0, | 247 times_1 = 0, |
248 times_2 = 1, | 248 times_2 = 1, |
249 times_4 = 2, | 249 times_4 = 2, |
250 times_8 = 3 | 250 times_8 = 3 |
251 }; | 251 }; |
252 | 252 |
253 | 253 |
254 class Operand BASE_EMBEDDED { | 254 class Operand BASE_EMBEDDED { |
255 public: | 255 public: |
256 // reg | |
257 INLINE(explicit Operand(Register reg)); | |
258 | |
259 // MemoryOperand | |
260 INLINE(explicit Operand()) { UNIMPLEMENTED(); } | |
261 | |
262 // Returns true if this Operand is a wrapper for the specified register. | |
263 bool is_reg(Register reg) const; | |
264 | |
265 // These constructors have been moved to MemOperand, and should | |
266 // be removed from Operand as soon as all their uses use MemOperands instead. | |
267 // [disp/r] | |
268 INLINE(explicit Operand(intptr_t disp, RelocInfo::Mode rmode)) { | |
269 UNIMPLEMENTED(); | |
270 } | |
271 // disp only must always be relocated | |
272 | |
273 // [base + disp/r] | 256 // [base + disp/r] |
274 explicit Operand(Register base, int32_t disp, | 257 INLINE(Operand(Register base, int32_t disp)); |
275 RelocInfo::Mode rmode = RelocInfo::NONE); | |
276 | 258 |
277 // [base + index*scale + disp/r] | 259 // [base + index*scale + disp/r] |
278 explicit Operand(Register base, | 260 Operand(Register base, |
279 Register index, | 261 Register index, |
280 ScaleFactor scale, | 262 ScaleFactor scale, |
281 int32_t disp, | 263 int32_t disp); |
282 RelocInfo::Mode rmode = RelocInfo::NONE); | |
283 | 264 |
284 // [index*scale + disp/r] | 265 // [index*scale + disp/r] |
285 explicit Operand(Register index, | 266 Operand(Register index, |
286 ScaleFactor scale, | 267 ScaleFactor scale, |
287 int32_t disp, | 268 int32_t disp); |
288 RelocInfo::Mode rmode = RelocInfo::NONE); | |
289 | |
290 // End of constructors and methods that have been moved to MemOperand. | |
291 | 269 |
292 private: | 270 private: |
293 byte rex_; | 271 byte rex_; |
294 byte buf_[10]; | 272 byte buf_[10]; |
295 // The number of bytes in buf_. | 273 // The number of bytes in buf_. |
296 unsigned int len_; | 274 unsigned int len_; |
297 // Only valid if len_ > 4. | |
298 RelocInfo::Mode rmode_; | 275 RelocInfo::Mode rmode_; |
299 | 276 |
300 // Set the ModRM byte without an encoded 'reg' register. The | 277 // Set the ModRM byte without an encoded 'reg' register. The |
301 // register is encoded later as part of the emit_operand operation. | 278 // register is encoded later as part of the emit_operand operation. |
| 279 // set_modrm can be called before or after set_sib and set_disp*. |
302 inline void set_modrm(int mod, Register rm); | 280 inline void set_modrm(int mod, Register rm); |
303 | 281 |
| 282 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. |
304 inline void set_sib(ScaleFactor scale, Register index, Register base); | 283 inline void set_sib(ScaleFactor scale, Register index, Register base); |
305 inline void set_disp8(int8_t disp); | 284 |
306 inline void set_disp32(int32_t disp); | 285 // Adds operand displacement fields (offsets added to the memory address). |
| 286 // Needs to be called after set_sib, not before it. |
| 287 inline void set_disp8(int disp); |
| 288 inline void set_disp32(int disp); |
307 | 289 |
308 friend class Assembler; | 290 friend class Assembler; |
309 }; | 291 }; |
310 | 292 |
311 class MemOperand : public Operand { | |
312 public: | |
313 // [disp/r] | |
314 INLINE(explicit MemOperand(int32_t disp, RelocInfo::Mode rmode)) : | |
315 Operand() { | |
316 UNIMPLEMENTED(); | |
317 } | |
318 // disp only must always be relocated | |
319 | |
320 // [base + disp/r] | |
321 explicit MemOperand(Register base, int32_t disp, | |
322 RelocInfo::Mode rmode = RelocInfo::NONE); | |
323 | |
324 // [base + index*scale + disp/r] | |
325 explicit MemOperand(Register base, | |
326 Register index, | |
327 ScaleFactor scale, | |
328 int32_t disp, | |
329 RelocInfo::Mode rmode = RelocInfo::NONE); | |
330 | |
331 // [index*scale + disp/r] | |
332 explicit MemOperand(Register index, | |
333 ScaleFactor scale, | |
334 int32_t disp, | |
335 RelocInfo::Mode rmode = RelocInfo::NONE); | |
336 }; | |
337 | |
338 // ----------------------------------------------------------------------------- | |
339 // A Displacement describes the 32bit immediate field of an instruction which | |
340 // may be used together with a Label in order to refer to a yet unknown code | |
341 // position. Displacements stored in the instruction stream are used to describe | |
342 // the instruction and to chain a list of instructions using the same Label. | |
343 // A Displacement contains 2 different fields: | |
344 // | |
345 // next field: position of next displacement in the chain (0 = end of list) | |
346 // type field: instruction type | |
347 // | |
348 // A next value of null (0) indicates the end of a chain (note that there can | |
349 // be no displacement at position zero, because there is always at least one | |
350 // instruction byte before the displacement). | |
351 // | |
352 // Displacement _data field layout | |
353 // | |
354 // |31.....2|1......0| | |
355 // [ next | type | | |
356 | |
357 class Displacement BASE_EMBEDDED { | |
358 public: | |
359 enum Type { | |
360 UNCONDITIONAL_JUMP, | |
361 CODE_RELATIVE, | |
362 OTHER | |
363 }; | |
364 | |
365 int data() const { return data_; } | |
366 Type type() const { return TypeField::decode(data_); } | |
367 void next(Label* L) const { | |
368 int n = NextField::decode(data_); | |
369 n > 0 ? L->link_to(n) : L->Unuse(); | |
370 } | |
371 void link_to(Label* L) { init(L, type()); } | |
372 | |
373 explicit Displacement(int data) { data_ = data; } | |
374 | |
375 Displacement(Label* L, Type type) { init(L, type); } | |
376 | |
377 void print() { | |
378 PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"), | |
379 NextField::decode(data_)); | |
380 } | |
381 | |
382 private: | |
383 int data_; | |
384 | |
385 class TypeField: public BitField<Type, 0, 2> {}; | |
386 class NextField: public BitField<int, 2, 32-2> {}; | |
387 | |
388 void init(Label* L, Type type); | |
389 }; | |
390 | |
391 | |
392 | 293 |
393 // CpuFeatures keeps track of which features are supported by the target CPU. | 294 // CpuFeatures keeps track of which features are supported by the target CPU. |
394 // Supported features must be enabled by a Scope before use. | 295 // Supported features must be enabled by a Scope before use. |
395 // Example: | 296 // Example: |
396 // if (CpuFeatures::IsSupported(SSE2)) { | 297 // if (CpuFeatures::IsSupported(SSE2)) { |
397 // CpuFeatures::Scope fscope(SSE2); | 298 // CpuFeatures::Scope fscope(SSE2); |
398 // // Generate SSE2 floating point code. | 299 // // Generate SSE2 floating point code. |
399 // } else { | 300 // } else { |
400 // // Generate standard x87 floating point code. | 301 // // Generate standard x87 floating point code. |
401 // } | 302 // } |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 | 744 |
844 void emit_operand(Register reg, const Operand& adr); | 745 void emit_operand(Register reg, const Operand& adr); |
845 | 746 |
846 void emit_farith(int b1, int b2, int i); | 747 void emit_farith(int b1, int b2, int i); |
847 | 748 |
848 // labels | 749 // labels |
849 void print(Label* L); | 750 void print(Label* L); |
850 void bind_to(Label* L, int pos); | 751 void bind_to(Label* L, int pos); |
851 void link_to(Label* L, Label* appendix); | 752 void link_to(Label* L, Label* appendix); |
852 | 753 |
853 // displacements | |
854 inline Displacement disp_at(Label* L); | |
855 inline void disp_at_put(Label* L, Displacement disp); | |
856 inline void emit_disp(Label* L, Displacement::Type type); | |
857 | |
858 // record reloc info for current pc_ | 754 // record reloc info for current pc_ |
859 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 755 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
860 | 756 |
861 friend class CodePatcher; | 757 friend class CodePatcher; |
862 friend class EnsureSpace; | 758 friend class EnsureSpace; |
863 | 759 |
864 // Code buffer: | 760 // Code buffer: |
865 // The buffer into which code and relocation info are generated. | 761 // The buffer into which code and relocation info are generated. |
866 byte* buffer_; | 762 byte* buffer_; |
867 int buffer_size_; | 763 int buffer_size_; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 private: | 804 private: |
909 Assembler* assembler_; | 805 Assembler* assembler_; |
910 #ifdef DEBUG | 806 #ifdef DEBUG |
911 int space_before_; | 807 int space_before_; |
912 #endif | 808 #endif |
913 }; | 809 }; |
914 | 810 |
915 } } // namespace v8::internal | 811 } } // namespace v8::internal |
916 | 812 |
917 #endif // V8_X64_ASSEMBLER_X64_H_ | 813 #endif // V8_X64_ASSEMBLER_X64_H_ |
OLD | NEW |