OLD | NEW |
1 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ------*- C++ -*-===// | 1 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ------*- C++ -*-===// |
2 // | 2 // |
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
6 // | 6 // |
7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
8 // | 8 // |
9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
10 // | 10 // |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 #include "assembler.h" | 32 #include "assembler.h" |
33 | 33 |
34 namespace Ice { | 34 namespace Ice { |
35 | 35 |
36 using RegX8632::GPRRegister; | 36 using RegX8632::GPRRegister; |
37 using RegX8632::XmmRegister; | 37 using RegX8632::XmmRegister; |
38 using RegX8632::ByteRegister; | 38 using RegX8632::ByteRegister; |
39 using RegX8632::X87STRegister; | 39 using RegX8632::X87STRegister; |
40 | 40 |
41 namespace x86 { | 41 namespace X8632 { |
42 | 42 |
43 const int MAX_NOP_SIZE = 8; | 43 const int MAX_NOP_SIZE = 8; |
44 | 44 |
45 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; | 45 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
46 | 46 |
47 class Immediate { | 47 class Immediate { |
48 Immediate(const Immediate &) = delete; | 48 Immediate(const Immediate &) = delete; |
49 Immediate &operator=(const Immediate &) = delete; | 49 Immediate &operator=(const Immediate &) = delete; |
50 | 50 |
51 public: | 51 public: |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 return encoding_[index]; | 163 return encoding_[index]; |
164 } | 164 } |
165 | 165 |
166 // Returns whether or not this operand is really the given register in | 166 // Returns whether or not this operand is really the given register in |
167 // disguise. Used from the assembler to generate better encodings. | 167 // disguise. Used from the assembler to generate better encodings. |
168 bool IsRegister(GPRRegister reg) const { | 168 bool IsRegister(GPRRegister reg) const { |
169 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. | 169 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. |
170 && ((encoding_[0] & 0x07) == reg); // Register codes match. | 170 && ((encoding_[0] & 0x07) == reg); // Register codes match. |
171 } | 171 } |
172 | 172 |
173 friend class AssemblerX86; | 173 friend class AssemblerX8632; |
174 }; | 174 }; |
175 | 175 |
176 class Address : public Operand { | 176 class Address : public Operand { |
177 public: | 177 public: |
178 Address(const Address &other) : Operand(other) {} | 178 Address(const Address &other) : Operand(other) {} |
179 | 179 |
180 Address &operator=(const Address &other) { | 180 Address &operator=(const Address &other) { |
181 Operand::operator=(other); | 181 Operand::operator=(other); |
182 return *this; | 182 return *this; |
183 } | 183 } |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 } | 323 } |
324 | 324 |
325 static const int kMaxUnresolvedBranches = 20; | 325 static const int kMaxUnresolvedBranches = 20; |
326 | 326 |
327 intptr_t position_; | 327 intptr_t position_; |
328 intptr_t num_unresolved_; | 328 intptr_t num_unresolved_; |
329 // TODO(stichnot,jvoung): Can this instead be | 329 // TODO(stichnot,jvoung): Can this instead be |
330 // llvm::SmallVector<intptr_t, kMaxUnresolvedBranches> ? | 330 // llvm::SmallVector<intptr_t, kMaxUnresolvedBranches> ? |
331 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; | 331 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; |
332 | 332 |
333 friend class AssemblerX86; | 333 friend class AssemblerX8632; |
334 }; | 334 }; |
335 | 335 |
336 class AssemblerX86 : public Assembler { | 336 class AssemblerX8632 : public Assembler { |
337 AssemblerX86(const AssemblerX86 &) = delete; | 337 AssemblerX8632(const AssemblerX8632 &) = delete; |
338 AssemblerX86 &operator=(const AssemblerX86 &) = delete; | 338 AssemblerX8632 &operator=(const AssemblerX8632 &) = delete; |
339 | 339 |
340 public: | 340 public: |
341 explicit AssemblerX86(bool use_far_branches = false) : Assembler() { | 341 explicit AssemblerX8632(bool use_far_branches = false) : Assembler() { |
342 // This mode is only needed and implemented for MIPS and ARM. | 342 // This mode is only needed and implemented for MIPS and ARM. |
343 assert(!use_far_branches); | 343 assert(!use_far_branches); |
344 (void)use_far_branches; | 344 (void)use_far_branches; |
345 } | 345 } |
346 ~AssemblerX86() override; | 346 ~AssemblerX8632() override; |
347 | 347 |
348 static const bool kNearJump = true; | 348 static const bool kNearJump = true; |
349 static const bool kFarJump = false; | 349 static const bool kFarJump = false; |
350 | 350 |
351 void alignFunction() override; | 351 void alignFunction() override; |
352 | 352 |
353 SizeT getBundleAlignLog2Bytes() const override { return 5; } | 353 SizeT getBundleAlignLog2Bytes() const override { return 5; } |
354 | 354 |
355 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { | 355 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { |
356 static const uint8_t Padding[] = {0xF4}; | 356 static const uint8_t Padding[] = {0xF4}; |
(...skipping 13 matching lines...) Expand all Loading... |
370 void BindCfgNodeLabel(SizeT NodeNumber) override; | 370 void BindCfgNodeLabel(SizeT NodeNumber) override; |
371 Label *GetOrCreateLocalLabel(SizeT Number); | 371 Label *GetOrCreateLocalLabel(SizeT Number); |
372 void BindLocalLabel(SizeT Number); | 372 void BindLocalLabel(SizeT Number); |
373 | 373 |
374 bool fixupIsPCRel(FixupKind Kind) const override { | 374 bool fixupIsPCRel(FixupKind Kind) const override { |
375 // Currently assuming this is the only PC-rel relocation type used. | 375 // Currently assuming this is the only PC-rel relocation type used. |
376 return Kind == llvm::ELF::R_386_PC32; | 376 return Kind == llvm::ELF::R_386_PC32; |
377 } | 377 } |
378 | 378 |
379 // Operations to emit GPR instructions (and dispatch on operand type). | 379 // Operations to emit GPR instructions (and dispatch on operand type). |
380 typedef void (AssemblerX86::*TypedEmitGPR)(Type, GPRRegister); | 380 typedef void (AssemblerX8632::*TypedEmitGPR)(Type, GPRRegister); |
381 typedef void (AssemblerX86::*TypedEmitAddr)(Type, const Address &); | 381 typedef void (AssemblerX8632::*TypedEmitAddr)(Type, const Address &); |
382 struct GPREmitterOneOp { | 382 struct GPREmitterOneOp { |
383 TypedEmitGPR Reg; | 383 TypedEmitGPR Reg; |
384 TypedEmitAddr Addr; | 384 TypedEmitAddr Addr; |
385 }; | 385 }; |
386 | 386 |
387 typedef void (AssemblerX86::*TypedEmitGPRGPR)(Type, GPRRegister, GPRRegister); | 387 typedef void (AssemblerX8632::*TypedEmitGPRGPR)(Type, GPRRegister, |
388 typedef void (AssemblerX86::*TypedEmitGPRAddr)(Type, GPRRegister, | 388 GPRRegister); |
389 const Address &); | 389 typedef void (AssemblerX8632::*TypedEmitGPRAddr)(Type, GPRRegister, |
390 typedef void (AssemblerX86::*TypedEmitGPRImm)(Type, GPRRegister, | 390 const Address &); |
391 const Immediate &); | 391 typedef void (AssemblerX8632::*TypedEmitGPRImm)(Type, GPRRegister, |
| 392 const Immediate &); |
392 struct GPREmitterRegOp { | 393 struct GPREmitterRegOp { |
393 TypedEmitGPRGPR GPRGPR; | 394 TypedEmitGPRGPR GPRGPR; |
394 TypedEmitGPRAddr GPRAddr; | 395 TypedEmitGPRAddr GPRAddr; |
395 TypedEmitGPRImm GPRImm; | 396 TypedEmitGPRImm GPRImm; |
396 }; | 397 }; |
397 | 398 |
398 struct GPREmitterShiftOp { | 399 struct GPREmitterShiftOp { |
399 // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are not. | 400 // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are not. |
400 // In practice, we always normalize the Dest to a Register first. | 401 // In practice, we always normalize the Dest to a Register first. |
401 TypedEmitGPRGPR GPRGPR; | 402 TypedEmitGPRGPR GPRGPR; |
402 TypedEmitGPRImm GPRImm; | 403 TypedEmitGPRImm GPRImm; |
403 }; | 404 }; |
404 | 405 |
405 typedef void (AssemblerX86::*TypedEmitGPRGPRImm)(Type, GPRRegister, | 406 typedef void (AssemblerX8632::*TypedEmitGPRGPRImm)(Type, GPRRegister, |
406 GPRRegister, | 407 GPRRegister, |
407 const Immediate &); | 408 const Immediate &); |
408 struct GPREmitterShiftD { | 409 struct GPREmitterShiftD { |
409 // Technically AddrGPR and AddrGPRImm are also allowed, but in practice | 410 // Technically AddrGPR and AddrGPRImm are also allowed, but in practice |
410 // we always normalize Dest to a Register first. | 411 // we always normalize Dest to a Register first. |
411 TypedEmitGPRGPR GPRGPR; | 412 TypedEmitGPRGPR GPRGPR; |
412 TypedEmitGPRGPRImm GPRGPRImm; | 413 TypedEmitGPRGPRImm GPRGPRImm; |
413 }; | 414 }; |
414 | 415 |
415 typedef void (AssemblerX86::*TypedEmitAddrGPR)(Type, const Address &, | 416 typedef void (AssemblerX8632::*TypedEmitAddrGPR)(Type, const Address &, |
416 GPRRegister); | 417 GPRRegister); |
417 typedef void (AssemblerX86::*TypedEmitAddrImm)(Type, const Address &, | 418 typedef void (AssemblerX8632::*TypedEmitAddrImm)(Type, const Address &, |
418 const Immediate &); | 419 const Immediate &); |
419 struct GPREmitterAddrOp { | 420 struct GPREmitterAddrOp { |
420 TypedEmitAddrGPR AddrGPR; | 421 TypedEmitAddrGPR AddrGPR; |
421 TypedEmitAddrImm AddrImm; | 422 TypedEmitAddrImm AddrImm; |
422 }; | 423 }; |
423 | 424 |
424 // Operations to emit XMM instructions (and dispatch on operand type). | 425 // Operations to emit XMM instructions (and dispatch on operand type). |
425 typedef void (AssemblerX86::*TypedEmitXmmXmm)(Type, XmmRegister, XmmRegister); | 426 typedef void (AssemblerX8632::*TypedEmitXmmXmm)(Type, XmmRegister, |
426 typedef void (AssemblerX86::*TypedEmitXmmAddr)(Type, XmmRegister, | 427 XmmRegister); |
427 const Address &); | 428 typedef void (AssemblerX8632::*TypedEmitXmmAddr)(Type, XmmRegister, |
| 429 const Address &); |
428 struct XmmEmitterRegOp { | 430 struct XmmEmitterRegOp { |
429 TypedEmitXmmXmm XmmXmm; | 431 TypedEmitXmmXmm XmmXmm; |
430 TypedEmitXmmAddr XmmAddr; | 432 TypedEmitXmmAddr XmmAddr; |
431 }; | 433 }; |
432 | 434 |
433 typedef void (AssemblerX86::*EmitXmmXmm)(XmmRegister, XmmRegister); | 435 typedef void (AssemblerX8632::*EmitXmmXmm)(XmmRegister, XmmRegister); |
434 typedef void (AssemblerX86::*EmitXmmAddr)(XmmRegister, const Address &); | 436 typedef void (AssemblerX8632::*EmitXmmAddr)(XmmRegister, const Address &); |
435 typedef void (AssemblerX86::*EmitAddrXmm)(const Address &, XmmRegister); | 437 typedef void (AssemblerX8632::*EmitAddrXmm)(const Address &, XmmRegister); |
436 struct XmmEmitterMovOps { | 438 struct XmmEmitterMovOps { |
437 EmitXmmXmm XmmXmm; | 439 EmitXmmXmm XmmXmm; |
438 EmitXmmAddr XmmAddr; | 440 EmitXmmAddr XmmAddr; |
439 EmitAddrXmm AddrXmm; | 441 EmitAddrXmm AddrXmm; |
440 }; | 442 }; |
441 | 443 |
442 typedef void (AssemblerX86::*TypedEmitXmmImm)(Type, XmmRegister, | 444 typedef void (AssemblerX8632::*TypedEmitXmmImm)(Type, XmmRegister, |
443 const Immediate &); | 445 const Immediate &); |
444 | 446 |
445 struct XmmEmitterShiftOp { | 447 struct XmmEmitterShiftOp { |
446 TypedEmitXmmXmm XmmXmm; | 448 TypedEmitXmmXmm XmmXmm; |
447 TypedEmitXmmAddr XmmAddr; | 449 TypedEmitXmmAddr XmmAddr; |
448 TypedEmitXmmImm XmmImm; | 450 TypedEmitXmmImm XmmImm; |
449 }; | 451 }; |
450 | 452 |
451 // Cross Xmm/GPR cast instructions. | 453 // Cross Xmm/GPR cast instructions. |
452 template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp { | 454 template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp { |
453 typedef void (AssemblerX86::*TypedEmitRegs)(Type, DReg_t, SReg_t); | 455 typedef void (AssemblerX8632::*TypedEmitRegs)(Type, DReg_t, SReg_t); |
454 typedef void (AssemblerX86::*TypedEmitAddr)(Type, DReg_t, const Address &); | 456 typedef void (AssemblerX8632::*TypedEmitAddr)(Type, DReg_t, |
| 457 const Address &); |
455 | 458 |
456 TypedEmitRegs RegReg; | 459 TypedEmitRegs RegReg; |
457 TypedEmitAddr RegAddr; | 460 TypedEmitAddr RegAddr; |
458 }; | 461 }; |
459 | 462 |
460 // Three operand (potentially) cross Xmm/GPR instructions. | 463 // Three operand (potentially) cross Xmm/GPR instructions. |
461 // The last operand must be an immediate. | 464 // The last operand must be an immediate. |
462 template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter { | 465 template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter { |
463 typedef void (AssemblerX86::*TypedEmitRegRegImm)(Type, DReg_t, SReg_t, | 466 typedef void (AssemblerX8632::*TypedEmitRegRegImm)(Type, DReg_t, SReg_t, |
464 const Immediate &); | 467 const Immediate &); |
465 typedef void (AssemblerX86::*TypedEmitRegAddrImm)(Type, DReg_t, | 468 typedef void (AssemblerX8632::*TypedEmitRegAddrImm)(Type, DReg_t, |
466 const Address &, | 469 const Address &, |
467 const Immediate &); | 470 const Immediate &); |
468 | 471 |
469 TypedEmitRegRegImm RegRegImm; | 472 TypedEmitRegRegImm RegRegImm; |
470 TypedEmitRegAddrImm RegAddrImm; | 473 TypedEmitRegAddrImm RegAddrImm; |
471 }; | 474 }; |
472 | 475 |
473 /* | 476 /* |
474 * Emit Machine Instructions. | 477 * Emit Machine Instructions. |
475 */ | 478 */ |
476 void call(GPRRegister reg); | 479 void call(GPRRegister reg); |
477 void call(const Address &address); | 480 void call(const Address &address); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 | 849 |
847 typedef std::vector<Label *> LabelVector; | 850 typedef std::vector<Label *> LabelVector; |
848 // A vector of pool-allocated x86 labels for CFG nodes. | 851 // A vector of pool-allocated x86 labels for CFG nodes. |
849 LabelVector CfgNodeLabels; | 852 LabelVector CfgNodeLabels; |
850 // A vector of pool-allocated x86 labels for Local labels. | 853 // A vector of pool-allocated x86 labels for Local labels. |
851 LabelVector LocalLabels; | 854 LabelVector LocalLabels; |
852 | 855 |
853 Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels); | 856 Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels); |
854 }; | 857 }; |
855 | 858 |
856 inline void AssemblerX86::EmitUint8(uint8_t value) { | 859 inline void AssemblerX8632::EmitUint8(uint8_t value) { |
857 buffer_.Emit<uint8_t>(value); | 860 buffer_.Emit<uint8_t>(value); |
858 } | 861 } |
859 | 862 |
860 inline void AssemblerX86::EmitInt16(int16_t value) { | 863 inline void AssemblerX8632::EmitInt16(int16_t value) { |
861 buffer_.Emit<int16_t>(value); | 864 buffer_.Emit<int16_t>(value); |
862 } | 865 } |
863 | 866 |
864 inline void AssemblerX86::EmitInt32(int32_t value) { | 867 inline void AssemblerX8632::EmitInt32(int32_t value) { |
865 buffer_.Emit<int32_t>(value); | 868 buffer_.Emit<int32_t>(value); |
866 } | 869 } |
867 | 870 |
868 inline void AssemblerX86::EmitRegisterOperand(int rm, int reg) { | 871 inline void AssemblerX8632::EmitRegisterOperand(int rm, int reg) { |
869 assert(rm >= 0 && rm < 8); | 872 assert(rm >= 0 && rm < 8); |
870 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg); | 873 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg); |
871 } | 874 } |
872 | 875 |
873 inline void AssemblerX86::EmitXmmRegisterOperand(int rm, XmmRegister reg) { | 876 inline void AssemblerX8632::EmitXmmRegisterOperand(int rm, XmmRegister reg) { |
874 EmitRegisterOperand(rm, static_cast<GPRRegister>(reg)); | 877 EmitRegisterOperand(rm, static_cast<GPRRegister>(reg)); |
875 } | 878 } |
876 | 879 |
877 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) { | 880 inline void AssemblerX8632::EmitFixup(AssemblerFixup *fixup) { |
878 buffer_.EmitFixup(fixup); | 881 buffer_.EmitFixup(fixup); |
879 } | 882 } |
880 | 883 |
881 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); } | 884 inline void AssemblerX8632::EmitOperandSizeOverride() { EmitUint8(0x66); } |
882 | 885 |
883 } // end of namespace x86 | 886 } // end of namespace X8632 |
884 } // end of namespace Ice | 887 } // end of namespace Ice |
885 | 888 |
886 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H | 889 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H |
OLD | NEW |