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

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

Issue 113997: Add miscellaneous operations to 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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 public: 287 public:
288 // Feature flags bit positions. They are mostly based on the CPUID spec. 288 // Feature flags bit positions. They are mostly based on the CPUID spec.
289 // (We assign CPUID itself to one of the currently reserved bits -- 289 // (We assign CPUID itself to one of the currently reserved bits --
290 // feel free to change this if needed.) 290 // feel free to change this if needed.)
291 enum Feature { SSE3 = 32, SSE2 = 26, CMOV = 15, RDTSC = 4, CPUID = 10 }; 291 enum Feature { SSE3 = 32, SSE2 = 26, CMOV = 15, RDTSC = 4, CPUID = 10 };
292 // Detect features of the target CPU. Set safe defaults if the serializer 292 // Detect features of the target CPU. Set safe defaults if the serializer
293 // is enabled (snapshots must be portable). 293 // is enabled (snapshots must be portable).
294 static void Probe(); 294 static void Probe();
295 // Check whether a feature is supported by the target CPU. 295 // Check whether a feature is supported by the target CPU.
296 static bool IsSupported(Feature f) { 296 static bool IsSupported(Feature f) {
297 return (supported_ & (static_cast<uint64_t>(1) << f)) != 0; 297 return (supported_ & (V8_UINT64_C(1) << f)) != 0;
298 } 298 }
299 // Check whether a feature is currently enabled. 299 // Check whether a feature is currently enabled.
300 static bool IsEnabled(Feature f) { 300 static bool IsEnabled(Feature f) {
301 return (enabled_ & (static_cast<uint64_t>(1) << f)) != 0; 301 return (enabled_ & (V8_UINT64_C(1) << f)) != 0;
302 } 302 }
303 // Enable a specified feature within a scope. 303 // Enable a specified feature within a scope.
304 class Scope BASE_EMBEDDED { 304 class Scope BASE_EMBEDDED {
305 #ifdef DEBUG 305 #ifdef DEBUG
306 public: 306 public:
307 explicit Scope(Feature f) { 307 explicit Scope(Feature f) {
308 ASSERT(CpuFeatures::IsSupported(f)); 308 ASSERT(CpuFeatures::IsSupported(f));
309 old_enabled_ = CpuFeatures::enabled_; 309 old_enabled_ = CpuFeatures::enabled_;
310 CpuFeatures::enabled_ |= (static_cast<uint64_t>(1) << f); 310 CpuFeatures::enabled_ |= (V8_UINT64_C(1) << f);
311 } 311 }
312 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } 312 ~Scope() { CpuFeatures::enabled_ = old_enabled_; }
313 private: 313 private:
314 uint64_t old_enabled_; 314 uint64_t old_enabled_;
315 #else 315 #else
316 public: 316 public:
317 explicit Scope(Feature f) {} 317 explicit Scope(Feature f) {}
318 #endif 318 #endif
319 }; 319 };
320 private: 320 private:
(...skipping 27 matching lines...) Expand all
348 // upon destruction of the assembler. 348 // upon destruction of the assembler.
349 Assembler(void* buffer, int buffer_size); 349 Assembler(void* buffer, int buffer_size);
350 ~Assembler(); 350 ~Assembler();
351 351
352 // GetCode emits any pending (non-emitted) code and fills the descriptor 352 // GetCode emits any pending (non-emitted) code and fills the descriptor
353 // desc. GetCode() is idempotent; it returns the same result if no other 353 // desc. GetCode() is idempotent; it returns the same result if no other
354 // Assembler functions are invoked in between GetCode() calls. 354 // Assembler functions are invoked in between GetCode() calls.
355 void GetCode(CodeDesc* desc); 355 void GetCode(CodeDesc* desc);
356 356
357 // Read/Modify the code target in the branch/call instruction at pc. 357 // Read/Modify the code target in the branch/call instruction at pc.
358 inline static Address target_address_at(Address pc); 358 // On the x64 architecture, the address is absolute, not relative.
359 inline static void set_target_address_at(Address pc, Address target); 359 static inline Address target_address_at(Address pc);
360 static inline void set_target_address_at(Address pc, Address target);
360 361
361 // Distance between the address of the code target in the call instruction 362 // Distance between the address of the code target in the call instruction
362 // and the return address 363 // and the return address
363 static const int kTargetAddrToReturnAddrDist = kPointerSize; 364 static const int kTargetAddrToReturnAddrDist = kPointerSize;
364 365
365 366
366 // --------------------------------------------------------------------------- 367 // ---------------------------------------------------------------------------
367 // Code generation 368 // Code generation
368 // 369 //
369 // Function names correspond one-to-one to x64 instruction mnemonics. 370 // Function names correspond one-to-one to x64 instruction mnemonics.
(...skipping 10 matching lines...) Expand all
380 // 381 //
381 // Some mnemonics, such as "and", are the same as C++ keywords. 382 // Some mnemonics, such as "and", are the same as C++ keywords.
382 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. 383 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'.
383 384
384 // Insert the smallest number of nop instructions 385 // Insert the smallest number of nop instructions
385 // possible to align the pc offset to a multiple 386 // possible to align the pc offset to a multiple
386 // of m. m must be a power of 2. 387 // of m. m must be a power of 2.
387 void Align(int m); 388 void Align(int m);
388 389
389 // Stack 390 // Stack
390 void pushad(); 391 void pushfq();
391 void popad(); 392 void popfq();
392 393
393 void pushfd(); 394 void push(Immediate value);
394 void popfd();
395
396 void push(const Immediate& x);
397 void push(Register src); 395 void push(Register src);
398 void push(const Operand& src); 396 void push(const Operand& src);
399 void push(Label* label, RelocInfo::Mode relocation_mode); 397 void push(Label* label, RelocInfo::Mode relocation_mode);
400 398
401 void pop(Register dst); 399 void pop(Register dst);
402 void pop(const Operand& dst); 400 void pop(const Operand& dst);
403 401
404 void enter(const Immediate& size); 402 void enter(Immediate size);
405 void leave(); 403 void leave();
406 404
407 // Moves 405 // Moves
408 void movb(Register dst, const Operand& src); 406 void movb(Register dst, const Operand& src);
409 void movb(const Operand& dst, int8_t imm8); 407 void movb(const Operand& dst, int8_t imm8);
410 void movb(const Operand& dst, Register src); 408 void movb(const Operand& dst, Register src);
411 409
410 void movl(Register dst, Register src);
411 void movl(Register dst, const Operand& src);
412 void movl(const Operand& dst, Register src);
413
412 void movq(Register dst, int32_t imm32); 414 void movq(Register dst, int32_t imm32);
413 void movq(Register dst, Immediate x); 415 void movq(Register dst, Immediate x);
414 void movq(Register dst, const Operand& src); 416 void movq(Register dst, const Operand& src);
415 void movq(Register dst, Register src); 417 void movq(Register dst, Register src);
416 void movq(const Operand& dst, const Immediate& x); 418 void movq(const Operand& dst, const Immediate& x);
417 void movq(const Operand& dst, Register src); 419 void movq(const Operand& dst, Register src);
418 420
419 // New x64 instructions to load a 64-bit immediate into a register. 421 // New x64 instructions to load a 64-bit immediate into a register.
420 // All 64-bit immediates must have a relocation mode. 422 // All 64-bit immediates must have a relocation mode.
421 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); 423 void movq(Register dst, void* ptr, RelocInfo::Mode rmode);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 void cmpb(const Operand& op, int8_t imm8); 510 void cmpb(const Operand& op, int8_t imm8);
509 void cmpb_al(const Operand& op); 511 void cmpb_al(const Operand& op);
510 void cmpw_ax(const Operand& op); 512 void cmpw_ax(const Operand& op);
511 void cmpw(const Operand& op, Immediate imm16); 513 void cmpw(const Operand& op, Immediate imm16);
512 514
513 void dec_b(Register dst); 515 void dec_b(Register dst);
514 516
515 void dec(Register dst); 517 void dec(Register dst);
516 void dec(const Operand& dst); 518 void dec(const Operand& dst);
517 519
518 void cdq(); 520 // Sign-extends rax into rdx:rax.
521 void cqo();
519 522
520 void idiv(Register src); 523 void idiv(Register src);
521 524
522 void imul(Register dst, const Operand& src); 525 void imul(Register dst, const Operand& src);
523 void imul(Register dst, Register src, int32_t imm32); 526 void imul(Register dst, Register src, int32_t imm32);
524 527
525 void inc(Register dst); 528 void inc(Register dst);
526 void inc(const Operand& dst); 529 void inc(const Operand& dst);
527 530
528 void lea(Register dst, const Operand& src); 531 void lea(Register dst, const Operand& src);
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; 826 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
824 } 827 }
825 828
826 // code emission 829 // code emission
827 void GrowBuffer(); 830 void GrowBuffer();
828 831
829 void emit(byte x) { *pc_++ = x; } 832 void emit(byte x) { *pc_++ = x; }
830 inline void emitl(uint32_t x); 833 inline void emitl(uint32_t x);
831 inline void emit(Handle<Object> handle); 834 inline void emit(Handle<Object> handle);
832 inline void emitq(uint64_t x, RelocInfo::Mode rmode); 835 inline void emitq(uint64_t x, RelocInfo::Mode rmode);
836 inline void emitw(uint16_t x);
833 void emit(Immediate x) { emitl(x.value_); } 837 void emit(Immediate x) { emitl(x.value_); }
834 838
835 // Emits a REX prefix that encodes a 64-bit operand size and 839 // Emits a REX prefix that encodes a 64-bit operand size and
836 // the top bit of both register codes. 840 // the top bit of both register codes.
837 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 841 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
838 // REX.W is set. 842 // REX.W is set.
839 inline void emit_rex_64(Register reg, Register rm_reg); 843 inline void emit_rex_64(Register reg, Register rm_reg);
840 844
841 // Emits a REX prefix that encodes a 64-bit operand size and 845 // Emits a REX prefix that encodes a 64-bit operand size and
842 // the top bit of the destination, index, and base register codes. 846 // the top bit of the destination, index, and base register codes.
843 // The high bit of reg is used for REX.R, the high bit of op's base 847 // The high bit of reg is used for REX.R, the high bit of op's base
844 // register is used for REX.B, and the high bit of op's index register 848 // register is used for REX.B, and the high bit of op's index register
845 // is used for REX.X. REX.W is set. 849 // is used for REX.X. REX.W is set.
846 inline void emit_rex_64(Register reg, const Operand& op); 850 inline void emit_rex_64(Register reg, const Operand& op);
847 851
848 // Emits a REX prefix that encodes a 64-bit operand size and 852 // Emits a REX prefix that encodes a 64-bit operand size and
849 // the top bit of the register code. 853 // the top bit of the register code.
850 // The high bit of register is used for REX.B. 854 // The high bit of register is used for REX.B.
851 // REX.W is set and REX.R and REX.X are clear. 855 // REX.W is set and REX.R and REX.X are clear.
852 inline void emit_rex_64(Register rm_reg); 856 inline void emit_rex_64(Register rm_reg);
853 857
854 // Emits a REX prefix that encodes a 64-bit operand size and 858 // Emits a REX prefix that encodes a 64-bit operand size and
855 // the top bit of the index and base register codes. 859 // the top bit of the index and base register codes.
856 // The high bit of op's base register is used for REX.B, and the high 860 // The high bit of op's base register is used for REX.B, and the high
857 // bit of op's index register is used for REX.X. 861 // bit of op's index register is used for REX.X.
858 // REX.W is set and REX.R clear. 862 // REX.W is set and REX.R clear.
859 inline void emit_rex_64(const Operand& op); 863 inline void emit_rex_64(const Operand& op);
860 864
865 // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
866 void emit_rex_64() { emit(0x48); }
867
861 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 868 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
862 // REX.W is clear. 869 // REX.W is clear.
863 inline void emit_rex_32(Register reg, Register rm_reg); 870 inline void emit_rex_32(Register reg, Register rm_reg);
864 871
865 // The high bit of reg is used for REX.R, the high bit of op's base 872 // The high bit of reg is used for REX.R, the high bit of op's base
866 // register is used for REX.B, and the high bit of op's index register 873 // register is used for REX.B, and the high bit of op's index register
867 // is used for REX.X. REX.W is cleared. 874 // is used for REX.X. REX.W is cleared.
868 inline void emit_rex_32(Register reg, const Operand& op); 875 inline void emit_rex_32(Register reg, const Operand& op);
869 876
870 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. 877 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 private: 973 private:
967 Assembler* assembler_; 974 Assembler* assembler_;
968 #ifdef DEBUG 975 #ifdef DEBUG
969 int space_before_; 976 int space_before_;
970 #endif 977 #endif
971 }; 978 };
972 979
973 } } // namespace v8::internal 980 } } // namespace v8::internal
974 981
975 #endif // V8_X64_ASSEMBLER_X64_H_ 982 #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