/3rd_party/llvm/lib/Target/Blackfin/BlackfinInstrInfo.td

https://code.google.com/p/softart/ · Unknown · 862 lines · 658 code · 204 blank · 0 comment · 0 complexity · 0c2cdb0c2b1248b5c7916a859509bfb8 MD5 · raw file

  1. //===- BlackfinInstrInfo.td - Target Description for Blackfin Target ------===//
  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 Blackfin instructions in TableGen format.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //===----------------------------------------------------------------------===//
  14. // Instruction format superclass
  15. //===----------------------------------------------------------------------===//
  16. include "BlackfinInstrFormats.td"
  17. // These are target-independent nodes, but have target-specific formats.
  18. def SDT_BfinCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
  19. def SDT_BfinCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
  20. SDTCisVT<1, i32> ]>;
  21. def BfinCallseqStart : SDNode<"ISD::CALLSEQ_START", SDT_BfinCallSeqStart,
  22. [SDNPHasChain, SDNPOutGlue]>;
  23. def BfinCallseqEnd : SDNode<"ISD::CALLSEQ_END", SDT_BfinCallSeqEnd,
  24. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
  25. def SDT_BfinCall : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
  26. def BfinCall : SDNode<"BFISD::CALL", SDT_BfinCall,
  27. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
  28. SDNPVariadic]>;
  29. def BfinRet: SDNode<"BFISD::RET_FLAG", SDTNone,
  30. [SDNPHasChain, SDNPOptInGlue]>;
  31. def BfinWrapper: SDNode<"BFISD::Wrapper", SDTIntUnaryOp>;
  32. //===----------------------------------------------------------------------===//
  33. // Transformations
  34. //===----------------------------------------------------------------------===//
  35. def trailingZeros_xform : SDNodeXForm<imm, [{
  36. return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(),
  37. MVT::i32);
  38. }]>;
  39. def trailingOnes_xform : SDNodeXForm<imm, [{
  40. return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(),
  41. MVT::i32);
  42. }]>;
  43. def LO16 : SDNodeXForm<imm, [{
  44. return CurDAG->getTargetConstant((unsigned short)N->getZExtValue(), MVT::i16);
  45. }]>;
  46. def HI16 : SDNodeXForm<imm, [{
  47. // Transformation function: shift the immediate value down into the low bits.
  48. return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 16, MVT::i16);
  49. }]>;
  50. //===----------------------------------------------------------------------===//
  51. // Immediates
  52. //===----------------------------------------------------------------------===//
  53. def imm3 : PatLeaf<(imm), [{return isInt<3>(N->getSExtValue());}]>;
  54. def uimm3 : PatLeaf<(imm), [{return isUInt<3>(N->getZExtValue());}]>;
  55. def uimm4 : PatLeaf<(imm), [{return isUInt<4>(N->getZExtValue());}]>;
  56. def uimm5 : PatLeaf<(imm), [{return isUInt<5>(N->getZExtValue());}]>;
  57. def uimm5m2 : PatLeaf<(imm), [{
  58. uint64_t value = N->getZExtValue();
  59. return value % 2 == 0 && isUInt<5>(value);
  60. }]>;
  61. def uimm6m4 : PatLeaf<(imm), [{
  62. uint64_t value = N->getZExtValue();
  63. return value % 4 == 0 && isUInt<6>(value);
  64. }]>;
  65. def imm7 : PatLeaf<(imm), [{return isInt<7>(N->getSExtValue());}]>;
  66. def imm16 : PatLeaf<(imm), [{return isInt<16>(N->getSExtValue());}]>;
  67. def uimm16 : PatLeaf<(imm), [{return isUInt<16>(N->getZExtValue());}]>;
  68. def ximm16 : PatLeaf<(imm), [{
  69. int64_t value = N->getSExtValue();
  70. return value < (1<<16) && value >= -(1<<15);
  71. }]>;
  72. def imm17m2 : PatLeaf<(imm), [{
  73. int64_t value = N->getSExtValue();
  74. return value % 2 == 0 && isInt<17>(value);
  75. }]>;
  76. def imm18m4 : PatLeaf<(imm), [{
  77. int64_t value = N->getSExtValue();
  78. return value % 4 == 0 && isInt<18>(value);
  79. }]>;
  80. // 32-bit bitmask transformed to a bit number
  81. def uimm5mask : Operand<i32>, PatLeaf<(imm), [{
  82. return isPowerOf2_32(N->getZExtValue());
  83. }], trailingZeros_xform>;
  84. // 32-bit inverse bitmask transformed to a bit number
  85. def uimm5imask : Operand<i32>, PatLeaf<(imm), [{
  86. return isPowerOf2_32(~N->getZExtValue());
  87. }], trailingOnes_xform>;
  88. //===----------------------------------------------------------------------===//
  89. // Operands
  90. //===----------------------------------------------------------------------===//
  91. def calltarget : Operand<iPTR>;
  92. def brtarget : Operand<OtherVT>;
  93. // Addressing modes
  94. def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>;
  95. // Address operands
  96. def MEMii : Operand<i32> {
  97. let PrintMethod = "printMemoryOperand";
  98. let MIOperandInfo = (ops i32imm, i32imm);
  99. }
  100. //===----------------------------------------------------------------------===//
  101. // Instructions
  102. //===----------------------------------------------------------------------===//
  103. // Pseudo instructions.
  104. class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
  105. : InstBfin<outs, ins, asmstr, pattern>;
  106. let Defs = [SP], Uses = [SP] in {
  107. def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
  108. "${:comment}ADJCALLSTACKDOWN $amt",
  109. [(BfinCallseqStart timm:$amt)]>;
  110. def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
  111. "${:comment}ADJCALLSTACKUP $amt1 $amt2",
  112. [(BfinCallseqEnd timm:$amt1, timm:$amt2)]>;
  113. }
  114. //===----------------------------------------------------------------------===//
  115. // Table C-9. Program Flow Control Instructions
  116. //===----------------------------------------------------------------------===//
  117. let isBranch = 1, isTerminator = 1 in {
  118. let isIndirectBranch = 1 in
  119. def JUMPp : F1<(outs), (ins P:$target),
  120. "JUMP ($target);",
  121. [(brind P:$target)]>;
  122. // TODO JUMP (PC-P)
  123. // NOTE: assembler chooses between JUMP.S and JUMP.L
  124. def JUMPa : F1<(outs), (ins brtarget:$target),
  125. "jump $target;",
  126. [(br bb:$target)]>;
  127. def JUMPcc : F1<(outs), (ins AnyCC:$cc, brtarget:$target),
  128. "if $cc jump $target;",
  129. [(brcond AnyCC:$cc, bb:$target)]>;
  130. }
  131. let isCall = 1,
  132. Defs = [R0, R1, R2, R3, P0, P1, P2, LB0, LB1, LC0, LC1, RETS, ASTAT] in {
  133. def CALLa: F1<(outs), (ins calltarget:$func, variable_ops),
  134. "call $func;", []>;
  135. def CALLp: F1<(outs), (ins P:$func, variable_ops),
  136. "call ($func);", [(BfinCall P:$func)]>;
  137. }
  138. let isReturn = 1,
  139. isTerminator = 1,
  140. isBarrier = 1,
  141. Uses = [RETS] in
  142. def RTS: F1<(outs), (ins), "rts;", [(BfinRet)]>;
  143. //===----------------------------------------------------------------------===//
  144. // Table C-10. Load / Store Instructions
  145. //===----------------------------------------------------------------------===//
  146. // Immediate constant loads
  147. // sext immediate, i32 D/P regs
  148. def LOADimm7: F1<(outs DP:$dst), (ins i32imm:$src),
  149. "$dst = $src (x);",
  150. [(set DP:$dst, imm7:$src)]>;
  151. // zext immediate, i32 reg groups 0-3
  152. def LOADuimm16: F2<(outs GR:$dst), (ins i32imm:$src),
  153. "$dst = $src (z);",
  154. [(set GR:$dst, uimm16:$src)]>;
  155. // sext immediate, i32 reg groups 0-3
  156. def LOADimm16: F2<(outs GR:$dst), (ins i32imm:$src),
  157. "$dst = $src (x);",
  158. [(set GR:$dst, imm16:$src)]>;
  159. // Pseudo-instruction for loading a general 32-bit constant.
  160. def LOAD32imm: Pseudo<(outs GR:$dst), (ins i32imm:$src),
  161. "$dst.h = ($src >> 16); $dst.l = ($src & 0xffff);",
  162. [(set GR:$dst, imm:$src)]>;
  163. def LOAD32sym: Pseudo<(outs GR:$dst), (ins i32imm:$src),
  164. "$dst.h = $src; $dst.l = $src;", []>;
  165. // 16-bit immediate, i16 reg groups 0-3
  166. def LOAD16i: F2<(outs GR16:$dst), (ins i16imm:$src),
  167. "$dst = $src;", []>;
  168. def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)),
  169. (LOAD32sym tglobaladdr:$addr)>;
  170. def : Pat<(BfinWrapper (i32 tjumptable:$addr)),
  171. (LOAD32sym tjumptable:$addr)>;
  172. // We cannot copy from GR16 to D16, and codegen wants to insert copies if we
  173. // emit GR16 instructions. As a hack, we use this fake instruction instead.
  174. def LOAD16i_d16: F2<(outs D16:$dst), (ins i16imm:$src),
  175. "$dst = $src;",
  176. [(set D16:$dst, ximm16:$src)]>;
  177. // Memory loads with patterns
  178. def LOAD32p: F1<(outs DP:$dst), (ins P:$ptr),
  179. "$dst = [$ptr];",
  180. [(set DP:$dst, (load P:$ptr))]>;
  181. // Pseudo-instruction for loading a stack slot
  182. def LOAD32fi: Pseudo<(outs DP:$dst), (ins MEMii:$mem),
  183. "${:comment}FI $dst = [$mem];",
  184. [(set DP:$dst, (load ADDRspii:$mem))]>;
  185. // Note: Expands to multiple insns
  186. def LOAD16fi: Pseudo<(outs D16:$dst), (ins MEMii:$mem),
  187. "${:comment}FI $dst = [$mem];",
  188. [(set D16:$dst, (load ADDRspii:$mem))]>;
  189. // Pseudo-instruction for loading a stack slot, used for AnyCC regs.
  190. // Replaced with Load D + CC=D
  191. def LOAD8fi: Pseudo<(outs AnyCC:$dst), (ins MEMii:$mem),
  192. "${:comment}FI $dst = B[$mem];",
  193. [(set AnyCC:$dst, (load ADDRspii:$mem))]>;
  194. def LOAD32p_uimm6m4: F1<(outs DP:$dst), (ins P:$ptr, i32imm:$off),
  195. "$dst = [$ptr + $off];",
  196. [(set DP:$dst, (load (add P:$ptr, uimm6m4:$off)))]>;
  197. def LOAD32p_imm18m4: F2<(outs DP:$dst), (ins P:$ptr, i32imm:$off),
  198. "$dst = [$ptr + $off];",
  199. [(set DP:$dst, (load (add P:$ptr, imm18m4:$off)))]>;
  200. def LOAD32p_16z: F1<(outs D:$dst), (ins P:$ptr),
  201. "$dst = W[$ptr] (z);",
  202. [(set D:$dst, (zextloadi16 P:$ptr))]>;
  203. def : Pat<(i32 (extloadi16 P:$ptr)),(LOAD32p_16z P:$ptr)>;
  204. def LOAD32p_uimm5m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
  205. "$dst = w[$ptr + $off] (z);",
  206. [(set D:$dst, (zextloadi16 (add P:$ptr,
  207. uimm5m2:$off)))]>;
  208. def : Pat<(i32 (extloadi16 (add P:$ptr, uimm5m2:$off))),
  209. (LOAD32p_uimm5m2_16z P:$ptr, imm:$off)>;
  210. def LOAD32p_imm17m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
  211. "$dst = w[$ptr + $off] (z);",
  212. [(set D:$dst,
  213. (zextloadi16 (add P:$ptr, imm17m2:$off)))]>;
  214. def : Pat<(i32 (extloadi16 (add P:$ptr, imm17m2:$off))),
  215. (LOAD32p_imm17m2_16z P:$ptr, imm:$off)>;
  216. def LOAD32p_16s: F1<(outs D:$dst), (ins P:$ptr),
  217. "$dst = w[$ptr] (x);",
  218. [(set D:$dst, (sextloadi16 P:$ptr))]>;
  219. def LOAD32p_uimm5m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
  220. "$dst = w[$ptr + $off] (x);",
  221. [(set D:$dst,
  222. (sextloadi16 (add P:$ptr, uimm5m2:$off)))]>;
  223. def LOAD32p_imm17m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
  224. "$dst = w[$ptr + $off] (x);",
  225. [(set D:$dst,
  226. (sextloadi16 (add P:$ptr, imm17m2:$off)))]>;
  227. def LOAD16pi: F1<(outs D16:$dst), (ins PI:$ptr),
  228. "$dst = w[$ptr];",
  229. [(set D16:$dst, (load PI:$ptr))]>;
  230. def LOAD32p_8z: F1<(outs D:$dst), (ins P:$ptr),
  231. "$dst = B[$ptr] (z);",
  232. [(set D:$dst, (zextloadi8 P:$ptr))]>;
  233. def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>;
  234. def : Pat<(i16 (extloadi8 P:$ptr)),
  235. (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>;
  236. def : Pat<(i16 (zextloadi8 P:$ptr)),
  237. (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>;
  238. def LOAD32p_imm16_8z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
  239. "$dst = b[$ptr + $off] (z);",
  240. [(set D:$dst, (zextloadi8 (add P:$ptr, imm16:$off)))]>;
  241. def : Pat<(i32 (extloadi8 (add P:$ptr, imm16:$off))),
  242. (LOAD32p_imm16_8z P:$ptr, imm:$off)>;
  243. def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))),
  244. (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
  245. lo16)>;
  246. def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))),
  247. (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
  248. lo16)>;
  249. def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr),
  250. "$dst = b[$ptr] (x);",
  251. [(set D:$dst, (sextloadi8 P:$ptr))]>;
  252. def : Pat<(i16 (sextloadi8 P:$ptr)),
  253. (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), lo16)>;
  254. def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
  255. "$dst = b[$ptr + $off] (x);",
  256. [(set D:$dst, (sextloadi8 (add P:$ptr, imm16:$off)))]>;
  257. def : Pat<(i16 (sextloadi8 (add P:$ptr, imm16:$off))),
  258. (EXTRACT_SUBREG (LOAD32p_imm16_8s P:$ptr, imm:$off),
  259. lo16)>;
  260. // Memory loads without patterns
  261. let mayLoad = 1 in {
  262. multiclass LOAD_incdec<RegisterClass drc, RegisterClass prc,
  263. string mem="", string suf=";"> {
  264. def _inc : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr),
  265. !strconcat(!subst("M", mem, "$dst = M[$ptr++]"), suf), []>;
  266. def _dec : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr),
  267. !strconcat(!subst("M", mem, "$dst = M[$ptr--]"), suf), []>;
  268. }
  269. multiclass LOAD_incdecpost<RegisterClass drc, RegisterClass prc,
  270. string mem="", string suf=";">
  271. : LOAD_incdec<drc, prc, mem, suf> {
  272. def _post : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr, prc:$off),
  273. !strconcat(!subst("M", mem, "$dst = M[$ptr++$off]"), suf), []>;
  274. }
  275. defm LOAD32p: LOAD_incdec<DP, P>;
  276. defm LOAD32i: LOAD_incdec<D, I>;
  277. defm LOAD8z32p: LOAD_incdec<D, P, "b", " (z);">;
  278. defm LOAD8s32p: LOAD_incdec<D, P, "b", " (x);">;
  279. defm LOADhi: LOAD_incdec<D16, I, "w">;
  280. defm LOAD16z32p: LOAD_incdecpost<D, P, "w", " (z);">;
  281. defm LOAD16s32p: LOAD_incdecpost<D, P, "w", " (x);">;
  282. def LOAD32p_post: F1<(outs D:$dst, P:$ptr_wb), (ins P:$ptr, P:$off),
  283. "$dst = [$ptr ++ $off];", []>;
  284. // Note: $fp MUST be FP
  285. def LOAD32fp_nimm7m4: F1<(outs DP:$dst), (ins P:$fp, i32imm:$off),
  286. "$dst = [$fp - $off];", []>;
  287. def LOAD32i: F1<(outs D:$dst), (ins I:$ptr),
  288. "$dst = [$ptr];", []>;
  289. def LOAD32i_post: F1<(outs D:$dst, I:$ptr_wb), (ins I:$ptr, M:$off),
  290. "$dst = [$ptr ++ $off];", []>;
  291. def LOADhp_post: F1<(outs D16:$dst, P:$ptr_wb), (ins P:$ptr, P:$off),
  292. "$dst = w[$ptr ++ $off];", []>;
  293. }
  294. // Memory stores with patterns
  295. def STORE32p: F1<(outs), (ins DP:$val, P:$ptr),
  296. "[$ptr] = $val;",
  297. [(store DP:$val, P:$ptr)]>;
  298. // Pseudo-instructions for storing to a stack slot
  299. def STORE32fi: Pseudo<(outs), (ins DP:$val, MEMii:$mem),
  300. "${:comment}FI [$mem] = $val;",
  301. [(store DP:$val, ADDRspii:$mem)]>;
  302. // Note: This stack-storing pseudo-instruction is expanded to multiple insns
  303. def STORE16fi: Pseudo<(outs), (ins D16:$val, MEMii:$mem),
  304. "${:comment}FI [$mem] = $val;",
  305. [(store D16:$val, ADDRspii:$mem)]>;
  306. // Pseudo-instructions for storing AnyCC register to a stack slot.
  307. // Replaced with D=CC + STORE byte
  308. def STORE8fi: Pseudo<(outs), (ins AnyCC:$val, MEMii:$mem),
  309. "${:comment}FI b[$mem] = $val;",
  310. [(store AnyCC:$val, ADDRspii:$mem)]>;
  311. def STORE32p_uimm6m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off),
  312. "[$ptr + $off] = $val;",
  313. [(store DP:$val, (add P:$ptr, uimm6m4:$off))]>;
  314. def STORE32p_imm18m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off),
  315. "[$ptr + $off] = $val;",
  316. [(store DP:$val, (add P:$ptr, imm18m4:$off))]>;
  317. def STORE16pi: F1<(outs), (ins D16:$val, PI:$ptr),
  318. "w[$ptr] = $val;",
  319. [(store D16:$val, PI:$ptr)]>;
  320. def STORE8p: F1<(outs), (ins D:$val, P:$ptr),
  321. "b[$ptr] = $val;",
  322. [(truncstorei8 D:$val, P:$ptr)]>;
  323. def STORE8p_imm16: F1<(outs), (ins D:$val, P:$ptr, i32imm:$off),
  324. "b[$ptr + $off] = $val;",
  325. [(truncstorei8 D:$val, (add P:$ptr, imm16:$off))]>;
  326. let Constraints = "$ptr = $ptr_wb" in {
  327. multiclass STORE_incdec<RegisterClass drc, RegisterClass prc,
  328. int off=4, string pre=""> {
  329. def _inc : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr),
  330. !strconcat(pre, "[$ptr++] = $val;"),
  331. [(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr, off))]>;
  332. def _dec : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr),
  333. !strconcat(pre, "[$ptr--] = $val;"),
  334. [(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr,
  335. (ineg off)))]>;
  336. }
  337. defm STORE32p: STORE_incdec<DP, P>;
  338. defm STORE16i: STORE_incdec<D16, I, 2, "w">;
  339. defm STORE8p: STORE_incdec<D, P, 1, "b">;
  340. def STORE32p_post: F1<(outs P:$ptr_wb), (ins D:$val, P:$ptr, P:$off),
  341. "[$ptr ++ $off] = $val;",
  342. [(set P:$ptr_wb, (post_store D:$val, P:$ptr, P:$off))]>;
  343. def STORE16p_post: F1<(outs P:$ptr_wb), (ins D16:$val, P:$ptr, P:$off),
  344. "w[$ptr ++ $off] = $val;",
  345. [(set P:$ptr_wb, (post_store D16:$val, P:$ptr, P:$off))]>;
  346. }
  347. // Memory stores without patterns
  348. let mayStore = 1 in {
  349. // Note: only works for $fp == FP
  350. def STORE32fp_nimm7m4: F1<(outs), (ins DP:$val, P:$fp, i32imm:$off),
  351. "[$fp - $off] = $val;", []>;
  352. def STORE32i: F1<(outs), (ins D:$val, I:$ptr),
  353. "[$ptr] = $val;", []>;
  354. def STORE32i_inc: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr),
  355. "[$ptr++] = $val;", []>;
  356. def STORE32i_dec: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr),
  357. "[$ptr--] = $val;", []>;
  358. def STORE32i_post: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr, M:$off),
  359. "[$ptr ++ $off] = $val;", []>;
  360. }
  361. def : Pat<(truncstorei16 D:$val, PI:$ptr),
  362. (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
  363. lo16), PI:$ptr)>;
  364. def : Pat<(truncstorei16 (srl D:$val, (i16 16)), PI:$ptr),
  365. (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
  366. hi16), PI:$ptr)>;
  367. def : Pat<(truncstorei8 D16L:$val, P:$ptr),
  368. (STORE8p (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
  369. (i16 (COPY_TO_REGCLASS D16L:$val, D16L)),
  370. lo16),
  371. P:$ptr)>;
  372. //===----------------------------------------------------------------------===//
  373. // Table C-11. Move Instructions.
  374. //===----------------------------------------------------------------------===//
  375. def MOVE: F1<(outs ALL:$dst), (ins ALL:$src),
  376. "$dst = $src;",
  377. []>;
  378. let Constraints = "$src1 = $dst" in
  379. def MOVEcc: F1<(outs DP:$dst), (ins DP:$src1, DP:$src2, AnyCC:$cc),
  380. "if $cc $dst = $src2;",
  381. [(set DP:$dst, (select AnyCC:$cc, DP:$src2, DP:$src1))]>;
  382. let Defs = [AZ, AN, AC0, V] in {
  383. def MOVEzext: F1<(outs D:$dst), (ins D16L:$src),
  384. "$dst = $src (z);",
  385. [(set D:$dst, (zext D16L:$src))]>;
  386. def MOVEsext: F1<(outs D:$dst), (ins D16L:$src),
  387. "$dst = $src (x);",
  388. [(set D:$dst, (sext D16L:$src))]>;
  389. def MOVEzext8: F1<(outs D:$dst), (ins D:$src),
  390. "$dst = $src.b (z);",
  391. [(set D:$dst, (and D:$src, 0xff))]>;
  392. def MOVEsext8: F1<(outs D:$dst), (ins D:$src),
  393. "$dst = $src.b (x);",
  394. [(set D:$dst, (sext_inreg D:$src, i8))]>;
  395. }
  396. def : Pat<(sext_inreg D16L:$src, i8),
  397. (EXTRACT_SUBREG (MOVEsext8
  398. (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
  399. D16L:$src,
  400. lo16)),
  401. lo16)>;
  402. def : Pat<(sext_inreg D:$src, i16),
  403. (MOVEsext (EXTRACT_SUBREG D:$src, lo16))>;
  404. def : Pat<(and D:$src, 0xffff),
  405. (MOVEzext (EXTRACT_SUBREG D:$src, lo16))>;
  406. def : Pat<(i32 (anyext D16L:$src)),
  407. (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
  408. (i16 (COPY_TO_REGCLASS D16L:$src, D16L)),
  409. lo16)>;
  410. // TODO Dreg = Dreg_byte (X/Z)
  411. // TODO Accumulator moves
  412. //===----------------------------------------------------------------------===//
  413. // Table C-12. Stack Control Instructions
  414. //===----------------------------------------------------------------------===//
  415. let Uses = [SP], Defs = [SP] in {
  416. def PUSH: F1<(outs), (ins ALL:$src),
  417. "[--sp] = $src;", []> { let mayStore = 1; }
  418. // NOTE: POP does not work for DP regs, use LOAD instead
  419. def POP: F1<(outs ALL:$dst), (ins),
  420. "$dst = [sp++];", []> { let mayLoad = 1; }
  421. }
  422. // TODO: push/pop multiple
  423. def LINK: F2<(outs), (ins i32imm:$amount),
  424. "link $amount;", []>;
  425. def UNLINK: F2<(outs), (ins),
  426. "unlink;", []>;
  427. //===----------------------------------------------------------------------===//
  428. // Table C-13. Control Code Bit Management Instructions
  429. //===----------------------------------------------------------------------===//
  430. multiclass SETCC<PatFrag opnode, PatFrag invnode, string cond, string suf=";"> {
  431. def dd : F1<(outs JustCC:$cc), (ins D:$a, D:$b),
  432. !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
  433. [(set JustCC:$cc, (opnode D:$a, D:$b))]>;
  434. def ri : F1<(outs JustCC:$cc), (ins DP:$a, i32imm:$b),
  435. !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
  436. [(set JustCC:$cc, (opnode DP:$a, imm3:$b))]>;
  437. def pp : F1<(outs JustCC:$cc), (ins P:$a, P:$b),
  438. !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
  439. []>;
  440. def ri_not : F1<(outs NotCC:$cc), (ins DP:$a, i32imm:$b),
  441. !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
  442. [(set NotCC:$cc, (invnode DP:$a, imm3:$b))]>;
  443. }
  444. defm SETEQ : SETCC<seteq, setne, "==">;
  445. defm SETLT : SETCC<setlt, setge, "<">;
  446. defm SETLE : SETCC<setle, setgt, "<=">;
  447. defm SETULT : SETCC<setult, setuge, "<", " (iu);">;
  448. defm SETULE : SETCC<setule, setugt, "<=", " (iu);">;
  449. def SETNEdd : F1<(outs NotCC:$cc), (ins D:$a, D:$b),
  450. "cc = $a == $b;",
  451. [(set NotCC:$cc, (setne D:$a, D:$b))]>;
  452. def : Pat<(setgt D:$a, D:$b), (SETLTdd D:$b, D:$a)>;
  453. def : Pat<(setge D:$a, D:$b), (SETLEdd D:$b, D:$a)>;
  454. def : Pat<(setugt D:$a, D:$b), (SETULTdd D:$b, D:$a)>;
  455. def : Pat<(setuge D:$a, D:$b), (SETULEdd D:$b, D:$a)>;
  456. // TODO: compare pointer for P-P comparisons
  457. // TODO: compare accumulator
  458. let Defs = [AC0] in
  459. def OR_ac0_cc : F1<(outs), (ins JustCC:$cc),
  460. "ac0 \\|= cc;", []>;
  461. let Uses = [AC0] in
  462. def MOVE_cc_ac0 : F1<(outs JustCC:$cc), (ins),
  463. "cc = ac0;", []>;
  464. def MOVE_ccncc : F1<(outs JustCC:$cc), (ins NotCC:$sb),
  465. "cc = !cc;", []>;
  466. def MOVE_ncccc : F1<(outs NotCC:$cc), (ins JustCC:$sb),
  467. "cc = !cc;", []>;
  468. def MOVECC_zext : F1<(outs D:$dst), (ins JustCC:$cc),
  469. "$dst = $cc;", []>;
  470. def MOVENCC_z : F1<(outs D:$dst), (ins NotCC:$cc),
  471. "$dst = cc;", []>;
  472. def MOVECC_nz : F1<(outs AnyCC:$cc), (ins D:$src),
  473. "cc = $src;",
  474. [(set AnyCC:$cc, (setne D:$src, 0))]>;
  475. //===----------------------------------------------------------------------===//
  476. // Table C-14. Logical Operations Instructions
  477. //===----------------------------------------------------------------------===//
  478. def AND: F1<(outs D:$dst), (ins D:$src1, D:$src2),
  479. "$dst = $src1 & $src2;",
  480. [(set D:$dst, (and D:$src1, D:$src2))]>;
  481. def NOT: F1<(outs D:$dst), (ins D:$src),
  482. "$dst = ~$src;",
  483. [(set D:$dst, (not D:$src))]>;
  484. def OR: F1<(outs D:$dst), (ins D:$src1, D:$src2),
  485. "$dst = $src1 \\| $src2;",
  486. [(set D:$dst, (or D:$src1, D:$src2))]>;
  487. def XOR: F1<(outs D:$dst), (ins D:$src1, D:$src2),
  488. "$dst = $src1 ^ $src2;",
  489. [(set D:$dst, (xor D:$src1, D:$src2))]>;
  490. // missing: BXOR, BXORSHIFT
  491. //===----------------------------------------------------------------------===//
  492. // Table C-15. Bit Operations Instructions
  493. //===----------------------------------------------------------------------===//
  494. let Constraints = "$src1 = $dst" in {
  495. def BITCLR: F1<(outs D:$dst), (ins D:$src1, uimm5imask:$src2),
  496. "bitclr($dst, $src2);",
  497. [(set D:$dst, (and D:$src1, uimm5imask:$src2))]>;
  498. def BITSET: F1<(outs D:$dst), (ins D:$src1, uimm5mask:$src2),
  499. "bitset($dst, $src2);",
  500. [(set D:$dst, (or D:$src1, uimm5mask:$src2))]>;
  501. def BITTGL: F1<(outs D:$dst), (ins D:$src1, uimm5mask:$src2),
  502. "bittgl($dst, $src2);",
  503. [(set D:$dst, (xor D:$src1, uimm5mask:$src2))]>;
  504. }
  505. def BITTST: F1<(outs JustCC:$cc), (ins D:$src1, uimm5mask:$src2),
  506. "cc = bittst($src1, $src2);",
  507. [(set JustCC:$cc, (setne (and D:$src1, uimm5mask:$src2),
  508. (i32 0)))]>;
  509. def NBITTST: F1<(outs JustCC:$cc), (ins D:$src1, uimm5mask:$src2),
  510. "cc = !bittst($src1, $src2);",
  511. [(set JustCC:$cc, (seteq (and D:$src1, uimm5mask:$src2),
  512. (i32 0)))]>;
  513. // TODO: DEPOSIT, EXTRACT, BITMUX
  514. def ONES: F2<(outs D16L:$dst), (ins D:$src),
  515. "$dst = ones $src;",
  516. [(set D16L:$dst, (trunc (ctpop D:$src)))]>;
  517. def : Pat<(ctpop D:$src), (MOVEzext (ONES D:$src))>;
  518. //===----------------------------------------------------------------------===//
  519. // Table C-16. Shift / Rotate Instructions
  520. //===----------------------------------------------------------------------===//
  521. multiclass SHIFT32<SDNode opnode, string ops> {
  522. def i : F1<(outs D:$dst), (ins D:$src, i16imm:$amount),
  523. !subst("XX", ops, "$dst XX= $amount;"),
  524. [(set D:$dst, (opnode D:$src, (i16 uimm5:$amount)))]>;
  525. def r : F1<(outs D:$dst), (ins D:$src, D:$amount),
  526. !subst("XX", ops, "$dst XX= $amount;"),
  527. [(set D:$dst, (opnode D:$src, D:$amount))]>;
  528. }
  529. let Defs = [AZ, AN, V, VS],
  530. Constraints = "$src = $dst" in {
  531. defm SRA : SHIFT32<sra, ">>>">;
  532. defm SRL : SHIFT32<srl, ">>">;
  533. defm SLL : SHIFT32<shl, "<<">;
  534. }
  535. // TODO: automatic switching between 2-addr and 3-addr (?)
  536. let Defs = [AZ, AN, V, VS] in {
  537. def SLLr16: F2<(outs D:$dst), (ins D:$src, D16L:$amount),
  538. "$dst = lshift $src by $amount;",
  539. [(set D:$dst, (shl D:$src, D16L:$amount))]>;
  540. // Arithmetic left-shift = saturing overflow.
  541. def SLAr16: F2<(outs D:$dst), (ins D:$src, D16L:$amount),
  542. "$dst = ashift $src by $amount;",
  543. [(set D:$dst, (sra D:$src, (ineg D16L:$amount)))]>;
  544. def SRA16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount),
  545. "$dst = $src >>> $amount;",
  546. [(set D16:$dst, (sra D16:$src, (i16 uimm4:$amount)))]>;
  547. def SRL16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount),
  548. "$dst = $src >> $amount;",
  549. [(set D16:$dst, (srl D16:$src, (i16 uimm4:$amount)))]>;
  550. // Arithmetic left-shift = saturing overflow.
  551. def SLA16r: F1<(outs D16:$dst), (ins D16:$src, D16L:$amount),
  552. "$dst = ashift $src BY $amount;",
  553. [(set D16:$dst, (srl D16:$src, (ineg D16L:$amount)))]>;
  554. def SLL16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount),
  555. "$dst = $src << $amount;",
  556. [(set D16:$dst, (shl D16:$src, (i16 uimm4:$amount)))]>;
  557. def SLL16r: F1<(outs D16:$dst), (ins D16:$src, D16L:$amount),
  558. "$dst = lshift $src by $amount;",
  559. [(set D16:$dst, (shl D16:$src, D16L:$amount))]>;
  560. }
  561. //===----------------------------------------------------------------------===//
  562. // Table C-17. Arithmetic Operations Instructions
  563. //===----------------------------------------------------------------------===//
  564. // TODO: ABS
  565. let Defs = [AZ, AN, AC0, V, VS] in {
  566. def ADD: F1<(outs D:$dst), (ins D:$src1, D:$src2),
  567. "$dst = $src1 + $src2;",
  568. [(set D:$dst, (add D:$src1, D:$src2))]>;
  569. def ADD16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
  570. "$dst = $src1 + $src2;",
  571. [(set D16:$dst, (add D16:$src1, D16:$src2))]>;
  572. let Constraints = "$src1 = $dst" in
  573. def ADDimm7: F1<(outs D:$dst), (ins D:$src1, i32imm:$src2),
  574. "$dst += $src2;",
  575. [(set D:$dst, (add D:$src1, imm7:$src2))]>;
  576. def SUB: F1<(outs D:$dst), (ins D:$src1, D:$src2),
  577. "$dst = $src1 - $src2;",
  578. [(set D:$dst, (sub D:$src1, D:$src2))]>;
  579. def SUB16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
  580. "$dst = $src1 - $src2;",
  581. [(set D16:$dst, (sub D16:$src1, D16:$src2))]>;
  582. }
  583. def : Pat<(addc D:$src1, D:$src2), (ADD D:$src1, D:$src2)>;
  584. def : Pat<(subc D:$src1, D:$src2), (SUB D:$src1, D:$src2)>;
  585. let Defs = [AZ, AN, V, VS] in
  586. def NEG: F1<(outs D:$dst), (ins D:$src),
  587. "$dst = -$src;",
  588. [(set D:$dst, (ineg D:$src))]>;
  589. // No pattern, it would confuse isel to have two i32 = i32+i32 patterns
  590. def ADDpp: F1<(outs P:$dst), (ins P:$src1, P:$src2),
  591. "$dst = $src1 + $src2;", []>;
  592. let Constraints = "$src1 = $dst" in
  593. def ADDpp_imm7: F1<(outs P:$dst), (ins P:$src1, i32imm:$src2),
  594. "$dst += $src2;", []>;
  595. let Defs = [AZ, AN, V] in
  596. def ADD_RND20: F2<(outs D16:$dst), (ins D:$src1, D:$src2),
  597. "$dst = $src1 + $src2 (rnd20);", []>;
  598. let Defs = [V, VS] in {
  599. def MUL16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
  600. "$dst = $src1 * $src2 (is);",
  601. [(set D16:$dst, (mul D16:$src1, D16:$src2))]>;
  602. def MULHS16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
  603. "$dst = $src1 * $src2 (ih);",
  604. [(set D16:$dst, (mulhs D16:$src1, D16:$src2))]>;
  605. def MULhh32s: F2<(outs D:$dst), (ins D16:$src1, D16:$src2),
  606. "$dst = $src1 * $src2 (is);",
  607. [(set D:$dst, (mul (sext D16:$src1), (sext D16:$src2)))]>;
  608. def MULhh32u: F2<(outs D:$dst), (ins D16:$src1, D16:$src2),
  609. "$dst = $src1 * $src2 (is);",
  610. [(set D:$dst, (mul (zext D16:$src1), (zext D16:$src2)))]>;
  611. }
  612. let Constraints = "$src1 = $dst" in
  613. def MUL32: F1<(outs D:$dst), (ins D:$src1, D:$src2),
  614. "$dst *= $src2;",
  615. [(set D:$dst, (mul D:$src1, D:$src2))]>;
  616. //===----------------------------------------------------------------------===//
  617. // Table C-18. External Exent Management Instructions
  618. //===----------------------------------------------------------------------===//
  619. def IDLE : F1<(outs), (ins), "idle;", [(int_bfin_idle)]>;
  620. def CSYNC : F1<(outs), (ins), "csync;", [(int_bfin_csync)]>;
  621. def SSYNC : F1<(outs), (ins), "ssync;", [(int_bfin_ssync)]>;
  622. def EMUEXCPT : F1<(outs), (ins), "emuexcpt;", []>;
  623. def CLI : F1<(outs D:$mask), (ins), "cli $mask;", []>;
  624. def STI : F1<(outs), (ins D:$mask), "sti $mask;", []>;
  625. def RAISE : F1<(outs), (ins i32imm:$itr), "raise $itr;", []>;
  626. def EXCPT : F1<(outs), (ins i32imm:$exc), "excpt $exc;", []>;
  627. def NOP : F1<(outs), (ins), "nop;", []>;
  628. def MNOP : F2<(outs), (ins), "mnop;", []>;
  629. def ABORT : F1<(outs), (ins), "abort;", []>;
  630. //===----------------------------------------------------------------------===//
  631. // Table C-19. Cache Control Instructions
  632. //===----------------------------------------------------------------------===//
  633. //===----------------------------------------------------------------------===//
  634. // Table C-20. Video Pixel Operations Instructions
  635. //===----------------------------------------------------------------------===//
  636. def ALIGN8 : F2<(outs D:$dst), (ins D:$src1, D:$src2),
  637. "$dst = align8($src1, $src2);",
  638. [(set D:$dst, (or (shl D:$src1, (i32 24)),
  639. (srl D:$src2, (i32 8))))]>;
  640. def ALIGN16 : F2<(outs D:$dst), (ins D:$src1, D:$src2),
  641. "$dst = align16($src1, $src2);",
  642. [(set D:$dst, (or (shl D:$src1, (i32 16)),
  643. (srl D:$src2, (i32 16))))]>;
  644. def ALIGN24 : F2<(outs D:$dst), (ins D:$src1, D:$src2),
  645. "$dst = align16($src1, $src2);",
  646. [(set D:$dst, (or (shl D:$src1, (i32 8)),
  647. (srl D:$src2, (i32 24))))]>;
  648. def DISALGNEXCPT : F2<(outs), (ins), "disalignexcpt;", []>;
  649. // TODO: BYTEOP3P, BYTEOP16P, BYTEOP1P, BYTEOP2P, BYTEOP16M, SAA,
  650. // BYTEPACK, BYTEUNPACK
  651. // Table C-21. Vector Operations Instructions
  652. // Patterns
  653. def : Pat<(BfinCall (i32 tglobaladdr:$dst)),
  654. (CALLa tglobaladdr:$dst)>;
  655. def : Pat<(BfinCall (i32 texternalsym:$dst)),
  656. (CALLa texternalsym:$dst)>;
  657. def : Pat<(i16 (trunc D:$src)),
  658. (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), lo16)>;