/3rd_party/llvm/lib/Target/X86/X86InstrArithmetic.td

https://code.google.com/p/softart/ · Unknown · 1395 lines · 1248 code · 147 blank · 0 comment · 0 complexity · e7802e0f7cd11df209074edc0307cabd MD5 · raw file

  1. //===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file describes the integer arithmetic instructions in the X86
  11. // architecture.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. //===----------------------------------------------------------------------===//
  15. // LEA - Load Effective Address
  16. let SchedRW = [WriteLEA] in {
  17. let neverHasSideEffects = 1 in
  18. def LEA16r : I<0x8D, MRMSrcMem,
  19. (outs GR16:$dst), (ins i32mem:$src),
  20. "lea{w}\t{$src|$dst}, {$dst|$src}", [], IIC_LEA_16>, OpSize;
  21. let isReMaterializable = 1 in
  22. def LEA32r : I<0x8D, MRMSrcMem,
  23. (outs GR32:$dst), (ins i32mem:$src),
  24. "lea{l}\t{$src|$dst}, {$dst|$src}",
  25. [(set GR32:$dst, lea32addr:$src)], IIC_LEA>,
  26. Requires<[In32BitMode]>;
  27. def LEA64_32r : I<0x8D, MRMSrcMem,
  28. (outs GR32:$dst), (ins lea64_32mem:$src),
  29. "lea{l}\t{$src|$dst}, {$dst|$src}",
  30. [(set GR32:$dst, lea64_32addr:$src)], IIC_LEA>,
  31. Requires<[In64BitMode]>;
  32. let isReMaterializable = 1 in
  33. def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
  34. "lea{q}\t{$src|$dst}, {$dst|$src}",
  35. [(set GR64:$dst, lea64addr:$src)], IIC_LEA>;
  36. } // SchedRW
  37. //===----------------------------------------------------------------------===//
  38. // Fixed-Register Multiplication and Division Instructions.
  39. //
  40. // SchedModel info for instruction that loads one value and gets the second
  41. // (and possibly third) value from a register.
  42. // This is used for instructions that put the memory operands before other
  43. // uses.
  44. class SchedLoadReg<SchedWrite SW> : Sched<[SW,
  45. // Memory operand.
  46. ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
  47. // Register reads (implicit or explicit).
  48. ReadAfterLd, ReadAfterLd]>;
  49. // Extra precision multiplication
  50. // AL is really implied by AX, but the registers in Defs must match the
  51. // SDNode results (i8, i32).
  52. // AL,AH = AL*GR8
  53. let Defs = [AL,EFLAGS,AX], Uses = [AL] in
  54. def MUL8r : I<0xF6, MRM4r, (outs), (ins GR8:$src), "mul{b}\t$src",
  55. // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
  56. // This probably ought to be moved to a def : Pat<> if the
  57. // syntax can be accepted.
  58. [(set AL, (mul AL, GR8:$src)),
  59. (implicit EFLAGS)], IIC_MUL8>, Sched<[WriteIMul]>;
  60. // AX,DX = AX*GR16
  61. let Defs = [AX,DX,EFLAGS], Uses = [AX], neverHasSideEffects = 1 in
  62. def MUL16r : I<0xF7, MRM4r, (outs), (ins GR16:$src),
  63. "mul{w}\t$src",
  64. [], IIC_MUL16_REG>, OpSize, Sched<[WriteIMul]>;
  65. // EAX,EDX = EAX*GR32
  66. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], neverHasSideEffects = 1 in
  67. def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src),
  68. "mul{l}\t$src",
  69. [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/],
  70. IIC_MUL32_REG>, Sched<[WriteIMul]>;
  71. // RAX,RDX = RAX*GR64
  72. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in
  73. def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
  74. "mul{q}\t$src",
  75. [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/],
  76. IIC_MUL64>, Sched<[WriteIMul]>;
  77. // AL,AH = AL*[mem8]
  78. let Defs = [AL,EFLAGS,AX], Uses = [AL] in
  79. def MUL8m : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
  80. "mul{b}\t$src",
  81. // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
  82. // This probably ought to be moved to a def : Pat<> if the
  83. // syntax can be accepted.
  84. [(set AL, (mul AL, (loadi8 addr:$src))),
  85. (implicit EFLAGS)], IIC_MUL8>, SchedLoadReg<WriteIMulLd>;
  86. // AX,DX = AX*[mem16]
  87. let mayLoad = 1, neverHasSideEffects = 1 in {
  88. let Defs = [AX,DX,EFLAGS], Uses = [AX] in
  89. def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
  90. "mul{w}\t$src",
  91. [], IIC_MUL16_MEM>, OpSize, SchedLoadReg<WriteIMulLd>;
  92. // EAX,EDX = EAX*[mem32]
  93. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
  94. def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
  95. "mul{l}\t$src",
  96. [], IIC_MUL32_MEM>, SchedLoadReg<WriteIMulLd>;
  97. // RAX,RDX = RAX*[mem64]
  98. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
  99. def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
  100. "mul{q}\t$src", [], IIC_MUL64>, SchedLoadReg<WriteIMulLd>;
  101. }
  102. let neverHasSideEffects = 1 in {
  103. // AL,AH = AL*GR8
  104. let Defs = [AL,EFLAGS,AX], Uses = [AL] in
  105. def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", [],
  106. IIC_IMUL8>, Sched<[WriteIMul]>;
  107. // AX,DX = AX*GR16
  108. let Defs = [AX,DX,EFLAGS], Uses = [AX] in
  109. def IMUL16r : I<0xF7, MRM5r, (outs), (ins GR16:$src), "imul{w}\t$src", [],
  110. IIC_IMUL16_RR>, OpSize, Sched<[WriteIMul]>;
  111. // EAX,EDX = EAX*GR32
  112. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
  113. def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", [],
  114. IIC_IMUL32_RR>, Sched<[WriteIMul]>;
  115. // RAX,RDX = RAX*GR64
  116. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
  117. def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", [],
  118. IIC_IMUL64_RR>, Sched<[WriteIMul]>;
  119. let mayLoad = 1 in {
  120. // AL,AH = AL*[mem8]
  121. let Defs = [AL,EFLAGS,AX], Uses = [AL] in
  122. def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
  123. "imul{b}\t$src", [], IIC_IMUL8>, SchedLoadReg<WriteIMulLd>;
  124. // AX,DX = AX*[mem16]
  125. let Defs = [AX,DX,EFLAGS], Uses = [AX] in
  126. def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
  127. "imul{w}\t$src", [], IIC_IMUL16_MEM>, OpSize,
  128. SchedLoadReg<WriteIMulLd>;
  129. // EAX,EDX = EAX*[mem32]
  130. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
  131. def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
  132. "imul{l}\t$src", [], IIC_IMUL32_MEM>, SchedLoadReg<WriteIMulLd>;
  133. // RAX,RDX = RAX*[mem64]
  134. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
  135. def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
  136. "imul{q}\t$src", [], IIC_IMUL64>, SchedLoadReg<WriteIMulLd>;
  137. }
  138. } // neverHasSideEffects
  139. let Defs = [EFLAGS] in {
  140. let Constraints = "$src1 = $dst" in {
  141. let isCommutable = 1, SchedRW = [WriteIMul] in {
  142. // X = IMUL Y, Z --> X = IMUL Z, Y
  143. // Register-Register Signed Integer Multiply
  144. def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
  145. "imul{w}\t{$src2, $dst|$dst, $src2}",
  146. [(set GR16:$dst, EFLAGS,
  147. (X86smul_flag GR16:$src1, GR16:$src2))], IIC_IMUL16_RR>,
  148. TB, OpSize;
  149. def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
  150. "imul{l}\t{$src2, $dst|$dst, $src2}",
  151. [(set GR32:$dst, EFLAGS,
  152. (X86smul_flag GR32:$src1, GR32:$src2))], IIC_IMUL32_RR>,
  153. TB;
  154. def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
  155. (ins GR64:$src1, GR64:$src2),
  156. "imul{q}\t{$src2, $dst|$dst, $src2}",
  157. [(set GR64:$dst, EFLAGS,
  158. (X86smul_flag GR64:$src1, GR64:$src2))], IIC_IMUL64_RR>,
  159. TB;
  160. } // isCommutable, SchedRW
  161. // Register-Memory Signed Integer Multiply
  162. let SchedRW = [WriteIMulLd, ReadAfterLd] in {
  163. def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
  164. (ins GR16:$src1, i16mem:$src2),
  165. "imul{w}\t{$src2, $dst|$dst, $src2}",
  166. [(set GR16:$dst, EFLAGS,
  167. (X86smul_flag GR16:$src1, (load addr:$src2)))],
  168. IIC_IMUL16_RM>,
  169. TB, OpSize;
  170. def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
  171. (ins GR32:$src1, i32mem:$src2),
  172. "imul{l}\t{$src2, $dst|$dst, $src2}",
  173. [(set GR32:$dst, EFLAGS,
  174. (X86smul_flag GR32:$src1, (load addr:$src2)))],
  175. IIC_IMUL32_RM>,
  176. TB;
  177. def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
  178. (ins GR64:$src1, i64mem:$src2),
  179. "imul{q}\t{$src2, $dst|$dst, $src2}",
  180. [(set GR64:$dst, EFLAGS,
  181. (X86smul_flag GR64:$src1, (load addr:$src2)))],
  182. IIC_IMUL64_RM>,
  183. TB;
  184. } // SchedRW
  185. } // Constraints = "$src1 = $dst"
  186. } // Defs = [EFLAGS]
  187. // Surprisingly enough, these are not two address instructions!
  188. let Defs = [EFLAGS] in {
  189. let SchedRW = [WriteIMul] in {
  190. // Register-Integer Signed Integer Multiply
  191. def IMUL16rri : Ii16<0x69, MRMSrcReg, // GR16 = GR16*I16
  192. (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
  193. "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  194. [(set GR16:$dst, EFLAGS,
  195. (X86smul_flag GR16:$src1, imm:$src2))],
  196. IIC_IMUL16_RRI>, OpSize;
  197. def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // GR16 = GR16*I8
  198. (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
  199. "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  200. [(set GR16:$dst, EFLAGS,
  201. (X86smul_flag GR16:$src1, i16immSExt8:$src2))],
  202. IIC_IMUL16_RRI>,
  203. OpSize;
  204. def IMUL32rri : Ii32<0x69, MRMSrcReg, // GR32 = GR32*I32
  205. (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
  206. "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  207. [(set GR32:$dst, EFLAGS,
  208. (X86smul_flag GR32:$src1, imm:$src2))],
  209. IIC_IMUL32_RRI>;
  210. def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // GR32 = GR32*I8
  211. (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
  212. "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  213. [(set GR32:$dst, EFLAGS,
  214. (X86smul_flag GR32:$src1, i32immSExt8:$src2))],
  215. IIC_IMUL32_RRI>;
  216. def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32
  217. (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
  218. "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  219. [(set GR64:$dst, EFLAGS,
  220. (X86smul_flag GR64:$src1, i64immSExt32:$src2))],
  221. IIC_IMUL64_RRI>;
  222. def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
  223. (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
  224. "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  225. [(set GR64:$dst, EFLAGS,
  226. (X86smul_flag GR64:$src1, i64immSExt8:$src2))],
  227. IIC_IMUL64_RRI>;
  228. } // SchedRW
  229. // Memory-Integer Signed Integer Multiply
  230. let SchedRW = [WriteIMulLd] in {
  231. def IMUL16rmi : Ii16<0x69, MRMSrcMem, // GR16 = [mem16]*I16
  232. (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2),
  233. "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  234. [(set GR16:$dst, EFLAGS,
  235. (X86smul_flag (load addr:$src1), imm:$src2))],
  236. IIC_IMUL16_RMI>,
  237. OpSize;
  238. def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // GR16 = [mem16]*I8
  239. (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2),
  240. "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  241. [(set GR16:$dst, EFLAGS,
  242. (X86smul_flag (load addr:$src1),
  243. i16immSExt8:$src2))], IIC_IMUL16_RMI>,
  244. OpSize;
  245. def IMUL32rmi : Ii32<0x69, MRMSrcMem, // GR32 = [mem32]*I32
  246. (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2),
  247. "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  248. [(set GR32:$dst, EFLAGS,
  249. (X86smul_flag (load addr:$src1), imm:$src2))],
  250. IIC_IMUL32_RMI>;
  251. def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // GR32 = [mem32]*I8
  252. (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
  253. "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  254. [(set GR32:$dst, EFLAGS,
  255. (X86smul_flag (load addr:$src1),
  256. i32immSExt8:$src2))],
  257. IIC_IMUL32_RMI>;
  258. def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32
  259. (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
  260. "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  261. [(set GR64:$dst, EFLAGS,
  262. (X86smul_flag (load addr:$src1),
  263. i64immSExt32:$src2))],
  264. IIC_IMUL64_RMI>;
  265. def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
  266. (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
  267. "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
  268. [(set GR64:$dst, EFLAGS,
  269. (X86smul_flag (load addr:$src1),
  270. i64immSExt8:$src2))],
  271. IIC_IMUL64_RMI>;
  272. } // SchedRW
  273. } // Defs = [EFLAGS]
  274. // unsigned division/remainder
  275. let hasSideEffects = 1 in { // so that we don't speculatively execute
  276. let SchedRW = [WriteIDiv] in {
  277. let Defs = [AL,AH,EFLAGS], Uses = [AX] in
  278. def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
  279. "div{b}\t$src", [], IIC_DIV8_REG>;
  280. let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
  281. def DIV16r : I<0xF7, MRM6r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
  282. "div{w}\t$src", [], IIC_DIV16>, OpSize;
  283. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
  284. def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
  285. "div{l}\t$src", [], IIC_DIV32>;
  286. // RDX:RAX/r64 = RAX,RDX
  287. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
  288. def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
  289. "div{q}\t$src", [], IIC_DIV64>;
  290. } // SchedRW
  291. let mayLoad = 1 in {
  292. let Defs = [AL,AH,EFLAGS], Uses = [AX] in
  293. def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
  294. "div{b}\t$src", [], IIC_DIV8_MEM>,
  295. SchedLoadReg<WriteIDivLd>;
  296. let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
  297. def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
  298. "div{w}\t$src", [], IIC_DIV16>, OpSize,
  299. SchedLoadReg<WriteIDivLd>;
  300. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX
  301. def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
  302. "div{l}\t$src", [], IIC_DIV32>,
  303. SchedLoadReg<WriteIDivLd>;
  304. // RDX:RAX/[mem64] = RAX,RDX
  305. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
  306. def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
  307. "div{q}\t$src", [], IIC_DIV64>,
  308. SchedLoadReg<WriteIDivLd>;
  309. }
  310. // Signed division/remainder.
  311. let SchedRW = [WriteIDiv] in {
  312. let Defs = [AL,AH,EFLAGS], Uses = [AX] in
  313. def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
  314. "idiv{b}\t$src", [], IIC_IDIV8>;
  315. let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
  316. def IDIV16r: I<0xF7, MRM7r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
  317. "idiv{w}\t$src", [], IIC_IDIV16>, OpSize;
  318. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
  319. def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
  320. "idiv{l}\t$src", [], IIC_IDIV32>;
  321. // RDX:RAX/r64 = RAX,RDX
  322. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
  323. def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
  324. "idiv{q}\t$src", [], IIC_IDIV64>;
  325. } // SchedRW
  326. let mayLoad = 1 in {
  327. let Defs = [AL,AH,EFLAGS], Uses = [AX] in
  328. def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
  329. "idiv{b}\t$src", [], IIC_IDIV8>,
  330. SchedLoadReg<WriteIDivLd>;
  331. let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
  332. def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
  333. "idiv{w}\t$src", [], IIC_IDIV16>, OpSize,
  334. SchedLoadReg<WriteIDivLd>;
  335. let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in // EDX:EAX/[mem32] = EAX,EDX
  336. def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
  337. "idiv{l}\t$src", [], IIC_IDIV32>,
  338. SchedLoadReg<WriteIDivLd>;
  339. let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
  340. def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
  341. "idiv{q}\t$src", [], IIC_IDIV64>,
  342. SchedLoadReg<WriteIDivLd>;
  343. }
  344. } // hasSideEffects = 0
  345. //===----------------------------------------------------------------------===//
  346. // Two address Instructions.
  347. //
  348. // unary instructions
  349. let CodeSize = 2 in {
  350. let Defs = [EFLAGS] in {
  351. let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
  352. def NEG8r : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1),
  353. "neg{b}\t$dst",
  354. [(set GR8:$dst, (ineg GR8:$src1)),
  355. (implicit EFLAGS)], IIC_UNARY_REG>;
  356. def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
  357. "neg{w}\t$dst",
  358. [(set GR16:$dst, (ineg GR16:$src1)),
  359. (implicit EFLAGS)], IIC_UNARY_REG>, OpSize;
  360. def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
  361. "neg{l}\t$dst",
  362. [(set GR32:$dst, (ineg GR32:$src1)),
  363. (implicit EFLAGS)], IIC_UNARY_REG>;
  364. def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst",
  365. [(set GR64:$dst, (ineg GR64:$src1)),
  366. (implicit EFLAGS)], IIC_UNARY_REG>;
  367. } // Constraints = "$src1 = $dst", SchedRW
  368. // Read-modify-write negate.
  369. let SchedRW = [WriteALULd, WriteRMW] in {
  370. def NEG8m : I<0xF6, MRM3m, (outs), (ins i8mem :$dst),
  371. "neg{b}\t$dst",
  372. [(store (ineg (loadi8 addr:$dst)), addr:$dst),
  373. (implicit EFLAGS)], IIC_UNARY_MEM>;
  374. def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst),
  375. "neg{w}\t$dst",
  376. [(store (ineg (loadi16 addr:$dst)), addr:$dst),
  377. (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize;
  378. def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst),
  379. "neg{l}\t$dst",
  380. [(store (ineg (loadi32 addr:$dst)), addr:$dst),
  381. (implicit EFLAGS)], IIC_UNARY_MEM>;
  382. def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
  383. [(store (ineg (loadi64 addr:$dst)), addr:$dst),
  384. (implicit EFLAGS)], IIC_UNARY_MEM>;
  385. } // SchedRW
  386. } // Defs = [EFLAGS]
  387. // Note: NOT does not set EFLAGS!
  388. let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
  389. // Match xor -1 to not. Favors these over a move imm + xor to save code size.
  390. let AddedComplexity = 15 in {
  391. def NOT8r : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1),
  392. "not{b}\t$dst",
  393. [(set GR8:$dst, (not GR8:$src1))], IIC_UNARY_REG>;
  394. def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
  395. "not{w}\t$dst",
  396. [(set GR16:$dst, (not GR16:$src1))], IIC_UNARY_REG>, OpSize;
  397. def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
  398. "not{l}\t$dst",
  399. [(set GR32:$dst, (not GR32:$src1))], IIC_UNARY_REG>;
  400. def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst",
  401. [(set GR64:$dst, (not GR64:$src1))], IIC_UNARY_REG>;
  402. }
  403. } // Constraints = "$src1 = $dst", SchedRW
  404. let SchedRW = [WriteALULd, WriteRMW] in {
  405. def NOT8m : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
  406. "not{b}\t$dst",
  407. [(store (not (loadi8 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
  408. def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst),
  409. "not{w}\t$dst",
  410. [(store (not (loadi16 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
  411. OpSize;
  412. def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst),
  413. "not{l}\t$dst",
  414. [(store (not (loadi32 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
  415. def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
  416. [(store (not (loadi64 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
  417. } // SchedRW
  418. } // CodeSize
  419. // TODO: inc/dec is slow for P4, but fast for Pentium-M.
  420. let Defs = [EFLAGS] in {
  421. let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
  422. let CodeSize = 2 in
  423. def INC8r : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
  424. "inc{b}\t$dst",
  425. [(set GR8:$dst, EFLAGS, (X86inc_flag GR8:$src1))],
  426. IIC_UNARY_REG>;
  427. let isConvertibleToThreeAddress = 1, CodeSize = 1 in { // Can xform into LEA.
  428. def INC16r : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
  429. "inc{w}\t$dst",
  430. [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))], IIC_UNARY_REG>,
  431. OpSize, Requires<[In32BitMode]>;
  432. def INC32r : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
  433. "inc{l}\t$dst",
  434. [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))],
  435. IIC_UNARY_REG>,
  436. Requires<[In32BitMode]>;
  437. def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
  438. [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src1))],
  439. IIC_UNARY_REG>;
  440. } // isConvertibleToThreeAddress = 1, CodeSize = 1
  441. // In 64-bit mode, single byte INC and DEC cannot be encoded.
  442. let isConvertibleToThreeAddress = 1, CodeSize = 2 in {
  443. // Can transform into LEA.
  444. def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
  445. "inc{w}\t$dst",
  446. [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))],
  447. IIC_UNARY_REG>,
  448. OpSize, Requires<[In64BitMode]>;
  449. def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
  450. "inc{l}\t$dst",
  451. [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))],
  452. IIC_UNARY_REG>,
  453. Requires<[In64BitMode]>;
  454. def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
  455. "dec{w}\t$dst",
  456. [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))],
  457. IIC_UNARY_REG>,
  458. OpSize, Requires<[In64BitMode]>;
  459. def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
  460. "dec{l}\t$dst",
  461. [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))],
  462. IIC_UNARY_REG>,
  463. Requires<[In64BitMode]>;
  464. } // isConvertibleToThreeAddress = 1, CodeSize = 2
  465. let isCodeGenOnly = 1, CodeSize = 2 in {
  466. def INC32_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
  467. "inc{w}\t$dst", [], IIC_UNARY_REG>,
  468. OpSize, Requires<[In32BitMode]>;
  469. def INC32_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
  470. "inc{l}\t$dst", [], IIC_UNARY_REG>,
  471. Requires<[In32BitMode]>;
  472. def DEC32_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
  473. "dec{w}\t$dst", [], IIC_UNARY_REG>,
  474. OpSize, Requires<[In32BitMode]>;
  475. def DEC32_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
  476. "dec{l}\t$dst", [], IIC_UNARY_REG>,
  477. Requires<[In32BitMode]>;
  478. } // isCodeGenOnly = 1, CodeSize = 2
  479. } // Constraints = "$src1 = $dst", SchedRW
  480. let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
  481. def INC8m : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
  482. [(store (add (loadi8 addr:$dst), 1), addr:$dst),
  483. (implicit EFLAGS)], IIC_UNARY_MEM>;
  484. def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
  485. [(store (add (loadi16 addr:$dst), 1), addr:$dst),
  486. (implicit EFLAGS)], IIC_UNARY_MEM>,
  487. OpSize, Requires<[In32BitMode]>;
  488. def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
  489. [(store (add (loadi32 addr:$dst), 1), addr:$dst),
  490. (implicit EFLAGS)], IIC_UNARY_MEM>,
  491. Requires<[In32BitMode]>;
  492. def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
  493. [(store (add (loadi64 addr:$dst), 1), addr:$dst),
  494. (implicit EFLAGS)], IIC_UNARY_MEM>;
  495. // These are duplicates of their 32-bit counterparts. Only needed so X86 knows
  496. // how to unfold them.
  497. // FIXME: What is this for??
  498. def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
  499. [(store (add (loadi16 addr:$dst), 1), addr:$dst),
  500. (implicit EFLAGS)], IIC_UNARY_MEM>,
  501. OpSize, Requires<[In64BitMode]>;
  502. def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
  503. [(store (add (loadi32 addr:$dst), 1), addr:$dst),
  504. (implicit EFLAGS)], IIC_UNARY_MEM>,
  505. Requires<[In64BitMode]>;
  506. def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
  507. [(store (add (loadi16 addr:$dst), -1), addr:$dst),
  508. (implicit EFLAGS)], IIC_UNARY_MEM>,
  509. OpSize, Requires<[In64BitMode]>;
  510. def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
  511. [(store (add (loadi32 addr:$dst), -1), addr:$dst),
  512. (implicit EFLAGS)], IIC_UNARY_MEM>,
  513. Requires<[In64BitMode]>;
  514. } // CodeSize = 2, SchedRW
  515. let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
  516. let CodeSize = 2 in
  517. def DEC8r : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
  518. "dec{b}\t$dst",
  519. [(set GR8:$dst, EFLAGS, (X86dec_flag GR8:$src1))],
  520. IIC_UNARY_REG>;
  521. let isConvertibleToThreeAddress = 1, CodeSize = 1 in { // Can xform into LEA.
  522. def DEC16r : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
  523. "dec{w}\t$dst",
  524. [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))],
  525. IIC_UNARY_REG>,
  526. OpSize, Requires<[In32BitMode]>;
  527. def DEC32r : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
  528. "dec{l}\t$dst",
  529. [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))],
  530. IIC_UNARY_REG>,
  531. Requires<[In32BitMode]>;
  532. def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
  533. [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src1))],
  534. IIC_UNARY_REG>;
  535. } // CodeSize = 2
  536. } // Constraints = "$src1 = $dst", SchedRW
  537. let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
  538. def DEC8m : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
  539. [(store (add (loadi8 addr:$dst), -1), addr:$dst),
  540. (implicit EFLAGS)], IIC_UNARY_MEM>;
  541. def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
  542. [(store (add (loadi16 addr:$dst), -1), addr:$dst),
  543. (implicit EFLAGS)], IIC_UNARY_MEM>,
  544. OpSize, Requires<[In32BitMode]>;
  545. def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
  546. [(store (add (loadi32 addr:$dst), -1), addr:$dst),
  547. (implicit EFLAGS)], IIC_UNARY_MEM>,
  548. Requires<[In32BitMode]>;
  549. def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
  550. [(store (add (loadi64 addr:$dst), -1), addr:$dst),
  551. (implicit EFLAGS)], IIC_UNARY_MEM>;
  552. } // CodeSize = 2, SchedRW
  553. } // Defs = [EFLAGS]
  554. /// X86TypeInfo - This is a bunch of information that describes relevant X86
  555. /// information about value types. For example, it can tell you what the
  556. /// register class and preferred load to use.
  557. class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
  558. PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
  559. Operand immoperand, SDPatternOperator immoperator,
  560. Operand imm8operand, SDPatternOperator imm8operator,
  561. bit hasOddOpcode, bit hasOpSizePrefix, bit hasREX_WPrefix> {
  562. /// VT - This is the value type itself.
  563. ValueType VT = vt;
  564. /// InstrSuffix - This is the suffix used on instructions with this type. For
  565. /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
  566. string InstrSuffix = instrsuffix;
  567. /// RegClass - This is the register class associated with this type. For
  568. /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
  569. RegisterClass RegClass = regclass;
  570. /// LoadNode - This is the load node associated with this type. For
  571. /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
  572. PatFrag LoadNode = loadnode;
  573. /// MemOperand - This is the memory operand associated with this type. For
  574. /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
  575. X86MemOperand MemOperand = memoperand;
  576. /// ImmEncoding - This is the encoding of an immediate of this type. For
  577. /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32. Note that i64 -> Imm32
  578. /// since the immediate fields of i64 instructions is a 32-bit sign extended
  579. /// value.
  580. ImmType ImmEncoding = immkind;
  581. /// ImmOperand - This is the operand kind of an immediate of this type. For
  582. /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm. Note that i64 ->
  583. /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
  584. /// extended value.
  585. Operand ImmOperand = immoperand;
  586. /// ImmOperator - This is the operator that should be used to match an
  587. /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
  588. SDPatternOperator ImmOperator = immoperator;
  589. /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
  590. /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm. This is
  591. /// only used for instructions that have a sign-extended imm8 field form.
  592. Operand Imm8Operand = imm8operand;
  593. /// Imm8Operator - This is the operator that should be used to match an 8-bit
  594. /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
  595. SDPatternOperator Imm8Operator = imm8operator;
  596. /// HasOddOpcode - This bit is true if the instruction should have an odd (as
  597. /// opposed to even) opcode. Operations on i8 are usually even, operations on
  598. /// other datatypes are odd.
  599. bit HasOddOpcode = hasOddOpcode;
  600. /// HasOpSizePrefix - This bit is set to true if the instruction should have
  601. /// the 0x66 operand size prefix. This is set for i16 types.
  602. bit HasOpSizePrefix = hasOpSizePrefix;
  603. /// HasREX_WPrefix - This bit is set to true if the instruction should have
  604. /// the 0x40 REX prefix. This is set for i64 types.
  605. bit HasREX_WPrefix = hasREX_WPrefix;
  606. }
  607. def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
  608. def Xi8 : X86TypeInfo<i8 , "b", GR8 , loadi8 , i8mem ,
  609. Imm8 , i8imm , imm, i8imm , invalid_node,
  610. 0, 0, 0>;
  611. def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
  612. Imm16, i16imm, imm, i16i8imm, i16immSExt8,
  613. 1, 1, 0>;
  614. def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
  615. Imm32, i32imm, imm, i32i8imm, i32immSExt8,
  616. 1, 0, 0>;
  617. def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
  618. Imm32, i64i32imm, i64immSExt32, i64i8imm, i64immSExt8,
  619. 1, 0, 1>;
  620. /// ITy - This instruction base class takes the type info for the instruction.
  621. /// Using this, it:
  622. /// 1. Concatenates together the instruction mnemonic with the appropriate
  623. /// suffix letter, a tab, and the arguments.
  624. /// 2. Infers whether the instruction should have a 0x66 prefix byte.
  625. /// 3. Infers whether the instruction should have a 0x40 REX_W prefix.
  626. /// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations)
  627. /// or 1 (for i16,i32,i64 operations).
  628. class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
  629. string mnemonic, string args, list<dag> pattern,
  630. InstrItinClass itin = IIC_BIN_NONMEM>
  631. : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4},
  632. opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode },
  633. f, outs, ins,
  634. !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern,
  635. itin> {
  636. // Infer instruction prefixes from type info.
  637. let hasOpSizePrefix = typeinfo.HasOpSizePrefix;
  638. let hasREX_WPrefix = typeinfo.HasREX_WPrefix;
  639. }
  640. // BinOpRR - Instructions like "add reg, reg, reg".
  641. class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  642. dag outlist, list<dag> pattern, InstrItinClass itin,
  643. Format f = MRMDestReg>
  644. : ITy<opcode, f, typeinfo, outlist,
  645. (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
  646. mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
  647. Sched<[WriteALU]>;
  648. // BinOpRR_R - Instructions like "add reg, reg, reg", where the pattern has
  649. // just a regclass (no eflags) as a result.
  650. class BinOpRR_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  651. SDNode opnode>
  652. : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
  653. [(set typeinfo.RegClass:$dst,
  654. (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
  655. IIC_BIN_NONMEM>;
  656. // BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
  657. // just a EFLAGS as a result.
  658. class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  659. SDPatternOperator opnode, Format f = MRMDestReg>
  660. : BinOpRR<opcode, mnemonic, typeinfo, (outs),
  661. [(set EFLAGS,
  662. (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
  663. IIC_BIN_NONMEM, f>;
  664. // BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
  665. // both a regclass and EFLAGS as a result.
  666. class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  667. SDNode opnode>
  668. : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
  669. [(set typeinfo.RegClass:$dst, EFLAGS,
  670. (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
  671. IIC_BIN_NONMEM>;
  672. // BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
  673. // both a regclass and EFLAGS as a result, and has EFLAGS as input.
  674. class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  675. SDNode opnode>
  676. : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
  677. [(set typeinfo.RegClass:$dst, EFLAGS,
  678. (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
  679. EFLAGS))], IIC_BIN_CARRY_NONMEM>;
  680. // BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
  681. class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  682. InstrItinClass itin = IIC_BIN_NONMEM>
  683. : ITy<opcode, MRMSrcReg, typeinfo,
  684. (outs typeinfo.RegClass:$dst),
  685. (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
  686. mnemonic, "{$src2, $dst|$dst, $src2}", [], itin>,
  687. Sched<[WriteALU]> {
  688. // The disassembler should know about this, but not the asmparser.
  689. let isCodeGenOnly = 1;
  690. let hasSideEffects = 0;
  691. }
  692. // BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
  693. class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
  694. : BinOpRR_Rev<opcode, mnemonic, typeinfo, IIC_BIN_CARRY_NONMEM>;
  695. // BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
  696. class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
  697. : ITy<opcode, MRMSrcReg, typeinfo, (outs),
  698. (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
  699. mnemonic, "{$src2, $src1|$src1, $src2}", [], IIC_BIN_NONMEM>,
  700. Sched<[WriteALU]> {
  701. // The disassembler should know about this, but not the asmparser.
  702. let isCodeGenOnly = 1;
  703. let hasSideEffects = 0;
  704. }
  705. // BinOpRM - Instructions like "add reg, reg, [mem]".
  706. class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  707. dag outlist, list<dag> pattern,
  708. InstrItinClass itin = IIC_BIN_MEM>
  709. : ITy<opcode, MRMSrcMem, typeinfo, outlist,
  710. (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
  711. mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
  712. Sched<[WriteALULd, ReadAfterLd]>;
  713. // BinOpRM_R - Instructions like "add reg, reg, [mem]".
  714. class BinOpRM_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  715. SDNode opnode>
  716. : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
  717. [(set typeinfo.RegClass:$dst,
  718. (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
  719. // BinOpRM_F - Instructions like "cmp reg, [mem]".
  720. class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  721. SDPatternOperator opnode>
  722. : BinOpRM<opcode, mnemonic, typeinfo, (outs),
  723. [(set EFLAGS,
  724. (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
  725. // BinOpRM_RF - Instructions like "add reg, reg, [mem]".
  726. class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  727. SDNode opnode>
  728. : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
  729. [(set typeinfo.RegClass:$dst, EFLAGS,
  730. (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
  731. // BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
  732. class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  733. SDNode opnode>
  734. : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
  735. [(set typeinfo.RegClass:$dst, EFLAGS,
  736. (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
  737. EFLAGS))], IIC_BIN_CARRY_MEM>;
  738. // BinOpRI - Instructions like "add reg, reg, imm".
  739. class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  740. Format f, dag outlist, list<dag> pattern,
  741. InstrItinClass itin = IIC_BIN_NONMEM>
  742. : ITy<opcode, f, typeinfo, outlist,
  743. (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
  744. mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
  745. Sched<[WriteALU]> {
  746. let ImmT = typeinfo.ImmEncoding;
  747. }
  748. // BinOpRI_R - Instructions like "add reg, reg, imm".
  749. class BinOpRI_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  750. SDNode opnode, Format f>
  751. : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
  752. [(set typeinfo.RegClass:$dst,
  753. (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
  754. // BinOpRI_F - Instructions like "cmp reg, imm".
  755. class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  756. SDPatternOperator opnode, Format f>
  757. : BinOpRI<opcode, mnemonic, typeinfo, f, (outs),
  758. [(set EFLAGS,
  759. (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
  760. // BinOpRI_RF - Instructions like "add reg, reg, imm".
  761. class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  762. SDNode opnode, Format f>
  763. : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
  764. [(set typeinfo.RegClass:$dst, EFLAGS,
  765. (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
  766. // BinOpRI_RFF - Instructions like "adc reg, reg, imm".
  767. class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  768. SDNode opnode, Format f>
  769. : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
  770. [(set typeinfo.RegClass:$dst, EFLAGS,
  771. (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
  772. EFLAGS))], IIC_BIN_CARRY_NONMEM>;
  773. // BinOpRI8 - Instructions like "add reg, reg, imm8".
  774. class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  775. Format f, dag outlist, list<dag> pattern,
  776. InstrItinClass itin = IIC_BIN_NONMEM>
  777. : ITy<opcode, f, typeinfo, outlist,
  778. (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
  779. mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
  780. Sched<[WriteALU]> {
  781. let ImmT = Imm8; // Always 8-bit immediate.
  782. }
  783. // BinOpRI8_R - Instructions like "add reg, reg, imm8".
  784. class BinOpRI8_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  785. SDNode opnode, Format f>
  786. : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
  787. [(set typeinfo.RegClass:$dst,
  788. (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
  789. // BinOpRI8_F - Instructions like "cmp reg, imm8".
  790. class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  791. SDNode opnode, Format f>
  792. : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs),
  793. [(set EFLAGS,
  794. (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
  795. // BinOpRI8_RF - Instructions like "add reg, reg, imm8".
  796. class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  797. SDNode opnode, Format f>
  798. : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
  799. [(set typeinfo.RegClass:$dst, EFLAGS,
  800. (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
  801. // BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
  802. class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  803. SDNode opnode, Format f>
  804. : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
  805. [(set typeinfo.RegClass:$dst, EFLAGS,
  806. (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
  807. EFLAGS))], IIC_BIN_CARRY_NONMEM>;
  808. // BinOpMR - Instructions like "add [mem], reg".
  809. class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  810. list<dag> pattern, InstrItinClass itin = IIC_BIN_MEM>
  811. : ITy<opcode, MRMDestMem, typeinfo,
  812. (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
  813. mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
  814. Sched<[WriteALULd, WriteRMW]>;
  815. // BinOpMR_RMW - Instructions like "add [mem], reg".
  816. class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  817. SDNode opnode>
  818. : BinOpMR<opcode, mnemonic, typeinfo,
  819. [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
  820. (implicit EFLAGS)]>;
  821. // BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
  822. class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  823. SDNode opnode>
  824. : BinOpMR<opcode, mnemonic, typeinfo,
  825. [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
  826. addr:$dst),
  827. (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
  828. // BinOpMR_F - Instructions like "cmp [mem], reg".
  829. class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  830. SDNode opnode>
  831. : BinOpMR<opcode, mnemonic, typeinfo,
  832. [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>;
  833. // BinOpMI - Instructions like "add [mem], imm".
  834. class BinOpMI<string mnemonic, X86TypeInfo typeinfo,
  835. Format f, list<dag> pattern, bits<8> opcode = 0x80,
  836. InstrItinClass itin = IIC_BIN_MEM>
  837. : ITy<opcode, f, typeinfo,
  838. (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
  839. mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
  840. Sched<[WriteALULd, WriteRMW]> {
  841. let ImmT = typeinfo.ImmEncoding;
  842. }
  843. // BinOpMI_RMW - Instructions like "add [mem], imm".
  844. class BinOpMI_RMW<string mnemonic, X86TypeInfo typeinfo,
  845. SDNode opnode, Format f>
  846. : BinOpMI<mnemonic, typeinfo, f,
  847. [(store (opnode (typeinfo.VT (load addr:$dst)),
  848. typeinfo.ImmOperator:$src), addr:$dst),
  849. (implicit EFLAGS)]>;
  850. // BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
  851. class BinOpMI_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
  852. SDNode opnode, Format f>
  853. : BinOpMI<mnemonic, typeinfo, f,
  854. [(store (opnode (typeinfo.VT (load addr:$dst)),
  855. typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
  856. (implicit EFLAGS)], 0x80, IIC_BIN_CARRY_MEM>;
  857. // BinOpMI_F - Instructions like "cmp [mem], imm".
  858. class BinOpMI_F<string mnemonic, X86TypeInfo typeinfo,
  859. SDPatternOperator opnode, Format f, bits<8> opcode = 0x80>
  860. : BinOpMI<mnemonic, typeinfo, f,
  861. [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)),
  862. typeinfo.ImmOperator:$src))],
  863. opcode>;
  864. // BinOpMI8 - Instructions like "add [mem], imm8".
  865. class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
  866. Format f, list<dag> pattern,
  867. InstrItinClass itin = IIC_BIN_MEM>
  868. : ITy<0x82, f, typeinfo,
  869. (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
  870. mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
  871. Sched<[WriteALULd, WriteRMW]> {
  872. let ImmT = Imm8; // Always 8-bit immediate.
  873. }
  874. // BinOpMI8_RMW - Instructions like "add [mem], imm8".
  875. class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
  876. SDNode opnode, Format f>
  877. : BinOpMI8<mnemonic, typeinfo, f,
  878. [(store (opnode (load addr:$dst),
  879. typeinfo.Imm8Operator:$src), addr:$dst),
  880. (implicit EFLAGS)]>;
  881. // BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
  882. class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
  883. SDNode opnode, Format f>
  884. : BinOpMI8<mnemonic, typeinfo, f,
  885. [(store (opnode (load addr:$dst),
  886. typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
  887. (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
  888. // BinOpMI8_F - Instructions like "cmp [mem], imm8".
  889. class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
  890. SDNode opnode, Format f>
  891. : BinOpMI8<mnemonic, typeinfo, f,
  892. [(set EFLAGS, (opnode (load addr:$dst),
  893. typeinfo.Imm8Operator:$src))]>;
  894. // BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
  895. class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  896. Register areg, string operands,
  897. InstrItinClass itin = IIC_BIN_NONMEM>
  898. : ITy<opcode, RawFrm, typeinfo,
  899. (outs), (ins typeinfo.ImmOperand:$src),
  900. mnemonic, operands, [], itin>, Sched<[WriteALU]> {
  901. let ImmT = typeinfo.ImmEncoding;
  902. let Uses = [areg];
  903. let Defs = [areg, EFLAGS];
  904. let hasSideEffects = 0;
  905. }
  906. // BinOpAI_FF - Instructions like "adc %eax, %eax, imm", that implicitly define
  907. // and use EFLAGS.
  908. class BinOpAI_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
  909. Register areg, string operands>
  910. : BinOpAI<opcode, mnemonic, typeinfo, areg, operands,
  911. IIC_BIN_CARRY_NONMEM> {
  912. let Uses = [areg, EFLAGS];
  913. }
  914. /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
  915. /// defined with "(set GPR:$dst, EFLAGS, (...".
  916. ///
  917. /// It would be nice to get rid of the second and third argument here, but
  918. /// tblgen can't handle dependent type references aggressively enough: PR8330
  919. multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
  920. string mnemonic, Format RegMRM, Format MemMRM,
  921. SDNode opnodeflag, SDNode opnode,
  922. bit CommutableRR, bit ConvertibleToThreeAddress> {
  923. let Defs = [EFLAGS] in {
  924. let Constraints = "$src1 = $dst" in {
  925. let isCommutable = CommutableRR,
  926. isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
  927. def NAME#8rr : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
  928. def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
  929. def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
  930. def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
  931. } // isCommutable
  932. def NAME#8rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>;
  933. def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>;
  934. def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>;
  935. def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>;
  936. def NAME#8rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
  937. def NAME#16rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
  938. def NAME#32rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
  939. def NAME#64rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
  940. let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
  941. // NOTE: These are order specific, we want the ri8 forms to be listed
  942. // first so that they are slightly preferred to the ri forms.
  943. def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
  944. def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
  945. def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
  946. def NAME#8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
  947. def NAME#16ri : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
  948. def NAME#32ri : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
  949. def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
  950. }
  951. } // Constraints = "$src1 = $dst"
  952. def NAME#8mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
  953. def NAME#16mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
  954. def NAME#32mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
  955. def NAME#64mr : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
  956. // NOTE: These are order specific, we want the mi8 forms to be listed
  957. // first so that they are slightly preferred to the mi forms.
  958. def NAME#16mi8 : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
  959. def NAME#32mi8 : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
  960. def NAME#64mi8 : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
  961. def NAME#8mi : BinOpMI_RMW<mnemonic, Xi8 , opnode, MemMRM>;
  962. def NAME#16mi : BinOpMI_RMW<mnemonic, Xi16, opnode, MemMRM>;
  963. def NAME#32mi : BinOpMI_RMW<mnemonic, Xi32, opnode, MemMRM>;
  964. def NAME#64mi32 : BinOpMI_RMW<mnemonic, Xi64, opnode, MemMRM>;
  965. } // Defs = [EFLAGS]
  966. def NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
  967. "{$src, %al|al, $src}">;
  968. def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
  969. "{$src, %ax|ax, $src}">;
  970. def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
  971. "{$src, %eax|eax, $src}">;
  972. def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
  973. "{$src, %rax|rax, $src}">;
  974. }
  975. /// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
  976. /// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
  977. /// SBB.
  978. ///
  979. /// It would be nice to get rid of the second and third argument here, but
  980. /// tblgen can't handle dependent type references aggressively enough: PR8330
  981. multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
  982. string mnemonic, Format RegMRM, Format MemMRM,
  983. SDNode opnode, bit CommutableRR,
  984. bit ConvertibleToThreeAddress> {
  985. let Uses = [EFLAGS], Defs = [EFLAGS] in {
  986. let Constraints = "$src1 = $dst" in {
  987. let isCommutable = CommutableRR,
  988. isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
  989. def NAME#8rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
  990. def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
  991. def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
  992. def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
  993. } // isCommutable
  994. def NAME#8rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>;
  995. def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>;
  996. def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>;
  997. def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>;
  998. def NAME#8rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
  999. def NAME#16rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
  1000. def NAME#32rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
  1001. def NAME#64rm : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
  1002. let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
  1003. // NOTE: These are order specific, we want the ri8 forms to be listed
  1004. // first so that they are slightly preferred to the ri forms.
  1005. def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
  1006. def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
  1007. def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
  1008. def NAME#8ri : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
  1009. def NAME#16ri : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
  1010. def NAME#32ri : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
  1011. def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
  1012. }
  1013. } // Constraints = "$src1 = $dst"
  1014. def NAME#8mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
  1015. def NAME#16mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
  1016. def NAME#32mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
  1017. def NAME#64mr : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
  1018. // NOTE: These are order specific, we want the mi8 forms to be listed
  1019. // first so that they are slightly preferred to the mi forms.
  1020. def NAME#16mi8 : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
  1021. def NAME#32mi8 : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
  1022. def NAME#64mi8 : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
  1023. def NAME#8mi : BinOpMI_RMW_FF<mnemonic, Xi8 , opnode, MemMRM>;
  1024. def NAME#16mi : BinOpMI_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
  1025. def NAME#32mi : BinOpMI_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
  1026. def NAME#64mi32 : BinOpMI_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
  1027. } // Uses = [EFLAGS], Defs = [EFLAGS]
  1028. def NAME#8i8 : BinOpAI_FF<BaseOpc4, mnemonic, Xi8 , AL,
  1029. "{$src, %al|al, $src}">;
  1030. def NAME#16i16 : BinOpAI_FF<BaseOpc4, mnemonic, Xi16, AX,
  1031. "{$src, %ax|ax, $src}">;
  1032. def NAME#32i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi32, EAX,
  1033. "{$src, %eax|eax, $src}">;
  1034. def NAME#64i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi64, RAX,
  1035. "{$src, %rax|rax, $src}">;
  1036. }
  1037. /// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
  1038. /// defined with "(set EFLAGS, (...". It would be really nice to find a way
  1039. /// to factor this with the other ArithBinOp_*.
  1040. ///
  1041. multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
  1042. string mnemonic, Format RegMRM, Format MemMRM,
  1043. SDNode opnode,
  1044. bit CommutableRR, bit ConvertibleToThreeAddress> {
  1045. let Defs = [EFLAGS] in {
  1046. let isCommutable = CommutableRR,
  1047. isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
  1048. def NAME#8rr : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
  1049. def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
  1050. def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
  1051. def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
  1052. } // isCommutable
  1053. def NAME#8rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>;
  1054. def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>;
  1055. def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>;
  1056. def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>;
  1057. def NAME#8rm : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
  1058. def NAME#16rm : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
  1059. def NAME#32rm : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
  1060. def NAME#64rm : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
  1061. let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
  1062. // NOTE: These are order specific, we want the ri8 forms to be listed
  1063. // first so that they are slightly preferred to the ri forms.
  1064. def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
  1065. def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
  1066. def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
  1067. def NAME#8ri : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
  1068. def NAME#16ri : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
  1069. def NAME#32ri : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
  1070. def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
  1071. }
  1072. def NAME#8mr : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
  1073. def NAME#16mr : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
  1074. def NAME#32mr : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
  1075. def NAME#64mr : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
  1076. // NOTE: These are order specific, we want the mi8 forms to be listed
  1077. // first so that they are slightly preferred to the mi forms.
  1078. def NAME#16mi8 : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
  1079. def NAME#32mi8 : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
  1080. def NAME#64mi8 : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
  1081. def NAME#8mi : BinOpMI_F<mnemonic, Xi8 , opnode, MemMRM>;
  1082. def NAME#16mi : BinOpMI_F<mnemonic, Xi16, opnode, MemMRM>;
  1083. def NAME#32mi : BinOpMI_F<mnemonic, Xi32, opnode, MemMRM>;
  1084. def NAME#64mi32 : BinOpMI_F<mnemonic, Xi64, opnode, MemMRM>;
  1085. } // Defs = [EFLAGS]
  1086. def NAME#8i8 : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
  1087. "{$src, %al|al, $src}">;
  1088. def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
  1089. "{$src, %ax|ax, $src}">;
  1090. def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
  1091. "{$src, %eax|eax, $src}">;
  1092. def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
  1093. "{$src, %rax|rax, $src}">;
  1094. }
  1095. defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
  1096. X86and_flag, and, 1, 0>;
  1097. defm OR : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
  1098. X86or_flag, or, 1, 0>;
  1099. defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
  1100. X86xor_flag, xor, 1, 0>;
  1101. defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
  1102. X86add_flag, add, 1, 1>;
  1103. let isCompare = 1 in {
  1104. defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
  1105. X86sub_flag, sub, 0, 0>;
  1106. }
  1107. // Arithmetic.
  1108. defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
  1109. 1, 0>;
  1110. defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
  1111. 0, 0>;
  1112. let isCompare = 1 in {
  1113. defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
  1114. }
  1115. //===----------------------------------------------------------------------===//
  1116. // Semantically, test instructions are similar like AND, except they don't
  1117. // generate a result. From an encoding perspective, they are very different:
  1118. // they don't have all the usual imm8 and REV forms, and are encoded into a
  1119. // different space.
  1120. def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
  1121. (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
  1122. let isCompare = 1 in {
  1123. let Defs = [EFLAGS] in {
  1124. let isCommutable = 1 in {
  1125. def TEST8rr : BinOpRR_F<0x84, "test", Xi8 , X86testpat, MRMSrcReg>;
  1126. def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat, MRMSrcReg>;
  1127. def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat, MRMSrcReg>;
  1128. def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat, MRMSrcReg>;
  1129. } // isCommutable
  1130. def TEST8rm : BinOpRM_F<0x84, "test", Xi8 , X86testpat>;
  1131. def TEST16rm : BinOpRM_F<0x84, "test", Xi16, X86testpat>;
  1132. def TEST32rm : BinOpRM_F<0x84, "test", Xi32, X86testpat>;
  1133. def TEST64rm : BinOpRM_F<0x84, "test", Xi64, X86testpat>;
  1134. def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
  1135. def TEST16ri : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
  1136. def TEST32ri : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
  1137. def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
  1138. def TEST8mi : BinOpMI_F<"test", Xi8 , X86testpat, MRM0m, 0xF6>;
  1139. def TEST16mi : BinOpMI_F<"test", Xi16, X86testpat, MRM0m, 0xF6>;
  1140. def TEST32mi : BinOpMI_F<"test", Xi32, X86testpat, MRM0m, 0xF6>;
  1141. def TEST64mi32 : BinOpMI_F<"test", Xi64, X86testpat, MRM0m, 0xF6>;
  1142. // When testing the result of EXTRACT_SUBREG sub_8bit_hi, make sure the
  1143. // register class is constrained to GR8_NOREX.
  1144. let isPseudo = 1 in
  1145. def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
  1146. "", [], IIC_BIN_NONMEM>, Sched<[WriteALU]>;
  1147. } // Defs = [EFLAGS]
  1148. def TEST8i8 : BinOpAI<0xA8, "test", Xi8 , AL,
  1149. "{$src, %al|al, $src}">;
  1150. def TEST16i16 : BinOpAI<0xA8, "test", Xi16, AX,
  1151. "{$src, %ax|ax, $src}">;
  1152. def TEST32i32 : BinOpAI<0xA8, "test", Xi32, EAX,
  1153. "{$src, %eax|eax, $src}">;
  1154. def TEST64i32 : BinOpAI<0xA8, "test", Xi64, RAX,
  1155. "{$src, %rax|rax, $src}">;
  1156. } // isCompare
  1157. //===----------------------------------------------------------------------===//
  1158. // ANDN Instruction
  1159. //
  1160. multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
  1161. PatFrag ld_frag> {
  1162. def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
  1163. !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
  1164. [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))],
  1165. IIC_BIN_NONMEM>, Sched<[WriteALU]>;
  1166. def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
  1167. !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
  1168. [(set RC:$dst, EFLAGS,
  1169. (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))], IIC_BIN_MEM>,
  1170. Sched<[WriteALULd, ReadAfterLd]>;
  1171. }
  1172. let Predicates = [HasBMI], Defs = [EFLAGS] in {
  1173. defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8, VEX_4V;
  1174. defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8, VEX_4V, VEX_W;
  1175. }
  1176. let Predicates = [HasBMI] in {
  1177. def : Pat<(and (not GR32:$src1), GR32:$src2),
  1178. (ANDN32rr GR32:$src1, GR32:$src2)>;
  1179. def : Pat<(and (not GR64:$src1), GR64:$src2),
  1180. (ANDN64rr GR64:$src1, GR64:$src2)>;
  1181. def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
  1182. (ANDN32rm GR32:$src1, addr:$src2)>;
  1183. def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
  1184. (ANDN64rm GR64:$src1, addr:$src2)>;
  1185. }
  1186. //===----------------------------------------------------------------------===//
  1187. // MULX Instruction
  1188. //
  1189. multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop> {
  1190. let neverHasSideEffects = 1 in {
  1191. let isCommutable = 1 in
  1192. def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
  1193. !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
  1194. [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMul, WriteIMulH]>;
  1195. let mayLoad = 1 in
  1196. def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
  1197. !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
  1198. [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMulLd, WriteIMulH]>;
  1199. }
  1200. }
  1201. let Predicates = [HasBMI2] in {
  1202. let Uses = [EDX] in
  1203. defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem>;
  1204. let Uses = [RDX] in
  1205. defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem>, VEX_W;
  1206. }
  1207. //===----------------------------------------------------------------------===//
  1208. // ADCX Instruction
  1209. //
  1210. let hasSideEffects = 0, Predicates = [HasADX], Defs = [EFLAGS] in {
  1211. let SchedRW = [WriteALU] in {
  1212. def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
  1213. "adcx{l}\t{$src, $dst|$dst, $src}",
  1214. [], IIC_BIN_NONMEM>, T8, OpSize;
  1215. def ADCX64rr : I<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
  1216. "adcx{q}\t{$src, $dst|$dst, $src}",
  1217. [], IIC_BIN_NONMEM>, T8, OpSize, REX_W, Requires<[In64BitMode]>;
  1218. } // SchedRW
  1219. let mayLoad = 1, SchedRW = [WriteALULd] in {
  1220. def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
  1221. "adcx{l}\t{$src, $dst|$dst, $src}",
  1222. [], IIC_BIN_MEM>, T8, OpSize;
  1223. def ADCX64rm : I<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
  1224. "adcx{q}\t{$src, $dst|$dst, $src}",
  1225. [], IIC_BIN_MEM>, T8, OpSize, REX_W, Requires<[In64BitMode]>;
  1226. }
  1227. }
  1228. //===----------------------------------------------------------------------===//
  1229. // ADOX Instruction
  1230. //
  1231. let hasSideEffects = 0, Predicates = [HasADX], Defs = [EFLAGS] in {
  1232. let SchedRW = [WriteALU] in {
  1233. def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
  1234. "adox{l}\t{$src, $dst|$dst, $src}",
  1235. [], IIC_BIN_NONMEM>, T8XS;
  1236. def ADOX64rr : I<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
  1237. "adox{q}\t{$src, $dst|$dst, $src}",
  1238. [], IIC_BIN_NONMEM>, T8XS, REX_W, Requires<[In64BitMode]>;
  1239. } // SchedRW
  1240. let mayLoad = 1, SchedRW = [WriteALULd] in {
  1241. def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
  1242. "adox{l}\t{$src, $dst|$dst, $src}",
  1243. [], IIC_BIN_MEM>, T8XS;
  1244. def ADOX64rm : I<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
  1245. "adox{q}\t{$src, $dst|$dst, $src}",
  1246. [], IIC_BIN_MEM>, T8XS, REX_W, Requires<[In64BitMode]>;
  1247. }
  1248. }