TargetInstrInfo.td 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // This test describes how we eventually want to describe instructions in
  2. // the target independent code generators.
  3. // RUN: llvm-tblgen %s
  4. // XFAIL: vg_leak
  5. // Target indep stuff.
  6. class Instruction { // Would have other stuff eventually
  7. bit isTwoAddress = 0;
  8. string AssemblyString;
  9. }
  10. class RegisterClass;
  11. class RTLNode;
  12. def ops; // Marker for operand list.
  13. // Various expressions used in RTL descriptions.
  14. def imm8 : RTLNode;
  15. def imm32 : RTLNode;
  16. def addr : RTLNode;
  17. def set : RTLNode;
  18. def signext : RTLNode;
  19. def zeroext : RTLNode;
  20. def plus : RTLNode;
  21. def and : RTLNode;
  22. def xor : RTLNode;
  23. def shl : RTLNode;
  24. def load : RTLNode;
  25. def store : RTLNode;
  26. def unspec : RTLNode;
  27. // Start of X86 specific stuff.
  28. def R8 : RegisterClass;
  29. def R16 : RegisterClass;
  30. def R32 : RegisterClass;
  31. def CL; // As are currently defined
  32. def AL;
  33. def AX;
  34. def EDX;
  35. class Format<bits<5> val> {
  36. bits<5> Value = val;
  37. }
  38. def Pseudo : Format<0>; def RawFrm : Format<1>;
  39. def AddRegFrm : Format<2>; def MRMDestReg : Format<3>;
  40. def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
  41. def MRMSrcMem : Format<6>;
  42. def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
  43. def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
  44. def MRM6r : Format<22>; def MRM7r : Format<23>;
  45. def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
  46. def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
  47. def MRM6m : Format<30>; def MRM7m : Format<31>;
  48. class Inst<dag opnds, string asmstr, bits<8> opcode,
  49. Format f, list<dag> rtl> : Instruction {
  50. dag Operands = opnds;
  51. string AssemblyString = asmstr;
  52. bits<8> Opcode = opcode;
  53. Format Format = f;
  54. list<dag> RTL = rtl;
  55. }
  56. // Start of instruction definitions, the real point of this file.
  57. //
  58. // Note that these patterns show a couple of important things:
  59. // 1. The order and contents of the operands of the MachineInstr are
  60. // described here. Eventually we can do away with this when everything
  61. // is generated from the description.
  62. // 2. The asm string is captured here, which makes it possible to get rid of
  63. // a ton of hacks in the various printers and a bunch of flags.
  64. // 3. Target specific properties (e.g. Format) can still be captured as
  65. // needed.
  66. // 4. We capture the behavior of the instruction with a simplified RTL-like
  67. // expression.
  68. // 5. The use/def properties for each operand are automatically inferred from
  69. // the pattern.
  70. // 6. Address expressions should become first-class entities.
  71. // Simple copy instruction.
  72. def MOV8rr : Inst<(ops R8:$dst, R8:$src),
  73. "mov $dst, $src", 0x88, MRMDestReg,
  74. [(set R8:$dst, R8:$src)]>;
  75. // Simple immediate initialization.
  76. def MOV8ri : Inst<(ops R8:$dst, imm8:$src),
  77. "mov $dst, $src", 0xB0, AddRegFrm,
  78. [(set R8:$dst, imm8:$src)]>;
  79. // Two address instructions are described as three-addr instructions, with
  80. // the special target-independent isTwoAddress flag set. The asm pattern
  81. // should not refer to the $src1, this would be enforced by the
  82. // TargetInstrInfo tablegen backend.
  83. let isTwoAddress = 1 in
  84. def AND8rr : Inst<(ops R8:$dst, R8:$src1, R8:$src2),
  85. "and $dst, $src2", 0x20, MRMDestReg,
  86. [(set R8:$dst, (and R8:$src1, R8:$src2))]>;
  87. // Instructions that have explicit uses/defs make them explicit in the RTL.
  88. // Instructions that need extra stuff emitted in the assembly can, trivially.
  89. let isTwoAddress = 1 in
  90. def SHL32rCL : Inst<(ops R32:$dst, R32:$src),
  91. "shl $dst, CL", 0xD2, MRM4r,
  92. [(set R32:$dst, (shl R32:$src, CL))]>;
  93. // The RTL list is a list, allowing complex instructions to be defined easily.
  94. // Temporary 'internal' registers can be used to break instructions apart.
  95. let isTwoAddress = 1 in
  96. def XOR32mi : Inst<(ops addr:$addr, imm32:$imm),
  97. "xor $dst, $src2", 0x81, MRM6m,
  98. [(set R32:$tmp1, (load addr:$addr)),
  99. (set R32:$tmp2, (xor R32:$tmp1, imm32:$imm)),
  100. (store addr:$addr, R32:$tmp2)]>;
  101. // Alternatively, if each tmporary register is only used once, the instruction
  102. // can just be described in nested form. This would be the canonical
  103. // representation the target generator would convert the above into. Pick your
  104. // favorite indentation scheme.
  105. let isTwoAddress = 1 in
  106. def AND32mr : Inst<(ops addr:$addr, R32:$src),
  107. "xor $dst, $src2", 0x81, MRM6m,
  108. [(store addr:$addr,
  109. (and
  110. (load addr:$addr),
  111. R32:$src)
  112. )
  113. ]>;
  114. // Describing complex instructions is not too hard! Note how implicit uses/defs
  115. // become explicit here.
  116. def CBW : Inst<(ops),
  117. "cbw", 0x98, RawFrm,
  118. [(set AX, (signext AL))]>;
  119. // Noop, does nothing.
  120. def NOOP : Inst<(ops), "nop", 0x90, RawFrm, []>;
  121. // Instructions that don't expect optimization can use unspec.
  122. def IN8rr : Inst<(ops), "in AL, EDX", 0xEC, RawFrm,
  123. [(set AL, (unspec EDX))]>;