ARMInstrThumb.td 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  1. //===-- ARMInstrThumb.td - Thumb support for ARM -----------*- tablegen -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file describes the Thumb instruction set.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. //===----------------------------------------------------------------------===//
  13. // Thumb specific DAG Nodes.
  14. //
  15. def ARMtsecall : SDNode<"ARMISD::tSECALL", SDT_ARMcall,
  16. [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
  17. SDNPVariadic]>;
  18. def imm_sr_XFORM: SDNodeXForm<imm, [{
  19. unsigned Imm = N->getZExtValue();
  20. return CurDAG->getTargetConstant((Imm == 32 ? 0 : Imm), SDLoc(N), MVT::i32);
  21. }]>;
  22. def ThumbSRImmAsmOperand: ImmAsmOperand<1,32> { let Name = "ImmThumbSR"; }
  23. def imm_sr : Operand<i32>, PatLeaf<(imm), [{
  24. uint64_t Imm = N->getZExtValue();
  25. return Imm > 0 && Imm <= 32;
  26. }], imm_sr_XFORM> {
  27. let PrintMethod = "printThumbSRImm";
  28. let ParserMatchClass = ThumbSRImmAsmOperand;
  29. }
  30. def imm0_7_neg : PatLeaf<(i32 imm), [{
  31. return (uint32_t)-N->getZExtValue() < 8;
  32. }], imm_neg_XFORM>;
  33. def ThumbModImmNeg1_7AsmOperand : AsmOperandClass { let Name = "ThumbModImmNeg1_7"; }
  34. def mod_imm1_7_neg : Operand<i32>, PatLeaf<(imm), [{
  35. unsigned Value = -(unsigned)N->getZExtValue();
  36. return 0 < Value && Value < 8;
  37. }], imm_neg_XFORM> {
  38. let ParserMatchClass = ThumbModImmNeg1_7AsmOperand;
  39. }
  40. def ThumbModImmNeg8_255AsmOperand : AsmOperandClass { let Name = "ThumbModImmNeg8_255"; }
  41. def mod_imm8_255_neg : Operand<i32>, PatLeaf<(imm), [{
  42. unsigned Value = -(unsigned)N->getZExtValue();
  43. return 7 < Value && Value < 256;
  44. }], imm_neg_XFORM> {
  45. let ParserMatchClass = ThumbModImmNeg8_255AsmOperand;
  46. }
  47. def imm0_255_comp : PatLeaf<(i32 imm), [{
  48. return ~((uint32_t)N->getZExtValue()) < 256;
  49. }]>;
  50. def imm8_255_neg : PatLeaf<(i32 imm), [{
  51. unsigned Val = -N->getZExtValue();
  52. return Val >= 8 && Val < 256;
  53. }], imm_neg_XFORM>;
  54. // Break imm's up into two pieces: an immediate + a left shift. This uses
  55. // thumb_immshifted to match and thumb_immshifted_val and thumb_immshifted_shamt
  56. // to get the val/shift pieces.
  57. def thumb_immshifted : PatLeaf<(imm), [{
  58. return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue());
  59. }]>;
  60. def thumb_immshifted_val : SDNodeXForm<imm, [{
  61. unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue());
  62. return CurDAG->getTargetConstant(V, SDLoc(N), MVT::i32);
  63. }]>;
  64. def thumb_immshifted_shamt : SDNodeXForm<imm, [{
  65. unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue());
  66. return CurDAG->getTargetConstant(V, SDLoc(N), MVT::i32);
  67. }]>;
  68. def imm256_510 : ImmLeaf<i32, [{
  69. return Imm >= 256 && Imm < 511;
  70. }]>;
  71. def thumb_imm256_510_addend : SDNodeXForm<imm, [{
  72. return CurDAG->getTargetConstant(N->getZExtValue() - 255, SDLoc(N), MVT::i32);
  73. }]>;
  74. // Scaled 4 immediate.
  75. def t_imm0_1020s4_asmoperand: AsmOperandClass { let Name = "Imm0_1020s4"; }
  76. def t_imm0_1020s4 : Operand<i32> {
  77. let PrintMethod = "printThumbS4ImmOperand";
  78. let ParserMatchClass = t_imm0_1020s4_asmoperand;
  79. let OperandType = "OPERAND_IMMEDIATE";
  80. }
  81. def t_imm0_508s4_asmoperand: AsmOperandClass { let Name = "Imm0_508s4"; }
  82. def t_imm0_508s4 : Operand<i32> {
  83. let PrintMethod = "printThumbS4ImmOperand";
  84. let ParserMatchClass = t_imm0_508s4_asmoperand;
  85. let OperandType = "OPERAND_IMMEDIATE";
  86. }
  87. // Alias use only, so no printer is necessary.
  88. def t_imm0_508s4_neg_asmoperand: AsmOperandClass { let Name = "Imm0_508s4Neg"; }
  89. def t_imm0_508s4_neg : Operand<i32> {
  90. let ParserMatchClass = t_imm0_508s4_neg_asmoperand;
  91. let OperandType = "OPERAND_IMMEDIATE";
  92. }
  93. // Define Thumb specific addressing modes.
  94. // unsigned 8-bit, 2-scaled memory offset
  95. class OperandUnsignedOffset_b8s2 : AsmOperandClass {
  96. let Name = "UnsignedOffset_b8s2";
  97. let PredicateMethod = "isUnsignedOffset<8, 2>";
  98. }
  99. def UnsignedOffset_b8s2 : OperandUnsignedOffset_b8s2;
  100. // thumb style PC relative operand. signed, 8 bits magnitude,
  101. // two bits shift. can be represented as either [pc, #imm], #imm,
  102. // or relocatable expression...
  103. def ThumbMemPC : AsmOperandClass {
  104. let Name = "ThumbMemPC";
  105. }
  106. let OperandType = "OPERAND_PCREL" in {
  107. def t_brtarget : Operand<OtherVT> {
  108. let EncoderMethod = "getThumbBRTargetOpValue";
  109. let DecoderMethod = "DecodeThumbBROperand";
  110. }
  111. // ADR instruction labels.
  112. def t_adrlabel : Operand<i32> {
  113. let EncoderMethod = "getThumbAdrLabelOpValue";
  114. let PrintMethod = "printAdrLabelOperand<2>";
  115. let ParserMatchClass = UnsignedOffset_b8s2;
  116. }
  117. def thumb_br_target : Operand<OtherVT> {
  118. let ParserMatchClass = ThumbBranchTarget;
  119. let EncoderMethod = "getThumbBranchTargetOpValue";
  120. let OperandType = "OPERAND_PCREL";
  121. }
  122. def thumb_bl_target : Operand<i32> {
  123. let ParserMatchClass = ThumbBranchTarget;
  124. let EncoderMethod = "getThumbBLTargetOpValue";
  125. let DecoderMethod = "DecodeThumbBLTargetOperand";
  126. }
  127. // Target for BLX *from* thumb mode.
  128. def thumb_blx_target : Operand<i32> {
  129. let ParserMatchClass = ARMBranchTarget;
  130. let EncoderMethod = "getThumbBLXTargetOpValue";
  131. let DecoderMethod = "DecodeThumbBLXOffset";
  132. }
  133. def thumb_bcc_target : Operand<OtherVT> {
  134. let ParserMatchClass = ThumbBranchTarget;
  135. let EncoderMethod = "getThumbBCCTargetOpValue";
  136. let DecoderMethod = "DecodeThumbBCCTargetOperand";
  137. }
  138. def thumb_cb_target : Operand<OtherVT> {
  139. let ParserMatchClass = ThumbBranchTarget;
  140. let EncoderMethod = "getThumbCBTargetOpValue";
  141. let DecoderMethod = "DecodeThumbCmpBROperand";
  142. }
  143. } // OperandType = "OPERAND_PCREL"
  144. // t_addrmode_pc := <label> => pc + imm8 * 4
  145. //
  146. def t_addrmode_pc : MemOperand {
  147. let EncoderMethod = "getAddrModePCOpValue";
  148. let DecoderMethod = "DecodeThumbAddrModePC";
  149. let PrintMethod = "printThumbLdrLabelOperand";
  150. let ParserMatchClass = ThumbMemPC;
  151. }
  152. // t_addrmode_rr := reg + reg
  153. //
  154. def t_addrmode_rr_asm_operand : AsmOperandClass { let Name = "MemThumbRR"; }
  155. def t_addrmode_rr : MemOperand,
  156. ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> {
  157. let EncoderMethod = "getThumbAddrModeRegRegOpValue";
  158. let PrintMethod = "printThumbAddrModeRROperand";
  159. let DecoderMethod = "DecodeThumbAddrModeRR";
  160. let ParserMatchClass = t_addrmode_rr_asm_operand;
  161. let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
  162. }
  163. // t_addrmode_rr_sext := reg + reg
  164. //
  165. // This is similar to t_addrmode_rr, but uses different heuristics for
  166. // ldrsb/ldrsh.
  167. def t_addrmode_rr_sext : MemOperand,
  168. ComplexPattern<i32, 2, "SelectThumbAddrModeRRSext", []> {
  169. let EncoderMethod = "getThumbAddrModeRegRegOpValue";
  170. let PrintMethod = "printThumbAddrModeRROperand";
  171. let DecoderMethod = "DecodeThumbAddrModeRR";
  172. let ParserMatchClass = t_addrmode_rr_asm_operand;
  173. let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
  174. }
  175. // t_addrmode_rrs := reg + reg
  176. //
  177. // We use separate scaled versions because the Select* functions need
  178. // to explicitly check for a matching constant and return false here so that
  179. // the reg+imm forms will match instead. This is a horrible way to do that,
  180. // as it forces tight coupling between the methods, but it's how selectiondag
  181. // currently works.
  182. def t_addrmode_rrs1 : MemOperand,
  183. ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S1", []> {
  184. let EncoderMethod = "getThumbAddrModeRegRegOpValue";
  185. let PrintMethod = "printThumbAddrModeRROperand";
  186. let DecoderMethod = "DecodeThumbAddrModeRR";
  187. let ParserMatchClass = t_addrmode_rr_asm_operand;
  188. let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
  189. }
  190. def t_addrmode_rrs2 : MemOperand,
  191. ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S2", []> {
  192. let EncoderMethod = "getThumbAddrModeRegRegOpValue";
  193. let DecoderMethod = "DecodeThumbAddrModeRR";
  194. let PrintMethod = "printThumbAddrModeRROperand";
  195. let ParserMatchClass = t_addrmode_rr_asm_operand;
  196. let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
  197. }
  198. def t_addrmode_rrs4 : MemOperand,
  199. ComplexPattern<i32, 2, "SelectThumbAddrModeRI5S4", []> {
  200. let EncoderMethod = "getThumbAddrModeRegRegOpValue";
  201. let DecoderMethod = "DecodeThumbAddrModeRR";
  202. let PrintMethod = "printThumbAddrModeRROperand";
  203. let ParserMatchClass = t_addrmode_rr_asm_operand;
  204. let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
  205. }
  206. // t_addrmode_is4 := reg + imm5 * 4
  207. //
  208. def t_addrmode_is4_asm_operand : AsmOperandClass { let Name = "MemThumbRIs4"; }
  209. def t_addrmode_is4 : MemOperand,
  210. ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S4", []> {
  211. let EncoderMethod = "getAddrModeISOpValue";
  212. let DecoderMethod = "DecodeThumbAddrModeIS";
  213. let PrintMethod = "printThumbAddrModeImm5S4Operand";
  214. let ParserMatchClass = t_addrmode_is4_asm_operand;
  215. let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
  216. }
  217. // t_addrmode_is2 := reg + imm5 * 2
  218. //
  219. def t_addrmode_is2_asm_operand : AsmOperandClass { let Name = "MemThumbRIs2"; }
  220. def t_addrmode_is2 : MemOperand,
  221. ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S2", []> {
  222. let EncoderMethod = "getAddrModeISOpValue";
  223. let DecoderMethod = "DecodeThumbAddrModeIS";
  224. let PrintMethod = "printThumbAddrModeImm5S2Operand";
  225. let ParserMatchClass = t_addrmode_is2_asm_operand;
  226. let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
  227. }
  228. // t_addrmode_is1 := reg + imm5
  229. //
  230. def t_addrmode_is1_asm_operand : AsmOperandClass { let Name = "MemThumbRIs1"; }
  231. def t_addrmode_is1 : MemOperand,
  232. ComplexPattern<i32, 2, "SelectThumbAddrModeImm5S1", []> {
  233. let EncoderMethod = "getAddrModeISOpValue";
  234. let DecoderMethod = "DecodeThumbAddrModeIS";
  235. let PrintMethod = "printThumbAddrModeImm5S1Operand";
  236. let ParserMatchClass = t_addrmode_is1_asm_operand;
  237. let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
  238. }
  239. // t_addrmode_sp := sp + imm8 * 4
  240. //
  241. // FIXME: This really shouldn't have an explicit SP operand at all. It should
  242. // be implicit, just like in the instruction encoding itself.
  243. def t_addrmode_sp_asm_operand : AsmOperandClass { let Name = "MemThumbSPI"; }
  244. def t_addrmode_sp : MemOperand,
  245. ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
  246. let EncoderMethod = "getAddrModeThumbSPOpValue";
  247. let DecoderMethod = "DecodeThumbAddrModeSP";
  248. let PrintMethod = "printThumbAddrModeSPOperand";
  249. let ParserMatchClass = t_addrmode_sp_asm_operand;
  250. let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
  251. }
  252. // Inspects parent to determine whether an or instruction can be implemented as
  253. // an add (i.e. whether we know overflow won't occur in the add).
  254. def AddLikeOrOp : ComplexPattern<i32, 1, "SelectAddLikeOr", [],
  255. [SDNPWantParent]>;
  256. // Pattern to exclude immediates from matching
  257. def non_imm32 : PatLeaf<(i32 GPR), [{ return !isa<ConstantSDNode>(N); }]>;
  258. //===----------------------------------------------------------------------===//
  259. // Miscellaneous Instructions.
  260. //
  261. // FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE
  262. // from removing one half of the matched pairs. That breaks PEI, which assumes
  263. // these will always be in pairs, and asserts if it finds otherwise. Better way?
  264. let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
  265. def tADJCALLSTACKUP :
  266. PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
  267. [(ARMcallseq_end imm:$amt1, imm:$amt2)]>,
  268. Requires<[IsThumb, IsThumb1Only]>;
  269. def tADJCALLSTACKDOWN :
  270. PseudoInst<(outs), (ins i32imm:$amt, i32imm:$amt2), NoItinerary,
  271. [(ARMcallseq_start imm:$amt, imm:$amt2)]>,
  272. Requires<[IsThumb, IsThumb1Only]>;
  273. }
  274. class T1SystemEncoding<bits<8> opc>
  275. : T1Encoding<0b101111> {
  276. let Inst{9-8} = 0b11;
  277. let Inst{7-0} = opc;
  278. }
  279. def tHINT : T1pI<(outs), (ins imm0_15:$imm), NoItinerary, "hint", "\t$imm",
  280. [(int_arm_hint imm0_15:$imm)]>,
  281. T1SystemEncoding<0x00>,
  282. Requires<[IsThumb, HasV6M]> {
  283. bits<4> imm;
  284. let Inst{7-4} = imm;
  285. }
  286. // Note: When EmitPriority == 1, the alias will be used for printing
  287. class tHintAlias<string Asm, dag Result, bit EmitPriority = 0> : tInstAlias<Asm, Result, EmitPriority> {
  288. let Predicates = [IsThumb, HasV6M];
  289. }
  290. def : tHintAlias<"nop$p", (tHINT 0, pred:$p), 1>; // A8.6.110
  291. def : tHintAlias<"yield$p", (tHINT 1, pred:$p), 1>; // A8.6.410
  292. def : tHintAlias<"wfe$p", (tHINT 2, pred:$p), 1>; // A8.6.408
  293. def : tHintAlias<"wfi$p", (tHINT 3, pred:$p), 1>; // A8.6.409
  294. def : tHintAlias<"sev$p", (tHINT 4, pred:$p), 1>; // A8.6.157
  295. def : tInstAlias<"sevl$p", (tHINT 5, pred:$p), 1> {
  296. let Predicates = [IsThumb2, HasV8];
  297. }
  298. // The imm operand $val can be used by a debugger to store more information
  299. // about the breakpoint.
  300. def tBKPT : T1I<(outs), (ins imm0_255:$val), NoItinerary, "bkpt\t$val",
  301. []>,
  302. T1Encoding<0b101111> {
  303. let Inst{9-8} = 0b10;
  304. // A8.6.22
  305. bits<8> val;
  306. let Inst{7-0} = val;
  307. }
  308. // default immediate for breakpoint mnemonic
  309. def : InstAlias<"bkpt", (tBKPT 0), 0>, Requires<[IsThumb]>;
  310. def tHLT : T1I<(outs), (ins imm0_63:$val), NoItinerary, "hlt\t$val",
  311. []>, T1Encoding<0b101110>, Requires<[IsThumb, HasV8]> {
  312. let Inst{9-6} = 0b1010;
  313. bits<6> val;
  314. let Inst{5-0} = val;
  315. }
  316. def tSETEND : T1I<(outs), (ins setend_op:$end), NoItinerary, "setend\t$end",
  317. []>, T1Encoding<0b101101>, Requires<[IsThumb, IsNotMClass]>, Deprecated<HasV8Ops> {
  318. bits<1> end;
  319. // A8.6.156
  320. let Inst{9-5} = 0b10010;
  321. let Inst{4} = 1;
  322. let Inst{3} = end;
  323. let Inst{2-0} = 0b000;
  324. }
  325. // Change Processor State is a system instruction -- for disassembly only.
  326. def tCPS : T1I<(outs), (ins imod_op:$imod, iflags_op:$iflags),
  327. NoItinerary, "cps$imod $iflags", []>,
  328. T1Misc<0b0110011> {
  329. // A8.6.38 & B6.1.1
  330. bit imod;
  331. bits<3> iflags;
  332. let Inst{4} = imod;
  333. let Inst{3} = 0;
  334. let Inst{2-0} = iflags;
  335. let DecoderMethod = "DecodeThumbCPS";
  336. }
  337. // For both thumb1 and thumb2.
  338. let isNotDuplicable = 1, isCodeGenOnly = 1 in
  339. def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, "",
  340. [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>,
  341. T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
  342. // A8.6.6
  343. bits<3> dst;
  344. let Inst{6-3} = 0b1111; // Rm = pc
  345. let Inst{2-0} = dst;
  346. }
  347. // ADD <Rd>, sp, #<imm8>
  348. // FIXME: This should not be marked as having side effects, and it should be
  349. // rematerializable. Clearing the side effect bit causes miscompilations,
  350. // probably because the instruction can be moved around.
  351. def tADDrSPi : T1pI<(outs tGPR:$dst), (ins GPRsp:$sp, t_imm0_1020s4:$imm),
  352. IIC_iALUi, "add", "\t$dst, $sp, $imm", []>,
  353. T1Encoding<{1,0,1,0,1,?}>, Sched<[WriteALU]> {
  354. // A6.2 & A8.6.8
  355. bits<3> dst;
  356. bits<8> imm;
  357. let Inst{10-8} = dst;
  358. let Inst{7-0} = imm;
  359. let DecoderMethod = "DecodeThumbAddSpecialReg";
  360. }
  361. // Thumb1 frame lowering is rather fragile, we hope to be able to use
  362. // tADDrSPi, but we may need to insert a sequence that clobbers CPSR.
  363. def tADDframe : PseudoInst<(outs tGPR:$dst), (ins i32imm:$base, i32imm:$offset),
  364. NoItinerary, []>,
  365. Requires<[IsThumb, IsThumb1Only]> {
  366. let Defs = [CPSR];
  367. }
  368. // ADD sp, sp, #<imm7>
  369. def tADDspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
  370. IIC_iALUi, "add", "\t$Rdn, $imm", []>,
  371. T1Misc<{0,0,0,0,0,?,?}>, Sched<[WriteALU]> {
  372. // A6.2.5 & A8.6.8
  373. bits<7> imm;
  374. let Inst{6-0} = imm;
  375. let DecoderMethod = "DecodeThumbAddSPImm";
  376. }
  377. // SUB sp, sp, #<imm7>
  378. // FIXME: The encoding and the ASM string don't match up.
  379. def tSUBspi : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, t_imm0_508s4:$imm),
  380. IIC_iALUi, "sub", "\t$Rdn, $imm", []>,
  381. T1Misc<{0,0,0,0,1,?,?}>, Sched<[WriteALU]> {
  382. // A6.2.5 & A8.6.214
  383. bits<7> imm;
  384. let Inst{6-0} = imm;
  385. let DecoderMethod = "DecodeThumbAddSPImm";
  386. }
  387. def : tInstSubst<"add${p} sp, $imm",
  388. (tSUBspi SP, t_imm0_508s4_neg:$imm, pred:$p)>;
  389. def : tInstSubst<"add${p} sp, sp, $imm",
  390. (tSUBspi SP, t_imm0_508s4_neg:$imm, pred:$p)>;
  391. // Can optionally specify SP as a three operand instruction.
  392. def : tInstAlias<"add${p} sp, sp, $imm",
  393. (tADDspi SP, t_imm0_508s4:$imm, pred:$p)>;
  394. def : tInstAlias<"sub${p} sp, sp, $imm",
  395. (tSUBspi SP, t_imm0_508s4:$imm, pred:$p)>;
  396. // ADD <Rm>, sp
  397. def tADDrSP : T1pI<(outs GPR:$Rdn), (ins GPRsp:$sp, GPR:$Rn), IIC_iALUr,
  398. "add", "\t$Rdn, $sp, $Rn", []>,
  399. T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
  400. // A8.6.9 Encoding T1
  401. bits<4> Rdn;
  402. let Inst{7} = Rdn{3};
  403. let Inst{6-3} = 0b1101;
  404. let Inst{2-0} = Rdn{2-0};
  405. let DecoderMethod = "DecodeThumbAddSPReg";
  406. }
  407. // ADD sp, <Rm>
  408. def tADDspr : T1pIt<(outs GPRsp:$Rdn), (ins GPRsp:$Rn, GPR:$Rm), IIC_iALUr,
  409. "add", "\t$Rdn, $Rm", []>,
  410. T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
  411. // A8.6.9 Encoding T2
  412. bits<4> Rm;
  413. let Inst{7} = 1;
  414. let Inst{6-3} = Rm;
  415. let Inst{2-0} = 0b101;
  416. let DecoderMethod = "DecodeThumbAddSPReg";
  417. }
  418. //===----------------------------------------------------------------------===//
  419. // Control Flow Instructions.
  420. //
  421. // Indirect branches
  422. let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
  423. def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>,
  424. T1Special<{1,1,0,?}>, Sched<[WriteBr]> {
  425. // A6.2.3 & A8.6.25
  426. bits<4> Rm;
  427. let Inst{6-3} = Rm;
  428. let Inst{2-0} = 0b000;
  429. let Unpredictable{2-0} = 0b111;
  430. }
  431. def tBXNS : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bxns${p}\t$Rm", []>,
  432. Requires<[IsThumb, Has8MSecExt]>,
  433. T1Special<{1,1,0,?}>, Sched<[WriteBr]> {
  434. bits<4> Rm;
  435. let Inst{6-3} = Rm;
  436. let Inst{2-0} = 0b100;
  437. let Unpredictable{1-0} = 0b11;
  438. }
  439. }
  440. let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
  441. def tBX_RET : tPseudoExpand<(outs), (ins pred:$p), 2, IIC_Br,
  442. [(ARMretflag)], (tBX LR, pred:$p)>, Sched<[WriteBr]>;
  443. // alternative return for CMSE entry functions
  444. def tBXNS_RET : tPseudoInst<(outs), (ins), 2, IIC_Br,
  445. [(ARMseretflag)]>, Sched<[WriteBr]>;
  446. // Alternative return instruction used by vararg functions.
  447. def tBX_RET_vararg : tPseudoExpand<(outs), (ins tGPR:$Rm, pred:$p),
  448. 2, IIC_Br, [],
  449. (tBX GPR:$Rm, pred:$p)>, Sched<[WriteBr]>;
  450. }
  451. // All calls clobber the non-callee saved registers. SP is marked as a use to
  452. // prevent stack-pointer assignments that appear immediately before calls from
  453. // potentially appearing dead.
  454. let isCall = 1,
  455. Defs = [LR], Uses = [SP] in {
  456. // Also used for Thumb2
  457. def tBL : TIx2<0b11110, 0b11, 1,
  458. (outs), (ins pred:$p, thumb_bl_target:$func), IIC_Br,
  459. "bl${p}\t$func",
  460. [(ARMcall tglobaladdr:$func)]>,
  461. Requires<[IsThumb]>, Sched<[WriteBrL]> {
  462. bits<24> func;
  463. let Inst{26} = func{23};
  464. let Inst{25-16} = func{20-11};
  465. let Inst{13} = func{22};
  466. let Inst{11} = func{21};
  467. let Inst{10-0} = func{10-0};
  468. }
  469. // ARMv5T and above, also used for Thumb2
  470. def tBLXi : TIx2<0b11110, 0b11, 0,
  471. (outs), (ins pred:$p, thumb_blx_target:$func), IIC_Br,
  472. "blx${p}\t$func", []>,
  473. Requires<[IsThumb, HasV5T, IsNotMClass]>, Sched<[WriteBrL]> {
  474. bits<24> func;
  475. let Inst{26} = func{23};
  476. let Inst{25-16} = func{20-11};
  477. let Inst{13} = func{22};
  478. let Inst{11} = func{21};
  479. let Inst{10-1} = func{10-1};
  480. let Inst{0} = 0; // func{0} is assumed zero
  481. }
  482. // Also used for Thumb2
  483. def tBLXr : TI<(outs), (ins pred:$p, GPR:$func), IIC_Br,
  484. "blx${p}\t$func", []>,
  485. Requires<[IsThumb, HasV5T]>,
  486. T1Special<{1,1,1,?}>, Sched<[WriteBrL]> { // A6.2.3 & A8.6.24;
  487. bits<4> func;
  488. let Inst{6-3} = func;
  489. let Inst{2-0} = 0b000;
  490. }
  491. def tBLXr_noip : ARMPseudoExpand<(outs), (ins pred:$p, GPRnoip:$func),
  492. 2, IIC_Br, [], (tBLXr pred:$p, GPR:$func)>,
  493. Requires<[IsThumb, HasV5T]>,
  494. Sched<[WriteBrL]>;
  495. // ARMv8-M Security Extensions
  496. def tBLXNSr : TI<(outs), (ins pred:$p, GPRnopc:$func), IIC_Br,
  497. "blxns${p}\t$func", []>,
  498. Requires<[IsThumb, Has8MSecExt]>,
  499. T1Special<{1,1,1,?}>, Sched<[WriteBrL]> {
  500. bits<4> func;
  501. let Inst{6-3} = func;
  502. let Inst{2-0} = 0b100;
  503. let Unpredictable{1-0} = 0b11;
  504. }
  505. def tBLXNS_CALL : PseudoInst<(outs), (ins GPRnopc:$func), IIC_Br,
  506. [(ARMtsecall GPRnopc:$func)]>,
  507. Requires<[IsThumb, Has8MSecExt]>, Sched<[WriteBr]>;
  508. // ARMv4T
  509. def tBX_CALL : tPseudoInst<(outs), (ins tGPR:$func),
  510. 4, IIC_Br,
  511. [(ARMcall_nolink tGPR:$func)]>,
  512. Requires<[IsThumb, IsThumb1Only]>, Sched<[WriteBr]>;
  513. // Also used for Thumb2
  514. // push lr before the call
  515. def tBL_PUSHLR : tPseudoInst<(outs), (ins GPRlr:$ra, pred:$p, thumb_bl_target:$func),
  516. 4, IIC_Br,
  517. []>,
  518. Requires<[IsThumb]>, Sched<[WriteBr]>;
  519. }
  520. def : ARMPat<(ARMcall GPR:$func), (tBLXr $func)>,
  521. Requires<[IsThumb, HasV5T, NoSLSBLRMitigation]>;
  522. def : ARMPat<(ARMcall GPRnoip:$func), (tBLXr_noip $func)>,
  523. Requires<[IsThumb, HasV5T, SLSBLRMitigation]>;
  524. let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
  525. let isPredicable = 1 in
  526. def tB : T1pI<(outs), (ins t_brtarget:$target), IIC_Br,
  527. "b", "\t$target", [(br bb:$target)]>,
  528. T1Encoding<{1,1,1,0,0,?}>, Sched<[WriteBr]> {
  529. bits<11> target;
  530. let Inst{10-0} = target;
  531. let AsmMatchConverter = "cvtThumbBranches";
  532. }
  533. // Far jump
  534. // Just a pseudo for a tBL instruction. Needed to let regalloc know about
  535. // the clobber of LR.
  536. let Defs = [LR] in
  537. def tBfar : tPseudoExpand<(outs), (ins thumb_bl_target:$target, pred:$p),
  538. 4, IIC_Br, [],
  539. (tBL pred:$p, thumb_bl_target:$target)>,
  540. Sched<[WriteBrTbl]>;
  541. def tBR_JTr : tPseudoInst<(outs),
  542. (ins tGPR:$target, i32imm:$jt),
  543. 0, IIC_Br,
  544. [(ARMbrjt tGPR:$target, tjumptable:$jt)]>,
  545. Sched<[WriteBrTbl]> {
  546. let Size = 2;
  547. let isNotDuplicable = 1;
  548. list<Predicate> Predicates = [IsThumb, IsThumb1Only];
  549. }
  550. }
  551. // FIXME: should be able to write a pattern for ARMBrcond, but can't use
  552. // a two-value operand where a dag node expects two operands. :(
  553. let isBranch = 1, isTerminator = 1 in
  554. def tBcc : T1I<(outs), (ins thumb_bcc_target:$target, pred:$p), IIC_Br,
  555. "b${p}\t$target",
  556. [/*(ARMbrcond bb:$target, imm:$cc)*/]>,
  557. T1BranchCond<{1,1,0,1}>, Sched<[WriteBr]> {
  558. bits<4> p;
  559. bits<8> target;
  560. let Inst{11-8} = p;
  561. let Inst{7-0} = target;
  562. let AsmMatchConverter = "cvtThumbBranches";
  563. }
  564. // Tail calls
  565. let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
  566. // IOS versions.
  567. let Uses = [SP] in {
  568. def tTAILJMPr : tPseudoExpand<(outs), (ins tcGPR:$dst),
  569. 4, IIC_Br, [],
  570. (tBX GPR:$dst, (ops 14, zero_reg))>,
  571. Requires<[IsThumb]>, Sched<[WriteBr]>;
  572. }
  573. // tTAILJMPd: MachO version uses a Thumb2 branch (no Thumb1 tail calls
  574. // on MachO), so it's in ARMInstrThumb2.td.
  575. // Non-MachO version:
  576. let Uses = [SP] in {
  577. def tTAILJMPdND : tPseudoExpand<(outs),
  578. (ins t_brtarget:$dst, pred:$p),
  579. 4, IIC_Br, [],
  580. (tB t_brtarget:$dst, pred:$p)>,
  581. Requires<[IsThumb, IsNotMachO]>, Sched<[WriteBr]>;
  582. }
  583. }
  584. // A8.6.218 Supervisor Call (Software Interrupt)
  585. // A8.6.16 B: Encoding T1
  586. // If Inst{11-8} == 0b1111 then SEE SVC
  587. let isCall = 1, Uses = [SP] in
  588. def tSVC : T1pI<(outs), (ins imm0_255:$imm), IIC_Br,
  589. "svc", "\t$imm", []>, Encoding16, Sched<[WriteBr]> {
  590. bits<8> imm;
  591. let Inst{15-12} = 0b1101;
  592. let Inst{11-8} = 0b1111;
  593. let Inst{7-0} = imm;
  594. }
  595. // The assembler uses 0xDEFE for a trap instruction.
  596. let isBarrier = 1, isTerminator = 1 in
  597. def tTRAP : TI<(outs), (ins), IIC_Br,
  598. "trap", [(trap)]>, Encoding16, Sched<[WriteBr]> {
  599. let Inst = 0xdefe;
  600. }
  601. //===----------------------------------------------------------------------===//
  602. // Load Store Instructions.
  603. //
  604. // PC-relative loads need to be matched first as constant pool accesses need to
  605. // always be PC-relative. We do this using AddedComplexity, as the pattern is
  606. // simpler than the patterns of the other load instructions.
  607. let canFoldAsLoad = 1, isReMaterializable = 1, AddedComplexity = 10 in
  608. def tLDRpci : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_pc:$addr), IIC_iLoad_i,
  609. "ldr", "\t$Rt, $addr",
  610. [(set tGPR:$Rt, (load (ARMWrapper tconstpool:$addr)))]>,
  611. T1Encoding<{0,1,0,0,1,?}>, Sched<[WriteLd]> {
  612. // A6.2 & A8.6.59
  613. bits<3> Rt;
  614. bits<8> addr;
  615. let Inst{10-8} = Rt;
  616. let Inst{7-0} = addr;
  617. }
  618. // SP-relative loads should be matched before standard immediate-offset loads as
  619. // it means we avoid having to move SP to another register.
  620. let canFoldAsLoad = 1 in
  621. def tLDRspi : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_sp:$addr), IIC_iLoad_i,
  622. "ldr", "\t$Rt, $addr",
  623. [(set tGPR:$Rt, (load t_addrmode_sp:$addr))]>,
  624. T1LdStSP<{1,?,?}>, Sched<[WriteLd]> {
  625. bits<3> Rt;
  626. bits<8> addr;
  627. let Inst{10-8} = Rt;
  628. let Inst{7-0} = addr;
  629. }
  630. // Loads: reg/reg and reg/imm5
  631. let canFoldAsLoad = 1, isReMaterializable = 1 in
  632. multiclass thumb_ld_rr_ri_enc<bits<3> reg_opc, bits<4> imm_opc,
  633. Operand AddrMode_r, Operand AddrMode_i,
  634. AddrMode am, InstrItinClass itin_r,
  635. InstrItinClass itin_i, string asm,
  636. PatFrag opnode> {
  637. // Immediate-offset loads should be matched before register-offset loads as
  638. // when the offset is a constant it's simpler to first check if it fits in the
  639. // immediate offset field then fall back to register-offset if it doesn't.
  640. def i : // reg/imm5
  641. T1pILdStEncodeImm<imm_opc, 1 /* Load */,
  642. (outs tGPR:$Rt), (ins AddrMode_i:$addr),
  643. am, itin_i, asm, "\t$Rt, $addr",
  644. [(set tGPR:$Rt, (opnode AddrMode_i:$addr))]>;
  645. // Register-offset loads are matched last.
  646. def r : // reg/reg
  647. T1pILdStEncode<reg_opc,
  648. (outs tGPR:$Rt), (ins AddrMode_r:$addr),
  649. am, itin_r, asm, "\t$Rt, $addr",
  650. [(set tGPR:$Rt, (opnode AddrMode_r:$addr))]>;
  651. }
  652. // Stores: reg/reg and reg/imm5
  653. multiclass thumb_st_rr_ri_enc<bits<3> reg_opc, bits<4> imm_opc,
  654. Operand AddrMode_r, Operand AddrMode_i,
  655. AddrMode am, InstrItinClass itin_r,
  656. InstrItinClass itin_i, string asm,
  657. PatFrag opnode> {
  658. def i : // reg/imm5
  659. T1pILdStEncodeImm<imm_opc, 0 /* Store */,
  660. (outs), (ins tGPR:$Rt, AddrMode_i:$addr),
  661. am, itin_i, asm, "\t$Rt, $addr",
  662. [(opnode tGPR:$Rt, AddrMode_i:$addr)]>;
  663. def r : // reg/reg
  664. T1pILdStEncode<reg_opc,
  665. (outs), (ins tGPR:$Rt, AddrMode_r:$addr),
  666. am, itin_r, asm, "\t$Rt, $addr",
  667. [(opnode tGPR:$Rt, AddrMode_r:$addr)]>;
  668. }
  669. // A8.6.57 & A8.6.60
  670. defm tLDR : thumb_ld_rr_ri_enc<0b100, 0b0110, t_addrmode_rr,
  671. t_addrmode_is4, AddrModeT1_4,
  672. IIC_iLoad_r, IIC_iLoad_i, "ldr",
  673. load>, Sched<[WriteLd]>;
  674. // A8.6.64 & A8.6.61
  675. defm tLDRB : thumb_ld_rr_ri_enc<0b110, 0b0111, t_addrmode_rr,
  676. t_addrmode_is1, AddrModeT1_1,
  677. IIC_iLoad_bh_r, IIC_iLoad_bh_i, "ldrb",
  678. zextloadi8>, Sched<[WriteLd]>;
  679. // A8.6.76 & A8.6.73
  680. defm tLDRH : thumb_ld_rr_ri_enc<0b101, 0b1000, t_addrmode_rr,
  681. t_addrmode_is2, AddrModeT1_2,
  682. IIC_iLoad_bh_r, IIC_iLoad_bh_i, "ldrh",
  683. zextloadi16>, Sched<[WriteLd]>;
  684. let AddedComplexity = 10 in
  685. def tLDRSB : // A8.6.80
  686. T1pILdStEncode<0b011, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
  687. AddrModeT1_1, IIC_iLoad_bh_r,
  688. "ldrsb", "\t$Rt, $addr",
  689. [(set tGPR:$Rt, (sextloadi8 t_addrmode_rr_sext:$addr))]>, Sched<[WriteLd]>;
  690. let AddedComplexity = 10 in
  691. def tLDRSH : // A8.6.84
  692. T1pILdStEncode<0b111, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
  693. AddrModeT1_2, IIC_iLoad_bh_r,
  694. "ldrsh", "\t$Rt, $addr",
  695. [(set tGPR:$Rt, (sextloadi16 t_addrmode_rr_sext:$addr))]>, Sched<[WriteLd]>;
  696. def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,
  697. "str", "\t$Rt, $addr",
  698. [(store tGPR:$Rt, t_addrmode_sp:$addr)]>,
  699. T1LdStSP<{0,?,?}>, Sched<[WriteST]> {
  700. bits<3> Rt;
  701. bits<8> addr;
  702. let Inst{10-8} = Rt;
  703. let Inst{7-0} = addr;
  704. }
  705. // A8.6.194 & A8.6.192
  706. defm tSTR : thumb_st_rr_ri_enc<0b000, 0b0110, t_addrmode_rr,
  707. t_addrmode_is4, AddrModeT1_4,
  708. IIC_iStore_r, IIC_iStore_i, "str",
  709. store>, Sched<[WriteST]>;
  710. // A8.6.197 & A8.6.195
  711. defm tSTRB : thumb_st_rr_ri_enc<0b010, 0b0111, t_addrmode_rr,
  712. t_addrmode_is1, AddrModeT1_1,
  713. IIC_iStore_bh_r, IIC_iStore_bh_i, "strb",
  714. truncstorei8>, Sched<[WriteST]>;
  715. // A8.6.207 & A8.6.205
  716. defm tSTRH : thumb_st_rr_ri_enc<0b001, 0b1000, t_addrmode_rr,
  717. t_addrmode_is2, AddrModeT1_2,
  718. IIC_iStore_bh_r, IIC_iStore_bh_i, "strh",
  719. truncstorei16>, Sched<[WriteST]>;
  720. //===----------------------------------------------------------------------===//
  721. // Load / store multiple Instructions.
  722. //
  723. // These require base address to be written back or one of the loaded regs.
  724. let hasSideEffects = 0 in {
  725. let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
  726. def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  727. IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> {
  728. bits<3> Rn;
  729. bits<8> regs;
  730. let Inst{10-8} = Rn;
  731. let Inst{7-0} = regs;
  732. }
  733. // Writeback version is just a pseudo, as there's no encoding difference.
  734. // Writeback happens iff the base register is not in the destination register
  735. // list.
  736. let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
  737. def tLDMIA_UPD :
  738. InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
  739. "$Rn = $wb", IIC_iLoad_mu>,
  740. PseudoInstExpansion<(tLDMIA tGPR:$Rn, pred:$p, reglist:$regs)> {
  741. let Size = 2;
  742. let OutOperandList = (outs tGPR:$wb);
  743. let InOperandList = (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops);
  744. let Pattern = [];
  745. let isCodeGenOnly = 1;
  746. let isPseudo = 1;
  747. list<Predicate> Predicates = [IsThumb];
  748. }
  749. // There is no non-writeback version of STM for Thumb.
  750. let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
  751. def tSTMIA_UPD : Thumb1I<(outs tGPR:$wb),
  752. (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
  753. AddrModeNone, 2, IIC_iStore_mu,
  754. "stm${p}\t$Rn!, $regs", "$Rn = $wb", []>,
  755. T1Encoding<{1,1,0,0,0,?}> {
  756. bits<3> Rn;
  757. bits<8> regs;
  758. let Inst{10-8} = Rn;
  759. let Inst{7-0} = regs;
  760. }
  761. } // hasSideEffects
  762. def : InstAlias<"ldm${p} $Rn!, $regs",
  763. (tLDMIA tGPR:$Rn, pred:$p, reglist:$regs), 0>,
  764. Requires<[IsThumb, IsThumb1Only]>;
  765. let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1,
  766. variadicOpsAreDefs = 1 in
  767. def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
  768. IIC_iPop,
  769. "pop${p}\t$regs", []>,
  770. T1Misc<{1,1,0,?,?,?,?}>, Sched<[WriteLd]> {
  771. bits<16> regs;
  772. let Inst{8} = regs{15};
  773. let Inst{7-0} = regs{7-0};
  774. }
  775. let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
  776. def tPUSH : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops),
  777. IIC_iStore_m,
  778. "push${p}\t$regs", []>,
  779. T1Misc<{0,1,0,?,?,?,?}>, Sched<[WriteST]> {
  780. bits<16> regs;
  781. let Inst{8} = regs{14};
  782. let Inst{7-0} = regs{7-0};
  783. }
  784. //===----------------------------------------------------------------------===//
  785. // Arithmetic Instructions.
  786. //
  787. // Helper classes for encoding T1pI patterns:
  788. class T1pIDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
  789. string opc, string asm, list<dag> pattern>
  790. : T1pI<oops, iops, itin, opc, asm, pattern>,
  791. T1DataProcessing<opA> {
  792. bits<3> Rm;
  793. bits<3> Rn;
  794. let Inst{5-3} = Rm;
  795. let Inst{2-0} = Rn;
  796. }
  797. class T1pIMiscEncode<bits<7> opA, dag oops, dag iops, InstrItinClass itin,
  798. string opc, string asm, list<dag> pattern>
  799. : T1pI<oops, iops, itin, opc, asm, pattern>,
  800. T1Misc<opA> {
  801. bits<3> Rm;
  802. bits<3> Rd;
  803. let Inst{5-3} = Rm;
  804. let Inst{2-0} = Rd;
  805. }
  806. // Helper classes for encoding T1sI patterns:
  807. class T1sIDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
  808. string opc, string asm, list<dag> pattern>
  809. : T1sI<oops, iops, itin, opc, asm, pattern>,
  810. T1DataProcessing<opA> {
  811. bits<3> Rd;
  812. bits<3> Rn;
  813. let Inst{5-3} = Rn;
  814. let Inst{2-0} = Rd;
  815. }
  816. class T1sIGenEncode<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
  817. string opc, string asm, list<dag> pattern>
  818. : T1sI<oops, iops, itin, opc, asm, pattern>,
  819. T1General<opA> {
  820. bits<3> Rm;
  821. bits<3> Rn;
  822. bits<3> Rd;
  823. let Inst{8-6} = Rm;
  824. let Inst{5-3} = Rn;
  825. let Inst{2-0} = Rd;
  826. }
  827. class T1sIGenEncodeImm<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
  828. string opc, string asm, list<dag> pattern>
  829. : T1sI<oops, iops, itin, opc, asm, pattern>,
  830. T1General<opA> {
  831. bits<3> Rd;
  832. bits<3> Rm;
  833. let Inst{5-3} = Rm;
  834. let Inst{2-0} = Rd;
  835. }
  836. // Helper classes for encoding T1sIt patterns:
  837. class T1sItDPEncode<bits<4> opA, dag oops, dag iops, InstrItinClass itin,
  838. string opc, string asm, list<dag> pattern>
  839. : T1sIt<oops, iops, itin, opc, asm, pattern>,
  840. T1DataProcessing<opA> {
  841. bits<3> Rdn;
  842. bits<3> Rm;
  843. let Inst{5-3} = Rm;
  844. let Inst{2-0} = Rdn;
  845. }
  846. class T1sItGenEncodeImm<bits<5> opA, dag oops, dag iops, InstrItinClass itin,
  847. string opc, string asm, list<dag> pattern>
  848. : T1sIt<oops, iops, itin, opc, asm, pattern>,
  849. T1General<opA> {
  850. bits<3> Rdn;
  851. bits<8> imm8;
  852. let Inst{10-8} = Rdn;
  853. let Inst{7-0} = imm8;
  854. }
  855. let isAdd = 1 in {
  856. // Add with carry register
  857. let isCommutable = 1, Uses = [CPSR] in
  858. def tADC : // A8.6.2
  859. T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr,
  860. "adc", "\t$Rdn, $Rm",
  861. []>, Sched<[WriteALU]>;
  862. // Add immediate
  863. def tADDi3 : // A8.6.4 T1
  864. T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
  865. IIC_iALUi,
  866. "add", "\t$Rd, $Rm, $imm3",
  867. [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>,
  868. Sched<[WriteALU]> {
  869. bits<3> imm3;
  870. let Inst{8-6} = imm3;
  871. }
  872. def tADDi8 : // A8.6.4 T2
  873. T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn),
  874. (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
  875. "add", "\t$Rdn, $imm8",
  876. [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>,
  877. Sched<[WriteALU]>;
  878. // Add register
  879. let isCommutable = 1 in
  880. def tADDrr : // A8.6.6 T1
  881. T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
  882. IIC_iALUr,
  883. "add", "\t$Rd, $Rn, $Rm",
  884. [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
  885. /// Similar to the above except these set the 's' bit so the
  886. /// instruction modifies the CPSR register.
  887. ///
  888. /// These opcodes will be converted to the real non-S opcodes by
  889. /// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
  890. let hasPostISelHook = 1, Defs = [CPSR] in {
  891. let isCommutable = 1, Uses = [CPSR] in
  892. def tADCS : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  893. 2, IIC_iALUr,
  894. [(set tGPR:$Rdn, CPSR, (ARMadde tGPR:$Rn, tGPR:$Rm,
  895. CPSR))]>,
  896. Requires<[IsThumb1Only]>,
  897. Sched<[WriteALU]>;
  898. def tADDSi3 : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
  899. 2, IIC_iALUi,
  900. [(set tGPR:$Rd, CPSR, (ARMaddc tGPR:$Rm,
  901. imm0_7:$imm3))]>,
  902. Requires<[IsThumb1Only]>,
  903. Sched<[WriteALU]>;
  904. def tADDSi8 : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, imm0_255:$imm8),
  905. 2, IIC_iALUi,
  906. [(set tGPR:$Rdn, CPSR, (ARMaddc tGPR:$Rn,
  907. imm8_255:$imm8))]>,
  908. Requires<[IsThumb1Only]>,
  909. Sched<[WriteALU]>;
  910. let isCommutable = 1 in
  911. def tADDSrr : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
  912. 2, IIC_iALUr,
  913. [(set tGPR:$Rd, CPSR, (ARMaddc tGPR:$Rn,
  914. tGPR:$Rm))]>,
  915. Requires<[IsThumb1Only]>,
  916. Sched<[WriteALU]>;
  917. }
  918. let hasSideEffects = 0 in
  919. def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr,
  920. "add", "\t$Rdn, $Rm", []>,
  921. T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
  922. // A8.6.6 T2
  923. bits<4> Rdn;
  924. bits<4> Rm;
  925. let Inst{7} = Rdn{3};
  926. let Inst{6-3} = Rm;
  927. let Inst{2-0} = Rdn{2-0};
  928. }
  929. }
  930. // Thumb has more flexible short encodings for ADD than ORR, so use those where
  931. // possible.
  932. def : T1Pat<(or AddLikeOrOp:$Rn, imm0_7:$imm), (tADDi3 $Rn, imm0_7:$imm)>;
  933. def : T1Pat<(or AddLikeOrOp:$Rn, imm8_255:$imm), (tADDi8 $Rn, imm8_255:$imm)>;
  934. def : T1Pat<(or AddLikeOrOp:$Rn, tGPR:$Rm), (tADDrr $Rn, $Rm)>;
  935. def : tInstAlias <"add${s}${p} $Rdn, $Rm",
  936. (tADDrr tGPR:$Rdn,s_cc_out:$s, tGPR:$Rdn, tGPR:$Rm, pred:$p)>;
  937. def : tInstSubst<"sub${s}${p} $rd, $rn, $imm",
  938. (tADDi3 tGPR:$rd, s_cc_out:$s, tGPR:$rn, mod_imm1_7_neg:$imm, pred:$p)>;
  939. def : tInstSubst<"sub${s}${p} $rdn, $imm",
  940. (tADDi8 tGPR:$rdn, s_cc_out:$s, mod_imm8_255_neg:$imm, pred:$p)>;
  941. // AND register
  942. let isCommutable = 1 in
  943. def tAND : // A8.6.12
  944. T1sItDPEncode<0b0000, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  945. IIC_iBITr,
  946. "and", "\t$Rdn, $Rm",
  947. [(set tGPR:$Rdn, (and tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
  948. // ASR immediate
  949. def tASRri : // A8.6.14
  950. T1sIGenEncodeImm<{0,1,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5),
  951. IIC_iMOVsi,
  952. "asr", "\t$Rd, $Rm, $imm5",
  953. [(set tGPR:$Rd, (sra tGPR:$Rm, (i32 imm_sr:$imm5)))]>,
  954. Sched<[WriteALU]> {
  955. bits<5> imm5;
  956. let Inst{10-6} = imm5;
  957. }
  958. // ASR register
  959. def tASRrr : // A8.6.15
  960. T1sItDPEncode<0b0100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  961. IIC_iMOVsr,
  962. "asr", "\t$Rdn, $Rm",
  963. [(set tGPR:$Rdn, (sra tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
  964. // BIC register
  965. def tBIC : // A8.6.20
  966. T1sItDPEncode<0b1110, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  967. IIC_iBITr,
  968. "bic", "\t$Rdn, $Rm",
  969. [(set tGPR:$Rdn, (and tGPR:$Rn, (not tGPR:$Rm)))]>,
  970. Sched<[WriteALU]>;
  971. // CMN register
  972. let isCompare = 1, Defs = [CPSR] in {
  973. //FIXME: Disable CMN, as CCodes are backwards from compare expectations
  974. // Compare-to-zero still works out, just not the relationals
  975. //def tCMN : // A8.6.33
  976. // T1pIDPEncode<0b1011, (outs), (ins tGPR:$lhs, tGPR:$rhs),
  977. // IIC_iCMPr,
  978. // "cmn", "\t$lhs, $rhs",
  979. // [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
  980. def tCMNz : // A8.6.33
  981. T1pIDPEncode<0b1011, (outs), (ins tGPR:$Rn, tGPR:$Rm),
  982. IIC_iCMPr,
  983. "cmn", "\t$Rn, $Rm",
  984. [(ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm))]>, Sched<[WriteCMP]>;
  985. } // isCompare = 1, Defs = [CPSR]
  986. // CMP immediate
  987. let isCompare = 1, Defs = [CPSR] in {
  988. def tCMPi8 : T1pI<(outs), (ins tGPR:$Rn, imm0_255:$imm8), IIC_iCMPi,
  989. "cmp", "\t$Rn, $imm8",
  990. [(ARMcmp tGPR:$Rn, imm0_255:$imm8)]>,
  991. T1General<{1,0,1,?,?}>, Sched<[WriteCMP]> {
  992. // A8.6.35
  993. bits<3> Rn;
  994. bits<8> imm8;
  995. let Inst{10-8} = Rn;
  996. let Inst{7-0} = imm8;
  997. }
  998. // CMP register
  999. def tCMPr : // A8.6.36 T1
  1000. T1pIDPEncode<0b1010, (outs), (ins tGPR:$Rn, tGPR:$Rm),
  1001. IIC_iCMPr,
  1002. "cmp", "\t$Rn, $Rm",
  1003. [(ARMcmp tGPR:$Rn, tGPR:$Rm)]>, Sched<[WriteCMP]>;
  1004. def tCMPhir : T1pI<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_iCMPr,
  1005. "cmp", "\t$Rn, $Rm", []>,
  1006. T1Special<{0,1,?,?}>, Sched<[WriteCMP]> {
  1007. // A8.6.36 T2
  1008. bits<4> Rm;
  1009. bits<4> Rn;
  1010. let Inst{7} = Rn{3};
  1011. let Inst{6-3} = Rm;
  1012. let Inst{2-0} = Rn{2-0};
  1013. }
  1014. } // isCompare = 1, Defs = [CPSR]
  1015. // XOR register
  1016. let isCommutable = 1 in
  1017. def tEOR : // A8.6.45
  1018. T1sItDPEncode<0b0001, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  1019. IIC_iBITr,
  1020. "eor", "\t$Rdn, $Rm",
  1021. [(set tGPR:$Rdn, (xor tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
  1022. // LSL immediate
  1023. def tLSLri : // A8.6.88
  1024. T1sIGenEncodeImm<{0,0,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_31:$imm5),
  1025. IIC_iMOVsi,
  1026. "lsl", "\t$Rd, $Rm, $imm5",
  1027. [(set tGPR:$Rd, (shl tGPR:$Rm, (i32 imm:$imm5)))]>,
  1028. Sched<[WriteALU]> {
  1029. bits<5> imm5;
  1030. let Inst{10-6} = imm5;
  1031. }
  1032. // LSL register
  1033. def tLSLrr : // A8.6.89
  1034. T1sItDPEncode<0b0010, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  1035. IIC_iMOVsr,
  1036. "lsl", "\t$Rdn, $Rm",
  1037. [(set tGPR:$Rdn, (shl tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
  1038. // LSR immediate
  1039. def tLSRri : // A8.6.90
  1040. T1sIGenEncodeImm<{0,0,1,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5),
  1041. IIC_iMOVsi,
  1042. "lsr", "\t$Rd, $Rm, $imm5",
  1043. [(set tGPR:$Rd, (srl tGPR:$Rm, (i32 imm_sr:$imm5)))]>,
  1044. Sched<[WriteALU]> {
  1045. bits<5> imm5;
  1046. let Inst{10-6} = imm5;
  1047. }
  1048. // LSR register
  1049. def tLSRrr : // A8.6.91
  1050. T1sItDPEncode<0b0011, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  1051. IIC_iMOVsr,
  1052. "lsr", "\t$Rdn, $Rm",
  1053. [(set tGPR:$Rdn, (srl tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
  1054. // Move register
  1055. let isMoveImm = 1 in
  1056. def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255:$imm8), IIC_iMOVi,
  1057. "mov", "\t$Rd, $imm8",
  1058. [(set tGPR:$Rd, imm0_255:$imm8)]>,
  1059. T1General<{1,0,0,?,?}>, Sched<[WriteALU]> {
  1060. // A8.6.96
  1061. bits<3> Rd;
  1062. bits<8> imm8;
  1063. let Inst{10-8} = Rd;
  1064. let Inst{7-0} = imm8;
  1065. }
  1066. // Because we have an explicit tMOVSr below, we need an alias to handle
  1067. // the immediate "movs" form here. Blech.
  1068. def : tInstAlias <"movs $Rdn, $imm",
  1069. (tMOVi8 tGPR:$Rdn, CPSR, imm0_255:$imm, 14, 0)>;
  1070. // A7-73: MOV(2) - mov setting flag.
  1071. let hasSideEffects = 0, isMoveReg = 1 in {
  1072. def tMOVr : Thumb1pI<(outs GPR:$Rd), (ins GPR:$Rm), AddrModeNone,
  1073. 2, IIC_iMOVr,
  1074. "mov", "\t$Rd, $Rm", "", []>,
  1075. T1Special<{1,0,?,?}>, Sched<[WriteALU]> {
  1076. // A8.6.97
  1077. bits<4> Rd;
  1078. bits<4> Rm;
  1079. let Inst{7} = Rd{3};
  1080. let Inst{6-3} = Rm;
  1081. let Inst{2-0} = Rd{2-0};
  1082. }
  1083. let Defs = [CPSR] in
  1084. def tMOVSr : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr,
  1085. "movs\t$Rd, $Rm", []>, Encoding16, Sched<[WriteALU]> {
  1086. // A8.6.97
  1087. bits<3> Rd;
  1088. bits<3> Rm;
  1089. let Inst{15-6} = 0b0000000000;
  1090. let Inst{5-3} = Rm;
  1091. let Inst{2-0} = Rd;
  1092. }
  1093. } // hasSideEffects
  1094. // Multiply register
  1095. let isCommutable = 1 in
  1096. def tMUL : // A8.6.105 T1
  1097. Thumb1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), AddrModeNone, 2,
  1098. IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", "$Rm = $Rd",
  1099. [(set tGPR:$Rd, (mul tGPR:$Rn, tGPR:$Rm))]>,
  1100. T1DataProcessing<0b1101>, Sched<[WriteMUL32, ReadMUL, ReadMUL]> {
  1101. bits<3> Rd;
  1102. bits<3> Rn;
  1103. let Inst{5-3} = Rn;
  1104. let Inst{2-0} = Rd;
  1105. let AsmMatchConverter = "cvtThumbMultiply";
  1106. }
  1107. def :tInstAlias<"mul${s}${p} $Rdm, $Rn", (tMUL tGPR:$Rdm, s_cc_out:$s, tGPR:$Rn,
  1108. pred:$p)>;
  1109. // Move inverse register
  1110. def tMVN : // A8.6.107
  1111. T1sIDPEncode<0b1111, (outs tGPR:$Rd), (ins tGPR:$Rn), IIC_iMVNr,
  1112. "mvn", "\t$Rd, $Rn",
  1113. [(set tGPR:$Rd, (not tGPR:$Rn))]>, Sched<[WriteALU]>;
  1114. // Bitwise or register
  1115. let isCommutable = 1 in
  1116. def tORR : // A8.6.114
  1117. T1sItDPEncode<0b1100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  1118. IIC_iBITr,
  1119. "orr", "\t$Rdn, $Rm",
  1120. [(set tGPR:$Rdn, (or tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
  1121. // Swaps
  1122. def tREV : // A8.6.134
  1123. T1pIMiscEncode<{1,0,1,0,0,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
  1124. IIC_iUNAr,
  1125. "rev", "\t$Rd, $Rm",
  1126. [(set tGPR:$Rd, (bswap tGPR:$Rm))]>,
  1127. Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
  1128. def tREV16 : // A8.6.135
  1129. T1pIMiscEncode<{1,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
  1130. IIC_iUNAr,
  1131. "rev16", "\t$Rd, $Rm",
  1132. [(set tGPR:$Rd, (rotr (bswap tGPR:$Rm), (i32 16)))]>,
  1133. Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
  1134. def tREVSH : // A8.6.136
  1135. T1pIMiscEncode<{1,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
  1136. IIC_iUNAr,
  1137. "revsh", "\t$Rd, $Rm",
  1138. [(set tGPR:$Rd, (sra (bswap tGPR:$Rm), (i32 16)))]>,
  1139. Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
  1140. // Rotate right register
  1141. def tROR : // A8.6.139
  1142. T1sItDPEncode<0b0111, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  1143. IIC_iMOVsr,
  1144. "ror", "\t$Rdn, $Rm",
  1145. [(set tGPR:$Rdn, (rotr tGPR:$Rn, tGPR:$Rm))]>,
  1146. Sched<[WriteALU]>;
  1147. // Negate register
  1148. def tRSB : // A8.6.141
  1149. T1sIDPEncode<0b1001, (outs tGPR:$Rd), (ins tGPR:$Rn),
  1150. IIC_iALUi,
  1151. "rsb", "\t$Rd, $Rn, #0",
  1152. [(set tGPR:$Rd, (ineg tGPR:$Rn))]>, Sched<[WriteALU]>;
  1153. // Subtract with carry register
  1154. let Uses = [CPSR] in
  1155. def tSBC : // A8.6.151
  1156. T1sItDPEncode<0b0110, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  1157. IIC_iALUr,
  1158. "sbc", "\t$Rdn, $Rm",
  1159. []>,
  1160. Sched<[WriteALU]>;
  1161. // Subtract immediate
  1162. def tSUBi3 : // A8.6.210 T1
  1163. T1sIGenEncodeImm<0b01111, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
  1164. IIC_iALUi,
  1165. "sub", "\t$Rd, $Rm, $imm3",
  1166. [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7_neg:$imm3))]>,
  1167. Sched<[WriteALU]> {
  1168. bits<3> imm3;
  1169. let Inst{8-6} = imm3;
  1170. }
  1171. def tSUBi8 : // A8.6.210 T2
  1172. T1sItGenEncodeImm<{1,1,1,?,?}, (outs tGPR:$Rdn),
  1173. (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
  1174. "sub", "\t$Rdn, $imm8",
  1175. [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255_neg:$imm8))]>,
  1176. Sched<[WriteALU]>;
  1177. def : tInstSubst<"add${s}${p} $rd, $rn, $imm",
  1178. (tSUBi3 tGPR:$rd, s_cc_out:$s, tGPR:$rn, mod_imm1_7_neg:$imm, pred:$p)>;
  1179. def : tInstSubst<"add${s}${p} $rdn, $imm",
  1180. (tSUBi8 tGPR:$rdn, s_cc_out:$s, mod_imm8_255_neg:$imm, pred:$p)>;
  1181. // Subtract register
  1182. def tSUBrr : // A8.6.212
  1183. T1sIGenEncode<0b01101, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
  1184. IIC_iALUr,
  1185. "sub", "\t$Rd, $Rn, $Rm",
  1186. [(set tGPR:$Rd, (sub tGPR:$Rn, tGPR:$Rm))]>,
  1187. Sched<[WriteALU]>;
  1188. def : tInstAlias <"sub${s}${p} $Rdn, $Rm",
  1189. (tSUBrr tGPR:$Rdn,s_cc_out:$s, tGPR:$Rdn, tGPR:$Rm, pred:$p)>;
  1190. /// Similar to the above except these set the 's' bit so the
  1191. /// instruction modifies the CPSR register.
  1192. ///
  1193. /// These opcodes will be converted to the real non-S opcodes by
  1194. /// AdjustInstrPostInstrSelection after giving then an optional CPSR operand.
  1195. let hasPostISelHook = 1, Defs = [CPSR] in {
  1196. let Uses = [CPSR] in
  1197. def tSBCS : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
  1198. 2, IIC_iALUr,
  1199. [(set tGPR:$Rdn, CPSR, (ARMsube tGPR:$Rn, tGPR:$Rm,
  1200. CPSR))]>,
  1201. Requires<[IsThumb1Only]>,
  1202. Sched<[WriteALU]>;
  1203. def tSUBSi3 : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
  1204. 2, IIC_iALUi,
  1205. [(set tGPR:$Rd, CPSR, (ARMsubc tGPR:$Rm,
  1206. imm0_7:$imm3))]>,
  1207. Requires<[IsThumb1Only]>,
  1208. Sched<[WriteALU]>;
  1209. def tSUBSi8 : tPseudoInst<(outs tGPR:$Rdn), (ins tGPR:$Rn, imm0_255:$imm8),
  1210. 2, IIC_iALUi,
  1211. [(set tGPR:$Rdn, CPSR, (ARMsubc tGPR:$Rn,
  1212. imm8_255:$imm8))]>,
  1213. Requires<[IsThumb1Only]>,
  1214. Sched<[WriteALU]>;
  1215. def tSUBSrr : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
  1216. 2, IIC_iALUr,
  1217. [(set tGPR:$Rd, CPSR, (ARMsubc tGPR:$Rn,
  1218. tGPR:$Rm))]>,
  1219. Requires<[IsThumb1Only]>,
  1220. Sched<[WriteALU]>;
  1221. def tRSBS : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn),
  1222. 2, IIC_iALUr,
  1223. [(set tGPR:$Rd, CPSR, (ARMsubc 0, tGPR:$Rn))]>,
  1224. Requires<[IsThumb1Only]>,
  1225. Sched<[WriteALU]>;
  1226. def tLSLSri : tPseudoInst<(outs tGPR:$Rd), (ins tGPR:$Rn, imm0_31:$imm5),
  1227. 2, IIC_iALUr,
  1228. [(set tGPR:$Rd, CPSR, (ARMlsls tGPR:$Rn, imm0_31:$imm5))]>,
  1229. Requires<[IsThumb1Only]>,
  1230. Sched<[WriteALU]>;
  1231. }
  1232. def : T1Pat<(ARMsubs tGPR:$Rn, tGPR:$Rm), (tSUBSrr $Rn, $Rm)>;
  1233. def : T1Pat<(ARMsubs tGPR:$Rn, imm0_7:$imm3), (tSUBSi3 $Rn, imm0_7:$imm3)>;
  1234. def : T1Pat<(ARMsubs tGPR:$Rn, imm0_255:$imm8), (tSUBSi8 $Rn, imm0_255:$imm8)>;
  1235. // Sign-extend byte
  1236. def tSXTB : // A8.6.222
  1237. T1pIMiscEncode<{0,0,1,0,0,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
  1238. IIC_iUNAr,
  1239. "sxtb", "\t$Rd, $Rm",
  1240. [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i8))]>,
  1241. Requires<[IsThumb, IsThumb1Only, HasV6]>,
  1242. Sched<[WriteALU]>;
  1243. // Sign-extend short
  1244. def tSXTH : // A8.6.224
  1245. T1pIMiscEncode<{0,0,1,0,0,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
  1246. IIC_iUNAr,
  1247. "sxth", "\t$Rd, $Rm",
  1248. [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i16))]>,
  1249. Requires<[IsThumb, IsThumb1Only, HasV6]>,
  1250. Sched<[WriteALU]>;
  1251. // Test
  1252. let isCompare = 1, isCommutable = 1, Defs = [CPSR] in
  1253. def tTST : // A8.6.230
  1254. T1pIDPEncode<0b1000, (outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iTSTr,
  1255. "tst", "\t$Rn, $Rm",
  1256. [(ARMcmpZ (and_su tGPR:$Rn, tGPR:$Rm), 0)]>,
  1257. Sched<[WriteALU]>;
  1258. // A8.8.247 UDF - Undefined (Encoding T1)
  1259. def tUDF : TI<(outs), (ins imm0_255:$imm8), IIC_Br, "udf\t$imm8",
  1260. [(int_arm_undefined imm0_255:$imm8)]>, Encoding16 {
  1261. bits<8> imm8;
  1262. let Inst{15-12} = 0b1101;
  1263. let Inst{11-8} = 0b1110;
  1264. let Inst{7-0} = imm8;
  1265. }
  1266. def : Pat<(debugtrap), (tBKPT 0)>, Requires<[IsThumb, HasV5T]>;
  1267. def : Pat<(debugtrap), (tUDF 254)>, Requires<[IsThumb, NoV5T]>;
  1268. def t__brkdiv0 : TI<(outs), (ins), IIC_Br, "__brkdiv0",
  1269. [(int_arm_undefined 249)]>, Encoding16,
  1270. Requires<[IsThumb, IsWindows]> {
  1271. let Inst = 0xdef9;
  1272. let isTerminator = 1;
  1273. }
  1274. // Zero-extend byte
  1275. def tUXTB : // A8.6.262
  1276. T1pIMiscEncode<{0,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
  1277. IIC_iUNAr,
  1278. "uxtb", "\t$Rd, $Rm",
  1279. [(set tGPR:$Rd, (and tGPR:$Rm, 0xFF))]>,
  1280. Requires<[IsThumb, IsThumb1Only, HasV6]>,
  1281. Sched<[WriteALU]>;
  1282. // Zero-extend short
  1283. def tUXTH : // A8.6.264
  1284. T1pIMiscEncode<{0,0,1,0,1,0,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
  1285. IIC_iUNAr,
  1286. "uxth", "\t$Rd, $Rm",
  1287. [(set tGPR:$Rd, (and tGPR:$Rm, 0xFFFF))]>,
  1288. Requires<[IsThumb, IsThumb1Only, HasV6]>, Sched<[WriteALU]>;
  1289. // Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC operation.
  1290. // Expanded after instruction selection into a branch sequence.
  1291. let usesCustomInserter = 1 in // Expanded after instruction selection.
  1292. def tMOVCCr_pseudo :
  1293. PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, cmovpred:$p),
  1294. NoItinerary,
  1295. [(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, cmovpred:$p))]>;
  1296. // tLEApcrel - Load a pc-relative address into a register without offending the
  1297. // assembler.
  1298. def tADR : T1I<(outs tGPR:$Rd), (ins t_adrlabel:$addr, pred:$p),
  1299. IIC_iALUi, "adr{$p}\t$Rd, $addr", []>,
  1300. T1Encoding<{1,0,1,0,0,?}>, Sched<[WriteALU]> {
  1301. bits<3> Rd;
  1302. bits<8> addr;
  1303. let Inst{10-8} = Rd;
  1304. let Inst{7-0} = addr;
  1305. let DecoderMethod = "DecodeThumbAddSpecialReg";
  1306. }
  1307. let hasSideEffects = 0, isReMaterializable = 1 in
  1308. def tLEApcrel : tPseudoInst<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p),
  1309. 2, IIC_iALUi, []>, Sched<[WriteALU]>;
  1310. let hasSideEffects = 1 in
  1311. def tLEApcrelJT : tPseudoInst<(outs tGPR:$Rd),
  1312. (ins i32imm:$label, pred:$p),
  1313. 2, IIC_iALUi, []>, Sched<[WriteALU]>;
  1314. // Thumb-1 doesn't have the TBB or TBH instructions, but we can synthesize them
  1315. // and make use of the same compressed jump table format as Thumb-2.
  1316. let Size = 2, isBranch = 1, isTerminator = 1, isBarrier = 1,
  1317. isIndirectBranch = 1, isNotDuplicable = 1 in {
  1318. def tTBB_JT : tPseudoInst<(outs),
  1319. (ins tGPRwithpc:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0,
  1320. IIC_Br, []>, Sched<[WriteBr]>;
  1321. def tTBH_JT : tPseudoInst<(outs),
  1322. (ins tGPRwithpc:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0,
  1323. IIC_Br, []>, Sched<[WriteBr]>;
  1324. }
  1325. //===----------------------------------------------------------------------===//
  1326. // TLS Instructions
  1327. //
  1328. // __aeabi_read_tp preserves the registers r1-r3.
  1329. // This is a pseudo inst so that we can get the encoding right,
  1330. // complete with fixup for the aeabi_read_tp function.
  1331. let isCall = 1, Defs = [R0, R12, LR, CPSR], Uses = [SP] in
  1332. def tTPsoft : tPseudoInst<(outs), (ins), 4, IIC_Br,
  1333. [(set R0, ARMthread_pointer)]>,
  1334. Requires<[IsThumb, IsReadTPSoft]>,
  1335. Sched<[WriteBr]>;
  1336. //===----------------------------------------------------------------------===//
  1337. // SJLJ Exception handling intrinsics
  1338. //
  1339. // eh_sjlj_setjmp() is an instruction sequence to store the return address and
  1340. // save #0 in R0 for the non-longjmp case. Since by its nature we may be coming
  1341. // from some other function to get here, and we're using the stack frame for the
  1342. // containing function to save/restore registers, we can't keep anything live in
  1343. // regs across the eh_sjlj_setjmp(), else it will almost certainly have been
  1344. // tromped upon when we get here from a longjmp(). We force everything out of
  1345. // registers except for our own input by listing the relevant registers in
  1346. // Defs. By doing so, we also cause the prologue/epilogue code to actively
  1347. // preserve all of the callee-saved registers, which is exactly what we want.
  1348. // $val is a scratch register for our use.
  1349. // This gets lowered to an instruction sequence of 12 bytes
  1350. let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R12, CPSR ],
  1351. hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, Size = 12,
  1352. usesCustomInserter = 1 in
  1353. def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val),
  1354. AddrModeNone, 0, NoItinerary, "","",
  1355. [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
  1356. // This gets lowered to an instruction sequence of 10 bytes
  1357. // FIXME: Non-IOS version(s)
  1358. let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
  1359. Size = 10, Defs = [ R7, LR, SP ] in
  1360. def tInt_eh_sjlj_longjmp : XI<(outs), (ins tGPR:$src, tGPR:$scratch),
  1361. AddrModeNone, 0, IndexModeNone,
  1362. Pseudo, NoItinerary, "", "",
  1363. [(ARMeh_sjlj_longjmp tGPR:$src, tGPR:$scratch)]>,
  1364. Requires<[IsThumb,IsNotWindows]>;
  1365. // This gets lowered to an instruction sequence of 12 bytes
  1366. // (Windows is Thumb2-only)
  1367. let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
  1368. Size = 12, Defs = [ R11, LR, SP ] in
  1369. def tInt_WIN_eh_sjlj_longjmp
  1370. : XI<(outs), (ins GPR:$src, GPR:$scratch), AddrModeNone, 0, IndexModeNone,
  1371. Pseudo, NoItinerary, "", "", [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
  1372. Requires<[IsThumb,IsWindows]>;
  1373. //===----------------------------------------------------------------------===//
  1374. // Non-Instruction Patterns
  1375. //
  1376. // Comparisons
  1377. def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8),
  1378. (tCMPi8 tGPR:$Rn, imm0_255:$imm8)>;
  1379. def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
  1380. (tCMPr tGPR:$Rn, tGPR:$Rm)>;
  1381. // Bswap 16 with load/store
  1382. def : T1Pat<(srl (bswap (extloadi16 t_addrmode_is2:$addr)), (i32 16)),
  1383. (tREV16 (tLDRHi t_addrmode_is2:$addr))>;
  1384. def : T1Pat<(srl (bswap (extloadi16 t_addrmode_rr:$addr)), (i32 16)),
  1385. (tREV16 (tLDRHr t_addrmode_rr:$addr))>;
  1386. def : T1Pat<(srl (bswap top16Zero:$Rn), (i32 16)),
  1387. (tREV16 tGPR:$Rn)>;
  1388. def : T1Pat<(truncstorei16 (srl (bswap tGPR:$Rn), (i32 16)),
  1389. t_addrmode_is2:$addr),
  1390. (tSTRHi(tREV16 tGPR:$Rn), t_addrmode_is2:$addr)>;
  1391. def : T1Pat<(truncstorei16 (srl (bswap tGPR:$Rn), (i32 16)),
  1392. t_addrmode_rr:$addr),
  1393. (tSTRHr (tREV16 tGPR:$Rn), t_addrmode_rr:$addr)>;
  1394. // ConstantPool
  1395. def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>;
  1396. // GlobalAddress
  1397. def tLDRLIT_ga_pcrel : PseudoInst<(outs tGPR:$dst), (ins i32imm:$addr),
  1398. IIC_iLoadiALU,
  1399. [(set tGPR:$dst,
  1400. (ARMWrapperPIC tglobaladdr:$addr))]>,
  1401. Requires<[IsThumb, DontUseMovtInPic]>;
  1402. def tLDRLIT_ga_abs : PseudoInst<(outs tGPR:$dst), (ins i32imm:$src),
  1403. IIC_iLoad_i,
  1404. [(set tGPR:$dst,
  1405. (ARMWrapper tglobaladdr:$src))]>,
  1406. Requires<[IsThumb, DontUseMovt]>;
  1407. // TLS globals
  1408. def : Pat<(ARMWrapperPIC tglobaltlsaddr:$addr),
  1409. (tLDRLIT_ga_pcrel tglobaltlsaddr:$addr)>,
  1410. Requires<[IsThumb, DontUseMovtInPic]>;
  1411. def : Pat<(ARMWrapper tglobaltlsaddr:$addr),
  1412. (tLDRLIT_ga_abs tglobaltlsaddr:$addr)>,
  1413. Requires<[IsThumb, DontUseMovt]>;
  1414. // JumpTable
  1415. def : T1Pat<(ARMWrapperJT tjumptable:$dst),
  1416. (tLEApcrelJT tjumptable:$dst)>;
  1417. // Direct calls
  1418. def : T1Pat<(ARMcall texternalsym:$func), (tBL texternalsym:$func)>,
  1419. Requires<[IsThumb]>;
  1420. // zextload i1 -> zextload i8
  1421. def : T1Pat<(zextloadi1 t_addrmode_is1:$addr),
  1422. (tLDRBi t_addrmode_is1:$addr)>;
  1423. def : T1Pat<(zextloadi1 t_addrmode_rr:$addr),
  1424. (tLDRBr t_addrmode_rr:$addr)>;
  1425. // extload from the stack -> word load from the stack, as it avoids having to
  1426. // materialize the base in a separate register. This only works when a word
  1427. // load puts the byte/halfword value in the same place in the register that the
  1428. // byte/halfword load would, i.e. when little-endian.
  1429. def : T1Pat<(extloadi1 t_addrmode_sp:$addr), (tLDRspi t_addrmode_sp:$addr)>,
  1430. Requires<[IsThumb, IsThumb1Only, IsLE]>;
  1431. def : T1Pat<(extloadi8 t_addrmode_sp:$addr), (tLDRspi t_addrmode_sp:$addr)>,
  1432. Requires<[IsThumb, IsThumb1Only, IsLE]>;
  1433. def : T1Pat<(extloadi16 t_addrmode_sp:$addr), (tLDRspi t_addrmode_sp:$addr)>,
  1434. Requires<[IsThumb, IsThumb1Only, IsLE]>;
  1435. // extload -> zextload
  1436. def : T1Pat<(extloadi1 t_addrmode_is1:$addr), (tLDRBi t_addrmode_is1:$addr)>;
  1437. def : T1Pat<(extloadi1 t_addrmode_rr:$addr), (tLDRBr t_addrmode_rr:$addr)>;
  1438. def : T1Pat<(extloadi8 t_addrmode_is1:$addr), (tLDRBi t_addrmode_is1:$addr)>;
  1439. def : T1Pat<(extloadi8 t_addrmode_rr:$addr), (tLDRBr t_addrmode_rr:$addr)>;
  1440. def : T1Pat<(extloadi16 t_addrmode_is2:$addr), (tLDRHi t_addrmode_is2:$addr)>;
  1441. def : T1Pat<(extloadi16 t_addrmode_rr:$addr), (tLDRHr t_addrmode_rr:$addr)>;
  1442. // post-inc loads and stores
  1443. // post-inc LDR -> LDM r0!, {r1}. The way operands are layed out in LDMs is
  1444. // different to how ISel expects them for a post-inc load, so use a pseudo
  1445. // and expand it just after ISel.
  1446. let usesCustomInserter = 1, mayLoad =1,
  1447. Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in
  1448. def tLDR_postidx: tPseudoInst<(outs tGPR:$Rt, tGPR:$Rn_wb),
  1449. (ins tGPR:$Rn, pred:$p),
  1450. 4, IIC_iStore_ru,
  1451. []>;
  1452. // post-inc STR -> STM r0!, {r1}. The layout of this (because it doesn't def
  1453. // multiple registers) is the same in ISel as MachineInstr, so there's no need
  1454. // for a pseudo.
  1455. def : T1Pat<(post_store tGPR:$Rt, tGPR:$Rn, 4),
  1456. (tSTMIA_UPD tGPR:$Rn, tGPR:$Rt)>;
  1457. // If it's impossible to use [r,r] address mode for sextload, select to
  1458. // ldsr{b|h} r, 0 instead, in a hope that the mov 0 will be more likely to be
  1459. // commoned out than a sxth.
  1460. let AddedComplexity = 10 in {
  1461. def : T1Pat<(sextloadi8 tGPR:$Rn),
  1462. (tLDRSB tGPR:$Rn, (tMOVi8 0))>,
  1463. Requires<[IsThumb, IsThumb1Only, HasV6]>;
  1464. def : T1Pat<(sextloadi16 tGPR:$Rn),
  1465. (tLDRSH tGPR:$Rn, (tMOVi8 0))>,
  1466. Requires<[IsThumb, IsThumb1Only, HasV6]>;
  1467. }
  1468. def : T1Pat<(sextloadi8 t_addrmode_is1:$addr),
  1469. (tASRri (tLSLri (tLDRBi t_addrmode_is1:$addr), 24), 24)>;
  1470. def : T1Pat<(sextloadi8 t_addrmode_rr:$addr),
  1471. (tASRri (tLSLri (tLDRBr t_addrmode_rr:$addr), 24), 24)>;
  1472. def : T1Pat<(sextloadi16 t_addrmode_is2:$addr),
  1473. (tASRri (tLSLri (tLDRHi t_addrmode_is2:$addr), 16), 16)>;
  1474. def : T1Pat<(sextloadi16 t_addrmode_rr:$addr),
  1475. (tASRri (tLSLri (tLDRHr t_addrmode_rr:$addr), 16), 16)>;
  1476. def : T1Pat<(atomic_load_8 t_addrmode_is1:$src),
  1477. (tLDRBi t_addrmode_is1:$src)>;
  1478. def : T1Pat<(atomic_load_8 t_addrmode_rr:$src),
  1479. (tLDRBr t_addrmode_rr:$src)>;
  1480. def : T1Pat<(atomic_load_16 t_addrmode_is2:$src),
  1481. (tLDRHi t_addrmode_is2:$src)>;
  1482. def : T1Pat<(atomic_load_16 t_addrmode_rr:$src),
  1483. (tLDRHr t_addrmode_rr:$src)>;
  1484. def : T1Pat<(atomic_load_32 t_addrmode_is4:$src),
  1485. (tLDRi t_addrmode_is4:$src)>;
  1486. def : T1Pat<(atomic_load_32 t_addrmode_rr:$src),
  1487. (tLDRr t_addrmode_rr:$src)>;
  1488. def : T1Pat<(atomic_store_8 t_addrmode_is1:$ptr, tGPR:$val),
  1489. (tSTRBi tGPR:$val, t_addrmode_is1:$ptr)>;
  1490. def : T1Pat<(atomic_store_8 t_addrmode_rr:$ptr, tGPR:$val),
  1491. (tSTRBr tGPR:$val, t_addrmode_rr:$ptr)>;
  1492. def : T1Pat<(atomic_store_16 t_addrmode_is2:$ptr, tGPR:$val),
  1493. (tSTRHi tGPR:$val, t_addrmode_is2:$ptr)>;
  1494. def : T1Pat<(atomic_store_16 t_addrmode_rr:$ptr, tGPR:$val),
  1495. (tSTRHr tGPR:$val, t_addrmode_rr:$ptr)>;
  1496. def : T1Pat<(atomic_store_32 t_addrmode_is4:$ptr, tGPR:$val),
  1497. (tSTRi tGPR:$val, t_addrmode_is4:$ptr)>;
  1498. def : T1Pat<(atomic_store_32 t_addrmode_rr:$ptr, tGPR:$val),
  1499. (tSTRr tGPR:$val, t_addrmode_rr:$ptr)>;
  1500. // Large immediate handling.
  1501. // Two piece imms.
  1502. def : T1Pat<(i32 thumb_immshifted:$src),
  1503. (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)),
  1504. (thumb_immshifted_shamt imm:$src))>;
  1505. def : T1Pat<(i32 imm0_255_comp:$src),
  1506. (tMVN (tMOVi8 (imm_not_XFORM imm:$src)))>;
  1507. def : T1Pat<(i32 imm256_510:$src),
  1508. (tADDi8 (tMOVi8 255),
  1509. (thumb_imm256_510_addend imm:$src))>;
  1510. // Pseudo instruction that combines ldr from constpool and add pc. This should
  1511. // be expanded into two instructions late to allow if-conversion and
  1512. // scheduling.
  1513. let isReMaterializable = 1 in
  1514. def tLDRpci_pic : PseudoInst<(outs tGPR:$dst), (ins i32imm:$addr, pclabel:$cp),
  1515. NoItinerary,
  1516. [(set tGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
  1517. imm:$cp))]>,
  1518. Requires<[IsThumb, IsThumb1Only]>;
  1519. // Pseudo-instruction for merged POP and return.
  1520. // FIXME: remove when we have a way to marking a MI with these properties.
  1521. let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
  1522. hasExtraDefRegAllocReq = 1 in
  1523. def tPOP_RET : tPseudoExpand<(outs), (ins pred:$p, reglist:$regs, variable_ops),
  1524. 2, IIC_iPop_Br, [],
  1525. (tPOP pred:$p, reglist:$regs)>, Sched<[WriteBrL]>;
  1526. // Indirect branch using "mov pc, $Rm"
  1527. let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
  1528. def tBRIND : tPseudoExpand<(outs), (ins GPR:$Rm, pred:$p),
  1529. 2, IIC_Br, [(brind GPR:$Rm)],
  1530. (tMOVr PC, GPR:$Rm, pred:$p)>, Sched<[WriteBr]>;
  1531. }
  1532. // In Thumb1, "nop" is encoded as a "mov r8, r8". Technically, the bf00
  1533. // encoding is available on ARMv6K, but we don't differentiate that finely.
  1534. def : InstAlias<"nop", (tMOVr R8, R8, 14, 0), 0>, Requires<[IsThumb, IsThumb1Only]>;
  1535. // "neg" is and alias for "rsb rd, rn, #0"
  1536. def : tInstAlias<"neg${s}${p} $Rd, $Rm",
  1537. (tRSB tGPR:$Rd, s_cc_out:$s, tGPR:$Rm, pred:$p)>;
  1538. // Implied destination operand forms for shifts.
  1539. def : tInstAlias<"lsl${s}${p} $Rdm, $imm",
  1540. (tLSLri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm0_31:$imm, pred:$p)>;
  1541. def : tInstAlias<"lsr${s}${p} $Rdm, $imm",
  1542. (tLSRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>;
  1543. def : tInstAlias<"asr${s}${p} $Rdm, $imm",
  1544. (tASRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>;
  1545. // Pseudo instruction ldr Rt, =immediate
  1546. def tLDRConstPool
  1547. : tAsmPseudo<"ldr${p} $Rt, $immediate",
  1548. (ins tGPR:$Rt, const_pool_asm_imm:$immediate, pred:$p)>;
  1549. //===----------------------------------
  1550. // Atomic cmpxchg for -O0
  1551. //===----------------------------------
  1552. // See ARMInstrInfo.td. These two thumb specific pseudos are required to
  1553. // restrict the register class for the UXTB/UXTH ops used in the expansion.
  1554. let Constraints = "@earlyclobber $Rd,@earlyclobber $temp",
  1555. mayLoad = 1, mayStore = 1 in {
  1556. def tCMP_SWAP_8 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
  1557. (ins GPR:$addr, tGPR:$desired, GPR:$new),
  1558. NoItinerary, []>, Sched<[]>;
  1559. def tCMP_SWAP_16 : PseudoInst<(outs GPR:$Rd, GPR:$temp),
  1560. (ins GPR:$addr, tGPR:$desired, GPR:$new),
  1561. NoItinerary, []>, Sched<[]>;
  1562. }