ARMExpandPseudoInsts.cpp 132 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157
  1. //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -------------===//
  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 contains a pass that expands pseudo instructions into target
  10. // instructions to allow proper scheduling, if-conversion, and other late
  11. // optimizations. This pass should be run after register allocation but before
  12. // the post-regalloc scheduling pass.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "ARM.h"
  16. #include "ARMBaseInstrInfo.h"
  17. #include "ARMBaseRegisterInfo.h"
  18. #include "ARMConstantPoolValue.h"
  19. #include "ARMMachineFunctionInfo.h"
  20. #include "ARMSubtarget.h"
  21. #include "MCTargetDesc/ARMAddressingModes.h"
  22. #include "llvm/CodeGen/LivePhysRegs.h"
  23. #include "llvm/CodeGen/MachineFrameInfo.h"
  24. #include "llvm/CodeGen/MachineFunctionPass.h"
  25. #include "llvm/Support/Debug.h"
  26. using namespace llvm;
  27. #define DEBUG_TYPE "arm-pseudo"
  28. static cl::opt<bool>
  29. VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden,
  30. cl::desc("Verify machine code after expanding ARM pseudos"));
  31. #define ARM_EXPAND_PSEUDO_NAME "ARM pseudo instruction expansion pass"
  32. namespace {
  33. class ARMExpandPseudo : public MachineFunctionPass {
  34. public:
  35. static char ID;
  36. ARMExpandPseudo() : MachineFunctionPass(ID) {}
  37. const ARMBaseInstrInfo *TII;
  38. const TargetRegisterInfo *TRI;
  39. const ARMSubtarget *STI;
  40. ARMFunctionInfo *AFI;
  41. bool runOnMachineFunction(MachineFunction &Fn) override;
  42. MachineFunctionProperties getRequiredProperties() const override {
  43. return MachineFunctionProperties().set(
  44. MachineFunctionProperties::Property::NoVRegs);
  45. }
  46. StringRef getPassName() const override {
  47. return ARM_EXPAND_PSEUDO_NAME;
  48. }
  49. private:
  50. void TransferImpOps(MachineInstr &OldMI,
  51. MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI);
  52. bool ExpandMI(MachineBasicBlock &MBB,
  53. MachineBasicBlock::iterator MBBI,
  54. MachineBasicBlock::iterator &NextMBBI);
  55. bool ExpandMBB(MachineBasicBlock &MBB);
  56. void ExpandVLD(MachineBasicBlock::iterator &MBBI);
  57. void ExpandVST(MachineBasicBlock::iterator &MBBI);
  58. void ExpandLaneOp(MachineBasicBlock::iterator &MBBI);
  59. void ExpandVTBL(MachineBasicBlock::iterator &MBBI,
  60. unsigned Opc, bool IsExt);
  61. void ExpandMQQPRLoadStore(MachineBasicBlock::iterator &MBBI);
  62. void ExpandMOV32BitImm(MachineBasicBlock &MBB,
  63. MachineBasicBlock::iterator &MBBI);
  64. void CMSEClearGPRegs(MachineBasicBlock &MBB,
  65. MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
  66. const SmallVectorImpl<unsigned> &ClearRegs,
  67. unsigned ClobberReg);
  68. MachineBasicBlock &CMSEClearFPRegs(MachineBasicBlock &MBB,
  69. MachineBasicBlock::iterator MBBI);
  70. MachineBasicBlock &CMSEClearFPRegsV8(MachineBasicBlock &MBB,
  71. MachineBasicBlock::iterator MBBI,
  72. const BitVector &ClearRegs);
  73. MachineBasicBlock &CMSEClearFPRegsV81(MachineBasicBlock &MBB,
  74. MachineBasicBlock::iterator MBBI,
  75. const BitVector &ClearRegs);
  76. void CMSESaveClearFPRegs(MachineBasicBlock &MBB,
  77. MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  78. const LivePhysRegs &LiveRegs,
  79. SmallVectorImpl<unsigned> &AvailableRegs);
  80. void CMSESaveClearFPRegsV8(MachineBasicBlock &MBB,
  81. MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  82. const LivePhysRegs &LiveRegs,
  83. SmallVectorImpl<unsigned> &ScratchRegs);
  84. void CMSESaveClearFPRegsV81(MachineBasicBlock &MBB,
  85. MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  86. const LivePhysRegs &LiveRegs);
  87. void CMSERestoreFPRegs(MachineBasicBlock &MBB,
  88. MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  89. SmallVectorImpl<unsigned> &AvailableRegs);
  90. void CMSERestoreFPRegsV8(MachineBasicBlock &MBB,
  91. MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  92. SmallVectorImpl<unsigned> &AvailableRegs);
  93. void CMSERestoreFPRegsV81(MachineBasicBlock &MBB,
  94. MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  95. SmallVectorImpl<unsigned> &AvailableRegs);
  96. bool ExpandCMP_SWAP(MachineBasicBlock &MBB,
  97. MachineBasicBlock::iterator MBBI, unsigned LdrexOp,
  98. unsigned StrexOp, unsigned UxtOp,
  99. MachineBasicBlock::iterator &NextMBBI);
  100. bool ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
  101. MachineBasicBlock::iterator MBBI,
  102. MachineBasicBlock::iterator &NextMBBI);
  103. };
  104. char ARMExpandPseudo::ID = 0;
  105. }
  106. INITIALIZE_PASS(ARMExpandPseudo, DEBUG_TYPE, ARM_EXPAND_PSEUDO_NAME, false,
  107. false)
  108. /// TransferImpOps - Transfer implicit operands on the pseudo instruction to
  109. /// the instructions created from the expansion.
  110. void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
  111. MachineInstrBuilder &UseMI,
  112. MachineInstrBuilder &DefMI) {
  113. const MCInstrDesc &Desc = OldMI.getDesc();
  114. for (const MachineOperand &MO :
  115. llvm::drop_begin(OldMI.operands(), Desc.getNumOperands())) {
  116. assert(MO.isReg() && MO.getReg());
  117. if (MO.isUse())
  118. UseMI.add(MO);
  119. else
  120. DefMI.add(MO);
  121. }
  122. }
  123. namespace {
  124. // Constants for register spacing in NEON load/store instructions.
  125. // For quad-register load-lane and store-lane pseudo instructors, the
  126. // spacing is initially assumed to be EvenDblSpc, and that is changed to
  127. // OddDblSpc depending on the lane number operand.
  128. enum NEONRegSpacing {
  129. SingleSpc,
  130. SingleLowSpc , // Single spacing, low registers, three and four vectors.
  131. SingleHighQSpc, // Single spacing, high registers, four vectors.
  132. SingleHighTSpc, // Single spacing, high registers, three vectors.
  133. EvenDblSpc,
  134. OddDblSpc
  135. };
  136. // Entries for NEON load/store information table. The table is sorted by
  137. // PseudoOpc for fast binary-search lookups.
  138. struct NEONLdStTableEntry {
  139. uint16_t PseudoOpc;
  140. uint16_t RealOpc;
  141. bool IsLoad;
  142. bool isUpdating;
  143. bool hasWritebackOperand;
  144. uint8_t RegSpacing; // One of type NEONRegSpacing
  145. uint8_t NumRegs; // D registers loaded or stored
  146. uint8_t RegElts; // elements per D register; used for lane ops
  147. // FIXME: Temporary flag to denote whether the real instruction takes
  148. // a single register (like the encoding) or all of the registers in
  149. // the list (like the asm syntax and the isel DAG). When all definitions
  150. // are converted to take only the single encoded register, this will
  151. // go away.
  152. bool copyAllListRegs;
  153. // Comparison methods for binary search of the table.
  154. bool operator<(const NEONLdStTableEntry &TE) const {
  155. return PseudoOpc < TE.PseudoOpc;
  156. }
  157. friend bool operator<(const NEONLdStTableEntry &TE, unsigned PseudoOpc) {
  158. return TE.PseudoOpc < PseudoOpc;
  159. }
  160. friend bool LLVM_ATTRIBUTE_UNUSED operator<(unsigned PseudoOpc,
  161. const NEONLdStTableEntry &TE) {
  162. return PseudoOpc < TE.PseudoOpc;
  163. }
  164. };
  165. }
  166. static const NEONLdStTableEntry NEONLdStTable[] = {
  167. { ARM::VLD1LNq16Pseudo, ARM::VLD1LNd16, true, false, false, EvenDblSpc, 1, 4 ,true},
  168. { ARM::VLD1LNq16Pseudo_UPD, ARM::VLD1LNd16_UPD, true, true, true, EvenDblSpc, 1, 4 ,true},
  169. { ARM::VLD1LNq32Pseudo, ARM::VLD1LNd32, true, false, false, EvenDblSpc, 1, 2 ,true},
  170. { ARM::VLD1LNq32Pseudo_UPD, ARM::VLD1LNd32_UPD, true, true, true, EvenDblSpc, 1, 2 ,true},
  171. { ARM::VLD1LNq8Pseudo, ARM::VLD1LNd8, true, false, false, EvenDblSpc, 1, 8 ,true},
  172. { ARM::VLD1LNq8Pseudo_UPD, ARM::VLD1LNd8_UPD, true, true, true, EvenDblSpc, 1, 8 ,true},
  173. { ARM::VLD1d16QPseudo, ARM::VLD1d16Q, true, false, false, SingleSpc, 4, 4 ,false},
  174. { ARM::VLD1d16QPseudoWB_fixed, ARM::VLD1d16Qwb_fixed, true, true, false, SingleSpc, 4, 4 ,false},
  175. { ARM::VLD1d16QPseudoWB_register, ARM::VLD1d16Qwb_register, true, true, true, SingleSpc, 4, 4 ,false},
  176. { ARM::VLD1d16TPseudo, ARM::VLD1d16T, true, false, false, SingleSpc, 3, 4 ,false},
  177. { ARM::VLD1d16TPseudoWB_fixed, ARM::VLD1d16Twb_fixed, true, true, false, SingleSpc, 3, 4 ,false},
  178. { ARM::VLD1d16TPseudoWB_register, ARM::VLD1d16Twb_register, true, true, true, SingleSpc, 3, 4 ,false},
  179. { ARM::VLD1d32QPseudo, ARM::VLD1d32Q, true, false, false, SingleSpc, 4, 2 ,false},
  180. { ARM::VLD1d32QPseudoWB_fixed, ARM::VLD1d32Qwb_fixed, true, true, false, SingleSpc, 4, 2 ,false},
  181. { ARM::VLD1d32QPseudoWB_register, ARM::VLD1d32Qwb_register, true, true, true, SingleSpc, 4, 2 ,false},
  182. { ARM::VLD1d32TPseudo, ARM::VLD1d32T, true, false, false, SingleSpc, 3, 2 ,false},
  183. { ARM::VLD1d32TPseudoWB_fixed, ARM::VLD1d32Twb_fixed, true, true, false, SingleSpc, 3, 2 ,false},
  184. { ARM::VLD1d32TPseudoWB_register, ARM::VLD1d32Twb_register, true, true, true, SingleSpc, 3, 2 ,false},
  185. { ARM::VLD1d64QPseudo, ARM::VLD1d64Q, true, false, false, SingleSpc, 4, 1 ,false},
  186. { ARM::VLD1d64QPseudoWB_fixed, ARM::VLD1d64Qwb_fixed, true, true, false, SingleSpc, 4, 1 ,false},
  187. { ARM::VLD1d64QPseudoWB_register, ARM::VLD1d64Qwb_register, true, true, true, SingleSpc, 4, 1 ,false},
  188. { ARM::VLD1d64TPseudo, ARM::VLD1d64T, true, false, false, SingleSpc, 3, 1 ,false},
  189. { ARM::VLD1d64TPseudoWB_fixed, ARM::VLD1d64Twb_fixed, true, true, false, SingleSpc, 3, 1 ,false},
  190. { ARM::VLD1d64TPseudoWB_register, ARM::VLD1d64Twb_register, true, true, true, SingleSpc, 3, 1 ,false},
  191. { ARM::VLD1d8QPseudo, ARM::VLD1d8Q, true, false, false, SingleSpc, 4, 8 ,false},
  192. { ARM::VLD1d8QPseudoWB_fixed, ARM::VLD1d8Qwb_fixed, true, true, false, SingleSpc, 4, 8 ,false},
  193. { ARM::VLD1d8QPseudoWB_register, ARM::VLD1d8Qwb_register, true, true, true, SingleSpc, 4, 8 ,false},
  194. { ARM::VLD1d8TPseudo, ARM::VLD1d8T, true, false, false, SingleSpc, 3, 8 ,false},
  195. { ARM::VLD1d8TPseudoWB_fixed, ARM::VLD1d8Twb_fixed, true, true, false, SingleSpc, 3, 8 ,false},
  196. { ARM::VLD1d8TPseudoWB_register, ARM::VLD1d8Twb_register, true, true, true, SingleSpc, 3, 8 ,false},
  197. { ARM::VLD1q16HighQPseudo, ARM::VLD1d16Q, true, false, false, SingleHighQSpc, 4, 4 ,false},
  198. { ARM::VLD1q16HighQPseudo_UPD, ARM::VLD1d16Qwb_fixed, true, true, true, SingleHighQSpc, 4, 4 ,false},
  199. { ARM::VLD1q16HighTPseudo, ARM::VLD1d16T, true, false, false, SingleHighTSpc, 3, 4 ,false},
  200. { ARM::VLD1q16HighTPseudo_UPD, ARM::VLD1d16Twb_fixed, true, true, true, SingleHighTSpc, 3, 4 ,false},
  201. { ARM::VLD1q16LowQPseudo_UPD, ARM::VLD1d16Qwb_fixed, true, true, true, SingleLowSpc, 4, 4 ,false},
  202. { ARM::VLD1q16LowTPseudo_UPD, ARM::VLD1d16Twb_fixed, true, true, true, SingleLowSpc, 3, 4 ,false},
  203. { ARM::VLD1q32HighQPseudo, ARM::VLD1d32Q, true, false, false, SingleHighQSpc, 4, 2 ,false},
  204. { ARM::VLD1q32HighQPseudo_UPD, ARM::VLD1d32Qwb_fixed, true, true, true, SingleHighQSpc, 4, 2 ,false},
  205. { ARM::VLD1q32HighTPseudo, ARM::VLD1d32T, true, false, false, SingleHighTSpc, 3, 2 ,false},
  206. { ARM::VLD1q32HighTPseudo_UPD, ARM::VLD1d32Twb_fixed, true, true, true, SingleHighTSpc, 3, 2 ,false},
  207. { ARM::VLD1q32LowQPseudo_UPD, ARM::VLD1d32Qwb_fixed, true, true, true, SingleLowSpc, 4, 2 ,false},
  208. { ARM::VLD1q32LowTPseudo_UPD, ARM::VLD1d32Twb_fixed, true, true, true, SingleLowSpc, 3, 2 ,false},
  209. { ARM::VLD1q64HighQPseudo, ARM::VLD1d64Q, true, false, false, SingleHighQSpc, 4, 1 ,false},
  210. { ARM::VLD1q64HighQPseudo_UPD, ARM::VLD1d64Qwb_fixed, true, true, true, SingleHighQSpc, 4, 1 ,false},
  211. { ARM::VLD1q64HighTPseudo, ARM::VLD1d64T, true, false, false, SingleHighTSpc, 3, 1 ,false},
  212. { ARM::VLD1q64HighTPseudo_UPD, ARM::VLD1d64Twb_fixed, true, true, true, SingleHighTSpc, 3, 1 ,false},
  213. { ARM::VLD1q64LowQPseudo_UPD, ARM::VLD1d64Qwb_fixed, true, true, true, SingleLowSpc, 4, 1 ,false},
  214. { ARM::VLD1q64LowTPseudo_UPD, ARM::VLD1d64Twb_fixed, true, true, true, SingleLowSpc, 3, 1 ,false},
  215. { ARM::VLD1q8HighQPseudo, ARM::VLD1d8Q, true, false, false, SingleHighQSpc, 4, 8 ,false},
  216. { ARM::VLD1q8HighQPseudo_UPD, ARM::VLD1d8Qwb_fixed, true, true, true, SingleHighQSpc, 4, 8 ,false},
  217. { ARM::VLD1q8HighTPseudo, ARM::VLD1d8T, true, false, false, SingleHighTSpc, 3, 8 ,false},
  218. { ARM::VLD1q8HighTPseudo_UPD, ARM::VLD1d8Twb_fixed, true, true, true, SingleHighTSpc, 3, 8 ,false},
  219. { ARM::VLD1q8LowQPseudo_UPD, ARM::VLD1d8Qwb_fixed, true, true, true, SingleLowSpc, 4, 8 ,false},
  220. { ARM::VLD1q8LowTPseudo_UPD, ARM::VLD1d8Twb_fixed, true, true, true, SingleLowSpc, 3, 8 ,false},
  221. { ARM::VLD2DUPq16EvenPseudo, ARM::VLD2DUPd16x2, true, false, false, EvenDblSpc, 2, 4 ,false},
  222. { ARM::VLD2DUPq16OddPseudo, ARM::VLD2DUPd16x2, true, false, false, OddDblSpc, 2, 4 ,false},
  223. { ARM::VLD2DUPq16OddPseudoWB_fixed, ARM::VLD2DUPd16x2wb_fixed, true, true, false, OddDblSpc, 2, 4 ,false},
  224. { ARM::VLD2DUPq16OddPseudoWB_register, ARM::VLD2DUPd16x2wb_register, true, true, true, OddDblSpc, 2, 4 ,false},
  225. { ARM::VLD2DUPq32EvenPseudo, ARM::VLD2DUPd32x2, true, false, false, EvenDblSpc, 2, 2 ,false},
  226. { ARM::VLD2DUPq32OddPseudo, ARM::VLD2DUPd32x2, true, false, false, OddDblSpc, 2, 2 ,false},
  227. { ARM::VLD2DUPq32OddPseudoWB_fixed, ARM::VLD2DUPd32x2wb_fixed, true, true, false, OddDblSpc, 2, 2 ,false},
  228. { ARM::VLD2DUPq32OddPseudoWB_register, ARM::VLD2DUPd32x2wb_register, true, true, true, OddDblSpc, 2, 2 ,false},
  229. { ARM::VLD2DUPq8EvenPseudo, ARM::VLD2DUPd8x2, true, false, false, EvenDblSpc, 2, 8 ,false},
  230. { ARM::VLD2DUPq8OddPseudo, ARM::VLD2DUPd8x2, true, false, false, OddDblSpc, 2, 8 ,false},
  231. { ARM::VLD2DUPq8OddPseudoWB_fixed, ARM::VLD2DUPd8x2wb_fixed, true, true, false, OddDblSpc, 2, 8 ,false},
  232. { ARM::VLD2DUPq8OddPseudoWB_register, ARM::VLD2DUPd8x2wb_register, true, true, true, OddDblSpc, 2, 8 ,false},
  233. { ARM::VLD2LNd16Pseudo, ARM::VLD2LNd16, true, false, false, SingleSpc, 2, 4 ,true},
  234. { ARM::VLD2LNd16Pseudo_UPD, ARM::VLD2LNd16_UPD, true, true, true, SingleSpc, 2, 4 ,true},
  235. { ARM::VLD2LNd32Pseudo, ARM::VLD2LNd32, true, false, false, SingleSpc, 2, 2 ,true},
  236. { ARM::VLD2LNd32Pseudo_UPD, ARM::VLD2LNd32_UPD, true, true, true, SingleSpc, 2, 2 ,true},
  237. { ARM::VLD2LNd8Pseudo, ARM::VLD2LNd8, true, false, false, SingleSpc, 2, 8 ,true},
  238. { ARM::VLD2LNd8Pseudo_UPD, ARM::VLD2LNd8_UPD, true, true, true, SingleSpc, 2, 8 ,true},
  239. { ARM::VLD2LNq16Pseudo, ARM::VLD2LNq16, true, false, false, EvenDblSpc, 2, 4 ,true},
  240. { ARM::VLD2LNq16Pseudo_UPD, ARM::VLD2LNq16_UPD, true, true, true, EvenDblSpc, 2, 4 ,true},
  241. { ARM::VLD2LNq32Pseudo, ARM::VLD2LNq32, true, false, false, EvenDblSpc, 2, 2 ,true},
  242. { ARM::VLD2LNq32Pseudo_UPD, ARM::VLD2LNq32_UPD, true, true, true, EvenDblSpc, 2, 2 ,true},
  243. { ARM::VLD2q16Pseudo, ARM::VLD2q16, true, false, false, SingleSpc, 4, 4 ,false},
  244. { ARM::VLD2q16PseudoWB_fixed, ARM::VLD2q16wb_fixed, true, true, false, SingleSpc, 4, 4 ,false},
  245. { ARM::VLD2q16PseudoWB_register, ARM::VLD2q16wb_register, true, true, true, SingleSpc, 4, 4 ,false},
  246. { ARM::VLD2q32Pseudo, ARM::VLD2q32, true, false, false, SingleSpc, 4, 2 ,false},
  247. { ARM::VLD2q32PseudoWB_fixed, ARM::VLD2q32wb_fixed, true, true, false, SingleSpc, 4, 2 ,false},
  248. { ARM::VLD2q32PseudoWB_register, ARM::VLD2q32wb_register, true, true, true, SingleSpc, 4, 2 ,false},
  249. { ARM::VLD2q8Pseudo, ARM::VLD2q8, true, false, false, SingleSpc, 4, 8 ,false},
  250. { ARM::VLD2q8PseudoWB_fixed, ARM::VLD2q8wb_fixed, true, true, false, SingleSpc, 4, 8 ,false},
  251. { ARM::VLD2q8PseudoWB_register, ARM::VLD2q8wb_register, true, true, true, SingleSpc, 4, 8 ,false},
  252. { ARM::VLD3DUPd16Pseudo, ARM::VLD3DUPd16, true, false, false, SingleSpc, 3, 4,true},
  253. { ARM::VLD3DUPd16Pseudo_UPD, ARM::VLD3DUPd16_UPD, true, true, true, SingleSpc, 3, 4,true},
  254. { ARM::VLD3DUPd32Pseudo, ARM::VLD3DUPd32, true, false, false, SingleSpc, 3, 2,true},
  255. { ARM::VLD3DUPd32Pseudo_UPD, ARM::VLD3DUPd32_UPD, true, true, true, SingleSpc, 3, 2,true},
  256. { ARM::VLD3DUPd8Pseudo, ARM::VLD3DUPd8, true, false, false, SingleSpc, 3, 8,true},
  257. { ARM::VLD3DUPd8Pseudo_UPD, ARM::VLD3DUPd8_UPD, true, true, true, SingleSpc, 3, 8,true},
  258. { ARM::VLD3DUPq16EvenPseudo, ARM::VLD3DUPq16, true, false, false, EvenDblSpc, 3, 4 ,true},
  259. { ARM::VLD3DUPq16OddPseudo, ARM::VLD3DUPq16, true, false, false, OddDblSpc, 3, 4 ,true},
  260. { ARM::VLD3DUPq16OddPseudo_UPD, ARM::VLD3DUPq16_UPD, true, true, true, OddDblSpc, 3, 4 ,true},
  261. { ARM::VLD3DUPq32EvenPseudo, ARM::VLD3DUPq32, true, false, false, EvenDblSpc, 3, 2 ,true},
  262. { ARM::VLD3DUPq32OddPseudo, ARM::VLD3DUPq32, true, false, false, OddDblSpc, 3, 2 ,true},
  263. { ARM::VLD3DUPq32OddPseudo_UPD, ARM::VLD3DUPq32_UPD, true, true, true, OddDblSpc, 3, 2 ,true},
  264. { ARM::VLD3DUPq8EvenPseudo, ARM::VLD3DUPq8, true, false, false, EvenDblSpc, 3, 8 ,true},
  265. { ARM::VLD3DUPq8OddPseudo, ARM::VLD3DUPq8, true, false, false, OddDblSpc, 3, 8 ,true},
  266. { ARM::VLD3DUPq8OddPseudo_UPD, ARM::VLD3DUPq8_UPD, true, true, true, OddDblSpc, 3, 8 ,true},
  267. { ARM::VLD3LNd16Pseudo, ARM::VLD3LNd16, true, false, false, SingleSpc, 3, 4 ,true},
  268. { ARM::VLD3LNd16Pseudo_UPD, ARM::VLD3LNd16_UPD, true, true, true, SingleSpc, 3, 4 ,true},
  269. { ARM::VLD3LNd32Pseudo, ARM::VLD3LNd32, true, false, false, SingleSpc, 3, 2 ,true},
  270. { ARM::VLD3LNd32Pseudo_UPD, ARM::VLD3LNd32_UPD, true, true, true, SingleSpc, 3, 2 ,true},
  271. { ARM::VLD3LNd8Pseudo, ARM::VLD3LNd8, true, false, false, SingleSpc, 3, 8 ,true},
  272. { ARM::VLD3LNd8Pseudo_UPD, ARM::VLD3LNd8_UPD, true, true, true, SingleSpc, 3, 8 ,true},
  273. { ARM::VLD3LNq16Pseudo, ARM::VLD3LNq16, true, false, false, EvenDblSpc, 3, 4 ,true},
  274. { ARM::VLD3LNq16Pseudo_UPD, ARM::VLD3LNq16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true},
  275. { ARM::VLD3LNq32Pseudo, ARM::VLD3LNq32, true, false, false, EvenDblSpc, 3, 2 ,true},
  276. { ARM::VLD3LNq32Pseudo_UPD, ARM::VLD3LNq32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true},
  277. { ARM::VLD3d16Pseudo, ARM::VLD3d16, true, false, false, SingleSpc, 3, 4 ,true},
  278. { ARM::VLD3d16Pseudo_UPD, ARM::VLD3d16_UPD, true, true, true, SingleSpc, 3, 4 ,true},
  279. { ARM::VLD3d32Pseudo, ARM::VLD3d32, true, false, false, SingleSpc, 3, 2 ,true},
  280. { ARM::VLD3d32Pseudo_UPD, ARM::VLD3d32_UPD, true, true, true, SingleSpc, 3, 2 ,true},
  281. { ARM::VLD3d8Pseudo, ARM::VLD3d8, true, false, false, SingleSpc, 3, 8 ,true},
  282. { ARM::VLD3d8Pseudo_UPD, ARM::VLD3d8_UPD, true, true, true, SingleSpc, 3, 8 ,true},
  283. { ARM::VLD3q16Pseudo_UPD, ARM::VLD3q16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true},
  284. { ARM::VLD3q16oddPseudo, ARM::VLD3q16, true, false, false, OddDblSpc, 3, 4 ,true},
  285. { ARM::VLD3q16oddPseudo_UPD, ARM::VLD3q16_UPD, true, true, true, OddDblSpc, 3, 4 ,true},
  286. { ARM::VLD3q32Pseudo_UPD, ARM::VLD3q32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true},
  287. { ARM::VLD3q32oddPseudo, ARM::VLD3q32, true, false, false, OddDblSpc, 3, 2 ,true},
  288. { ARM::VLD3q32oddPseudo_UPD, ARM::VLD3q32_UPD, true, true, true, OddDblSpc, 3, 2 ,true},
  289. { ARM::VLD3q8Pseudo_UPD, ARM::VLD3q8_UPD, true, true, true, EvenDblSpc, 3, 8 ,true},
  290. { ARM::VLD3q8oddPseudo, ARM::VLD3q8, true, false, false, OddDblSpc, 3, 8 ,true},
  291. { ARM::VLD3q8oddPseudo_UPD, ARM::VLD3q8_UPD, true, true, true, OddDblSpc, 3, 8 ,true},
  292. { ARM::VLD4DUPd16Pseudo, ARM::VLD4DUPd16, true, false, false, SingleSpc, 4, 4,true},
  293. { ARM::VLD4DUPd16Pseudo_UPD, ARM::VLD4DUPd16_UPD, true, true, true, SingleSpc, 4, 4,true},
  294. { ARM::VLD4DUPd32Pseudo, ARM::VLD4DUPd32, true, false, false, SingleSpc, 4, 2,true},
  295. { ARM::VLD4DUPd32Pseudo_UPD, ARM::VLD4DUPd32_UPD, true, true, true, SingleSpc, 4, 2,true},
  296. { ARM::VLD4DUPd8Pseudo, ARM::VLD4DUPd8, true, false, false, SingleSpc, 4, 8,true},
  297. { ARM::VLD4DUPd8Pseudo_UPD, ARM::VLD4DUPd8_UPD, true, true, true, SingleSpc, 4, 8,true},
  298. { ARM::VLD4DUPq16EvenPseudo, ARM::VLD4DUPq16, true, false, false, EvenDblSpc, 4, 4 ,true},
  299. { ARM::VLD4DUPq16OddPseudo, ARM::VLD4DUPq16, true, false, false, OddDblSpc, 4, 4 ,true},
  300. { ARM::VLD4DUPq16OddPseudo_UPD, ARM::VLD4DUPq16_UPD, true, true, true, OddDblSpc, 4, 4 ,true},
  301. { ARM::VLD4DUPq32EvenPseudo, ARM::VLD4DUPq32, true, false, false, EvenDblSpc, 4, 2 ,true},
  302. { ARM::VLD4DUPq32OddPseudo, ARM::VLD4DUPq32, true, false, false, OddDblSpc, 4, 2 ,true},
  303. { ARM::VLD4DUPq32OddPseudo_UPD, ARM::VLD4DUPq32_UPD, true, true, true, OddDblSpc, 4, 2 ,true},
  304. { ARM::VLD4DUPq8EvenPseudo, ARM::VLD4DUPq8, true, false, false, EvenDblSpc, 4, 8 ,true},
  305. { ARM::VLD4DUPq8OddPseudo, ARM::VLD4DUPq8, true, false, false, OddDblSpc, 4, 8 ,true},
  306. { ARM::VLD4DUPq8OddPseudo_UPD, ARM::VLD4DUPq8_UPD, true, true, true, OddDblSpc, 4, 8 ,true},
  307. { ARM::VLD4LNd16Pseudo, ARM::VLD4LNd16, true, false, false, SingleSpc, 4, 4 ,true},
  308. { ARM::VLD4LNd16Pseudo_UPD, ARM::VLD4LNd16_UPD, true, true, true, SingleSpc, 4, 4 ,true},
  309. { ARM::VLD4LNd32Pseudo, ARM::VLD4LNd32, true, false, false, SingleSpc, 4, 2 ,true},
  310. { ARM::VLD4LNd32Pseudo_UPD, ARM::VLD4LNd32_UPD, true, true, true, SingleSpc, 4, 2 ,true},
  311. { ARM::VLD4LNd8Pseudo, ARM::VLD4LNd8, true, false, false, SingleSpc, 4, 8 ,true},
  312. { ARM::VLD4LNd8Pseudo_UPD, ARM::VLD4LNd8_UPD, true, true, true, SingleSpc, 4, 8 ,true},
  313. { ARM::VLD4LNq16Pseudo, ARM::VLD4LNq16, true, false, false, EvenDblSpc, 4, 4 ,true},
  314. { ARM::VLD4LNq16Pseudo_UPD, ARM::VLD4LNq16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true},
  315. { ARM::VLD4LNq32Pseudo, ARM::VLD4LNq32, true, false, false, EvenDblSpc, 4, 2 ,true},
  316. { ARM::VLD4LNq32Pseudo_UPD, ARM::VLD4LNq32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true},
  317. { ARM::VLD4d16Pseudo, ARM::VLD4d16, true, false, false, SingleSpc, 4, 4 ,true},
  318. { ARM::VLD4d16Pseudo_UPD, ARM::VLD4d16_UPD, true, true, true, SingleSpc, 4, 4 ,true},
  319. { ARM::VLD4d32Pseudo, ARM::VLD4d32, true, false, false, SingleSpc, 4, 2 ,true},
  320. { ARM::VLD4d32Pseudo_UPD, ARM::VLD4d32_UPD, true, true, true, SingleSpc, 4, 2 ,true},
  321. { ARM::VLD4d8Pseudo, ARM::VLD4d8, true, false, false, SingleSpc, 4, 8 ,true},
  322. { ARM::VLD4d8Pseudo_UPD, ARM::VLD4d8_UPD, true, true, true, SingleSpc, 4, 8 ,true},
  323. { ARM::VLD4q16Pseudo_UPD, ARM::VLD4q16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true},
  324. { ARM::VLD4q16oddPseudo, ARM::VLD4q16, true, false, false, OddDblSpc, 4, 4 ,true},
  325. { ARM::VLD4q16oddPseudo_UPD, ARM::VLD4q16_UPD, true, true, true, OddDblSpc, 4, 4 ,true},
  326. { ARM::VLD4q32Pseudo_UPD, ARM::VLD4q32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true},
  327. { ARM::VLD4q32oddPseudo, ARM::VLD4q32, true, false, false, OddDblSpc, 4, 2 ,true},
  328. { ARM::VLD4q32oddPseudo_UPD, ARM::VLD4q32_UPD, true, true, true, OddDblSpc, 4, 2 ,true},
  329. { ARM::VLD4q8Pseudo_UPD, ARM::VLD4q8_UPD, true, true, true, EvenDblSpc, 4, 8 ,true},
  330. { ARM::VLD4q8oddPseudo, ARM::VLD4q8, true, false, false, OddDblSpc, 4, 8 ,true},
  331. { ARM::VLD4q8oddPseudo_UPD, ARM::VLD4q8_UPD, true, true, true, OddDblSpc, 4, 8 ,true},
  332. { ARM::VST1LNq16Pseudo, ARM::VST1LNd16, false, false, false, EvenDblSpc, 1, 4 ,true},
  333. { ARM::VST1LNq16Pseudo_UPD, ARM::VST1LNd16_UPD, false, true, true, EvenDblSpc, 1, 4 ,true},
  334. { ARM::VST1LNq32Pseudo, ARM::VST1LNd32, false, false, false, EvenDblSpc, 1, 2 ,true},
  335. { ARM::VST1LNq32Pseudo_UPD, ARM::VST1LNd32_UPD, false, true, true, EvenDblSpc, 1, 2 ,true},
  336. { ARM::VST1LNq8Pseudo, ARM::VST1LNd8, false, false, false, EvenDblSpc, 1, 8 ,true},
  337. { ARM::VST1LNq8Pseudo_UPD, ARM::VST1LNd8_UPD, false, true, true, EvenDblSpc, 1, 8 ,true},
  338. { ARM::VST1d16QPseudo, ARM::VST1d16Q, false, false, false, SingleSpc, 4, 4 ,false},
  339. { ARM::VST1d16QPseudoWB_fixed, ARM::VST1d16Qwb_fixed, false, true, false, SingleSpc, 4, 4 ,false},
  340. { ARM::VST1d16QPseudoWB_register, ARM::VST1d16Qwb_register, false, true, true, SingleSpc, 4, 4 ,false},
  341. { ARM::VST1d16TPseudo, ARM::VST1d16T, false, false, false, SingleSpc, 3, 4 ,false},
  342. { ARM::VST1d16TPseudoWB_fixed, ARM::VST1d16Twb_fixed, false, true, false, SingleSpc, 3, 4 ,false},
  343. { ARM::VST1d16TPseudoWB_register, ARM::VST1d16Twb_register, false, true, true, SingleSpc, 3, 4 ,false},
  344. { ARM::VST1d32QPseudo, ARM::VST1d32Q, false, false, false, SingleSpc, 4, 2 ,false},
  345. { ARM::VST1d32QPseudoWB_fixed, ARM::VST1d32Qwb_fixed, false, true, false, SingleSpc, 4, 2 ,false},
  346. { ARM::VST1d32QPseudoWB_register, ARM::VST1d32Qwb_register, false, true, true, SingleSpc, 4, 2 ,false},
  347. { ARM::VST1d32TPseudo, ARM::VST1d32T, false, false, false, SingleSpc, 3, 2 ,false},
  348. { ARM::VST1d32TPseudoWB_fixed, ARM::VST1d32Twb_fixed, false, true, false, SingleSpc, 3, 2 ,false},
  349. { ARM::VST1d32TPseudoWB_register, ARM::VST1d32Twb_register, false, true, true, SingleSpc, 3, 2 ,false},
  350. { ARM::VST1d64QPseudo, ARM::VST1d64Q, false, false, false, SingleSpc, 4, 1 ,false},
  351. { ARM::VST1d64QPseudoWB_fixed, ARM::VST1d64Qwb_fixed, false, true, false, SingleSpc, 4, 1 ,false},
  352. { ARM::VST1d64QPseudoWB_register, ARM::VST1d64Qwb_register, false, true, true, SingleSpc, 4, 1 ,false},
  353. { ARM::VST1d64TPseudo, ARM::VST1d64T, false, false, false, SingleSpc, 3, 1 ,false},
  354. { ARM::VST1d64TPseudoWB_fixed, ARM::VST1d64Twb_fixed, false, true, false, SingleSpc, 3, 1 ,false},
  355. { ARM::VST1d64TPseudoWB_register, ARM::VST1d64Twb_register, false, true, true, SingleSpc, 3, 1 ,false},
  356. { ARM::VST1d8QPseudo, ARM::VST1d8Q, false, false, false, SingleSpc, 4, 8 ,false},
  357. { ARM::VST1d8QPseudoWB_fixed, ARM::VST1d8Qwb_fixed, false, true, false, SingleSpc, 4, 8 ,false},
  358. { ARM::VST1d8QPseudoWB_register, ARM::VST1d8Qwb_register, false, true, true, SingleSpc, 4, 8 ,false},
  359. { ARM::VST1d8TPseudo, ARM::VST1d8T, false, false, false, SingleSpc, 3, 8 ,false},
  360. { ARM::VST1d8TPseudoWB_fixed, ARM::VST1d8Twb_fixed, false, true, false, SingleSpc, 3, 8 ,false},
  361. { ARM::VST1d8TPseudoWB_register, ARM::VST1d8Twb_register, false, true, true, SingleSpc, 3, 8 ,false},
  362. { ARM::VST1q16HighQPseudo, ARM::VST1d16Q, false, false, false, SingleHighQSpc, 4, 4 ,false},
  363. { ARM::VST1q16HighQPseudo_UPD, ARM::VST1d16Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
  364. { ARM::VST1q16HighTPseudo, ARM::VST1d16T, false, false, false, SingleHighTSpc, 3, 4 ,false},
  365. { ARM::VST1q16HighTPseudo_UPD, ARM::VST1d16Twb_fixed, false, true, true, SingleHighTSpc, 3, 4 ,false},
  366. { ARM::VST1q16LowQPseudo_UPD, ARM::VST1d16Qwb_fixed, false, true, true, SingleLowSpc, 4, 4 ,false},
  367. { ARM::VST1q16LowTPseudo_UPD, ARM::VST1d16Twb_fixed, false, true, true, SingleLowSpc, 3, 4 ,false},
  368. { ARM::VST1q32HighQPseudo, ARM::VST1d32Q, false, false, false, SingleHighQSpc, 4, 2 ,false},
  369. { ARM::VST1q32HighQPseudo_UPD, ARM::VST1d32Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
  370. { ARM::VST1q32HighTPseudo, ARM::VST1d32T, false, false, false, SingleHighTSpc, 3, 2 ,false},
  371. { ARM::VST1q32HighTPseudo_UPD, ARM::VST1d32Twb_fixed, false, true, true, SingleHighTSpc, 3, 2 ,false},
  372. { ARM::VST1q32LowQPseudo_UPD, ARM::VST1d32Qwb_fixed, false, true, true, SingleLowSpc, 4, 2 ,false},
  373. { ARM::VST1q32LowTPseudo_UPD, ARM::VST1d32Twb_fixed, false, true, true, SingleLowSpc, 3, 2 ,false},
  374. { ARM::VST1q64HighQPseudo, ARM::VST1d64Q, false, false, false, SingleHighQSpc, 4, 1 ,false},
  375. { ARM::VST1q64HighQPseudo_UPD, ARM::VST1d64Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
  376. { ARM::VST1q64HighTPseudo, ARM::VST1d64T, false, false, false, SingleHighTSpc, 3, 1 ,false},
  377. { ARM::VST1q64HighTPseudo_UPD, ARM::VST1d64Twb_fixed, false, true, true, SingleHighTSpc, 3, 1 ,false},
  378. { ARM::VST1q64LowQPseudo_UPD, ARM::VST1d64Qwb_fixed, false, true, true, SingleLowSpc, 4, 1 ,false},
  379. { ARM::VST1q64LowTPseudo_UPD, ARM::VST1d64Twb_fixed, false, true, true, SingleLowSpc, 3, 1 ,false},
  380. { ARM::VST1q8HighQPseudo, ARM::VST1d8Q, false, false, false, SingleHighQSpc, 4, 8 ,false},
  381. { ARM::VST1q8HighQPseudo_UPD, ARM::VST1d8Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
  382. { ARM::VST1q8HighTPseudo, ARM::VST1d8T, false, false, false, SingleHighTSpc, 3, 8 ,false},
  383. { ARM::VST1q8HighTPseudo_UPD, ARM::VST1d8Twb_fixed, false, true, true, SingleHighTSpc, 3, 8 ,false},
  384. { ARM::VST1q8LowQPseudo_UPD, ARM::VST1d8Qwb_fixed, false, true, true, SingleLowSpc, 4, 8 ,false},
  385. { ARM::VST1q8LowTPseudo_UPD, ARM::VST1d8Twb_fixed, false, true, true, SingleLowSpc, 3, 8 ,false},
  386. { ARM::VST2LNd16Pseudo, ARM::VST2LNd16, false, false, false, SingleSpc, 2, 4 ,true},
  387. { ARM::VST2LNd16Pseudo_UPD, ARM::VST2LNd16_UPD, false, true, true, SingleSpc, 2, 4 ,true},
  388. { ARM::VST2LNd32Pseudo, ARM::VST2LNd32, false, false, false, SingleSpc, 2, 2 ,true},
  389. { ARM::VST2LNd32Pseudo_UPD, ARM::VST2LNd32_UPD, false, true, true, SingleSpc, 2, 2 ,true},
  390. { ARM::VST2LNd8Pseudo, ARM::VST2LNd8, false, false, false, SingleSpc, 2, 8 ,true},
  391. { ARM::VST2LNd8Pseudo_UPD, ARM::VST2LNd8_UPD, false, true, true, SingleSpc, 2, 8 ,true},
  392. { ARM::VST2LNq16Pseudo, ARM::VST2LNq16, false, false, false, EvenDblSpc, 2, 4,true},
  393. { ARM::VST2LNq16Pseudo_UPD, ARM::VST2LNq16_UPD, false, true, true, EvenDblSpc, 2, 4,true},
  394. { ARM::VST2LNq32Pseudo, ARM::VST2LNq32, false, false, false, EvenDblSpc, 2, 2,true},
  395. { ARM::VST2LNq32Pseudo_UPD, ARM::VST2LNq32_UPD, false, true, true, EvenDblSpc, 2, 2,true},
  396. { ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,false},
  397. { ARM::VST2q16PseudoWB_fixed, ARM::VST2q16wb_fixed, false, true, false, SingleSpc, 4, 4 ,false},
  398. { ARM::VST2q16PseudoWB_register, ARM::VST2q16wb_register, false, true, true, SingleSpc, 4, 4 ,false},
  399. { ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,false},
  400. { ARM::VST2q32PseudoWB_fixed, ARM::VST2q32wb_fixed, false, true, false, SingleSpc, 4, 2 ,false},
  401. { ARM::VST2q32PseudoWB_register, ARM::VST2q32wb_register, false, true, true, SingleSpc, 4, 2 ,false},
  402. { ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,false},
  403. { ARM::VST2q8PseudoWB_fixed, ARM::VST2q8wb_fixed, false, true, false, SingleSpc, 4, 8 ,false},
  404. { ARM::VST2q8PseudoWB_register, ARM::VST2q8wb_register, false, true, true, SingleSpc, 4, 8 ,false},
  405. { ARM::VST3LNd16Pseudo, ARM::VST3LNd16, false, false, false, SingleSpc, 3, 4 ,true},
  406. { ARM::VST3LNd16Pseudo_UPD, ARM::VST3LNd16_UPD, false, true, true, SingleSpc, 3, 4 ,true},
  407. { ARM::VST3LNd32Pseudo, ARM::VST3LNd32, false, false, false, SingleSpc, 3, 2 ,true},
  408. { ARM::VST3LNd32Pseudo_UPD, ARM::VST3LNd32_UPD, false, true, true, SingleSpc, 3, 2 ,true},
  409. { ARM::VST3LNd8Pseudo, ARM::VST3LNd8, false, false, false, SingleSpc, 3, 8 ,true},
  410. { ARM::VST3LNd8Pseudo_UPD, ARM::VST3LNd8_UPD, false, true, true, SingleSpc, 3, 8 ,true},
  411. { ARM::VST3LNq16Pseudo, ARM::VST3LNq16, false, false, false, EvenDblSpc, 3, 4,true},
  412. { ARM::VST3LNq16Pseudo_UPD, ARM::VST3LNq16_UPD, false, true, true, EvenDblSpc, 3, 4,true},
  413. { ARM::VST3LNq32Pseudo, ARM::VST3LNq32, false, false, false, EvenDblSpc, 3, 2,true},
  414. { ARM::VST3LNq32Pseudo_UPD, ARM::VST3LNq32_UPD, false, true, true, EvenDblSpc, 3, 2,true},
  415. { ARM::VST3d16Pseudo, ARM::VST3d16, false, false, false, SingleSpc, 3, 4 ,true},
  416. { ARM::VST3d16Pseudo_UPD, ARM::VST3d16_UPD, false, true, true, SingleSpc, 3, 4 ,true},
  417. { ARM::VST3d32Pseudo, ARM::VST3d32, false, false, false, SingleSpc, 3, 2 ,true},
  418. { ARM::VST3d32Pseudo_UPD, ARM::VST3d32_UPD, false, true, true, SingleSpc, 3, 2 ,true},
  419. { ARM::VST3d8Pseudo, ARM::VST3d8, false, false, false, SingleSpc, 3, 8 ,true},
  420. { ARM::VST3d8Pseudo_UPD, ARM::VST3d8_UPD, false, true, true, SingleSpc, 3, 8 ,true},
  421. { ARM::VST3q16Pseudo_UPD, ARM::VST3q16_UPD, false, true, true, EvenDblSpc, 3, 4 ,true},
  422. { ARM::VST3q16oddPseudo, ARM::VST3q16, false, false, false, OddDblSpc, 3, 4 ,true},
  423. { ARM::VST3q16oddPseudo_UPD, ARM::VST3q16_UPD, false, true, true, OddDblSpc, 3, 4 ,true},
  424. { ARM::VST3q32Pseudo_UPD, ARM::VST3q32_UPD, false, true, true, EvenDblSpc, 3, 2 ,true},
  425. { ARM::VST3q32oddPseudo, ARM::VST3q32, false, false, false, OddDblSpc, 3, 2 ,true},
  426. { ARM::VST3q32oddPseudo_UPD, ARM::VST3q32_UPD, false, true, true, OddDblSpc, 3, 2 ,true},
  427. { ARM::VST3q8Pseudo_UPD, ARM::VST3q8_UPD, false, true, true, EvenDblSpc, 3, 8 ,true},
  428. { ARM::VST3q8oddPseudo, ARM::VST3q8, false, false, false, OddDblSpc, 3, 8 ,true},
  429. { ARM::VST3q8oddPseudo_UPD, ARM::VST3q8_UPD, false, true, true, OddDblSpc, 3, 8 ,true},
  430. { ARM::VST4LNd16Pseudo, ARM::VST4LNd16, false, false, false, SingleSpc, 4, 4 ,true},
  431. { ARM::VST4LNd16Pseudo_UPD, ARM::VST4LNd16_UPD, false, true, true, SingleSpc, 4, 4 ,true},
  432. { ARM::VST4LNd32Pseudo, ARM::VST4LNd32, false, false, false, SingleSpc, 4, 2 ,true},
  433. { ARM::VST4LNd32Pseudo_UPD, ARM::VST4LNd32_UPD, false, true, true, SingleSpc, 4, 2 ,true},
  434. { ARM::VST4LNd8Pseudo, ARM::VST4LNd8, false, false, false, SingleSpc, 4, 8 ,true},
  435. { ARM::VST4LNd8Pseudo_UPD, ARM::VST4LNd8_UPD, false, true, true, SingleSpc, 4, 8 ,true},
  436. { ARM::VST4LNq16Pseudo, ARM::VST4LNq16, false, false, false, EvenDblSpc, 4, 4,true},
  437. { ARM::VST4LNq16Pseudo_UPD, ARM::VST4LNq16_UPD, false, true, true, EvenDblSpc, 4, 4,true},
  438. { ARM::VST4LNq32Pseudo, ARM::VST4LNq32, false, false, false, EvenDblSpc, 4, 2,true},
  439. { ARM::VST4LNq32Pseudo_UPD, ARM::VST4LNq32_UPD, false, true, true, EvenDblSpc, 4, 2,true},
  440. { ARM::VST4d16Pseudo, ARM::VST4d16, false, false, false, SingleSpc, 4, 4 ,true},
  441. { ARM::VST4d16Pseudo_UPD, ARM::VST4d16_UPD, false, true, true, SingleSpc, 4, 4 ,true},
  442. { ARM::VST4d32Pseudo, ARM::VST4d32, false, false, false, SingleSpc, 4, 2 ,true},
  443. { ARM::VST4d32Pseudo_UPD, ARM::VST4d32_UPD, false, true, true, SingleSpc, 4, 2 ,true},
  444. { ARM::VST4d8Pseudo, ARM::VST4d8, false, false, false, SingleSpc, 4, 8 ,true},
  445. { ARM::VST4d8Pseudo_UPD, ARM::VST4d8_UPD, false, true, true, SingleSpc, 4, 8 ,true},
  446. { ARM::VST4q16Pseudo_UPD, ARM::VST4q16_UPD, false, true, true, EvenDblSpc, 4, 4 ,true},
  447. { ARM::VST4q16oddPseudo, ARM::VST4q16, false, false, false, OddDblSpc, 4, 4 ,true},
  448. { ARM::VST4q16oddPseudo_UPD, ARM::VST4q16_UPD, false, true, true, OddDblSpc, 4, 4 ,true},
  449. { ARM::VST4q32Pseudo_UPD, ARM::VST4q32_UPD, false, true, true, EvenDblSpc, 4, 2 ,true},
  450. { ARM::VST4q32oddPseudo, ARM::VST4q32, false, false, false, OddDblSpc, 4, 2 ,true},
  451. { ARM::VST4q32oddPseudo_UPD, ARM::VST4q32_UPD, false, true, true, OddDblSpc, 4, 2 ,true},
  452. { ARM::VST4q8Pseudo_UPD, ARM::VST4q8_UPD, false, true, true, EvenDblSpc, 4, 8 ,true},
  453. { ARM::VST4q8oddPseudo, ARM::VST4q8, false, false, false, OddDblSpc, 4, 8 ,true},
  454. { ARM::VST4q8oddPseudo_UPD, ARM::VST4q8_UPD, false, true, true, OddDblSpc, 4, 8 ,true}
  455. };
  456. /// LookupNEONLdSt - Search the NEONLdStTable for information about a NEON
  457. /// load or store pseudo instruction.
  458. static const NEONLdStTableEntry *LookupNEONLdSt(unsigned Opcode) {
  459. #ifndef NDEBUG
  460. // Make sure the table is sorted.
  461. static std::atomic<bool> TableChecked(false);
  462. if (!TableChecked.load(std::memory_order_relaxed)) {
  463. assert(llvm::is_sorted(NEONLdStTable) && "NEONLdStTable is not sorted!");
  464. TableChecked.store(true, std::memory_order_relaxed);
  465. }
  466. #endif
  467. auto I = llvm::lower_bound(NEONLdStTable, Opcode);
  468. if (I != std::end(NEONLdStTable) && I->PseudoOpc == Opcode)
  469. return I;
  470. return nullptr;
  471. }
  472. /// GetDSubRegs - Get 4 D subregisters of a Q, QQ, or QQQQ register,
  473. /// corresponding to the specified register spacing. Not all of the results
  474. /// are necessarily valid, e.g., a Q register only has 2 D subregisters.
  475. static void GetDSubRegs(unsigned Reg, NEONRegSpacing RegSpc,
  476. const TargetRegisterInfo *TRI, unsigned &D0,
  477. unsigned &D1, unsigned &D2, unsigned &D3) {
  478. if (RegSpc == SingleSpc || RegSpc == SingleLowSpc) {
  479. D0 = TRI->getSubReg(Reg, ARM::dsub_0);
  480. D1 = TRI->getSubReg(Reg, ARM::dsub_1);
  481. D2 = TRI->getSubReg(Reg, ARM::dsub_2);
  482. D3 = TRI->getSubReg(Reg, ARM::dsub_3);
  483. } else if (RegSpc == SingleHighQSpc) {
  484. D0 = TRI->getSubReg(Reg, ARM::dsub_4);
  485. D1 = TRI->getSubReg(Reg, ARM::dsub_5);
  486. D2 = TRI->getSubReg(Reg, ARM::dsub_6);
  487. D3 = TRI->getSubReg(Reg, ARM::dsub_7);
  488. } else if (RegSpc == SingleHighTSpc) {
  489. D0 = TRI->getSubReg(Reg, ARM::dsub_3);
  490. D1 = TRI->getSubReg(Reg, ARM::dsub_4);
  491. D2 = TRI->getSubReg(Reg, ARM::dsub_5);
  492. D3 = TRI->getSubReg(Reg, ARM::dsub_6);
  493. } else if (RegSpc == EvenDblSpc) {
  494. D0 = TRI->getSubReg(Reg, ARM::dsub_0);
  495. D1 = TRI->getSubReg(Reg, ARM::dsub_2);
  496. D2 = TRI->getSubReg(Reg, ARM::dsub_4);
  497. D3 = TRI->getSubReg(Reg, ARM::dsub_6);
  498. } else {
  499. assert(RegSpc == OddDblSpc && "unknown register spacing");
  500. D0 = TRI->getSubReg(Reg, ARM::dsub_1);
  501. D1 = TRI->getSubReg(Reg, ARM::dsub_3);
  502. D2 = TRI->getSubReg(Reg, ARM::dsub_5);
  503. D3 = TRI->getSubReg(Reg, ARM::dsub_7);
  504. }
  505. }
  506. /// ExpandVLD - Translate VLD pseudo instructions with Q, QQ or QQQQ register
  507. /// operands to real VLD instructions with D register operands.
  508. void ARMExpandPseudo::ExpandVLD(MachineBasicBlock::iterator &MBBI) {
  509. MachineInstr &MI = *MBBI;
  510. MachineBasicBlock &MBB = *MI.getParent();
  511. LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
  512. const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
  513. assert(TableEntry && TableEntry->IsLoad && "NEONLdStTable lookup failed");
  514. NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
  515. unsigned NumRegs = TableEntry->NumRegs;
  516. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
  517. TII->get(TableEntry->RealOpc));
  518. unsigned OpIdx = 0;
  519. bool DstIsDead = MI.getOperand(OpIdx).isDead();
  520. Register DstReg = MI.getOperand(OpIdx++).getReg();
  521. bool IsVLD2DUP = TableEntry->RealOpc == ARM::VLD2DUPd8x2 ||
  522. TableEntry->RealOpc == ARM::VLD2DUPd16x2 ||
  523. TableEntry->RealOpc == ARM::VLD2DUPd32x2 ||
  524. TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_fixed ||
  525. TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_fixed ||
  526. TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_fixed ||
  527. TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_register ||
  528. TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_register ||
  529. TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_register;
  530. if (IsVLD2DUP) {
  531. unsigned SubRegIndex;
  532. if (RegSpc == EvenDblSpc) {
  533. SubRegIndex = ARM::dsub_0;
  534. } else {
  535. assert(RegSpc == OddDblSpc && "Unexpected spacing!");
  536. SubRegIndex = ARM::dsub_1;
  537. }
  538. Register SubReg = TRI->getSubReg(DstReg, SubRegIndex);
  539. unsigned DstRegPair = TRI->getMatchingSuperReg(SubReg, ARM::dsub_0,
  540. &ARM::DPairSpcRegClass);
  541. MIB.addReg(DstRegPair, RegState::Define | getDeadRegState(DstIsDead));
  542. } else {
  543. unsigned D0, D1, D2, D3;
  544. GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3);
  545. MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead));
  546. if (NumRegs > 1 && TableEntry->copyAllListRegs)
  547. MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
  548. if (NumRegs > 2 && TableEntry->copyAllListRegs)
  549. MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead));
  550. if (NumRegs > 3 && TableEntry->copyAllListRegs)
  551. MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
  552. }
  553. if (TableEntry->isUpdating)
  554. MIB.add(MI.getOperand(OpIdx++));
  555. // Copy the addrmode6 operands.
  556. MIB.add(MI.getOperand(OpIdx++));
  557. MIB.add(MI.getOperand(OpIdx++));
  558. // Copy the am6offset operand.
  559. if (TableEntry->hasWritebackOperand) {
  560. // TODO: The writing-back pseudo instructions we translate here are all
  561. // defined to take am6offset nodes that are capable to represent both fixed
  562. // and register forms. Some real instructions, however, do not rely on
  563. // am6offset and have separate definitions for such forms. When this is the
  564. // case, fixed forms do not take any offset nodes, so here we skip them for
  565. // such instructions. Once all real and pseudo writing-back instructions are
  566. // rewritten without use of am6offset nodes, this code will go away.
  567. const MachineOperand &AM6Offset = MI.getOperand(OpIdx++);
  568. if (TableEntry->RealOpc == ARM::VLD1d8Qwb_fixed ||
  569. TableEntry->RealOpc == ARM::VLD1d16Qwb_fixed ||
  570. TableEntry->RealOpc == ARM::VLD1d32Qwb_fixed ||
  571. TableEntry->RealOpc == ARM::VLD1d64Qwb_fixed ||
  572. TableEntry->RealOpc == ARM::VLD1d8Twb_fixed ||
  573. TableEntry->RealOpc == ARM::VLD1d16Twb_fixed ||
  574. TableEntry->RealOpc == ARM::VLD1d32Twb_fixed ||
  575. TableEntry->RealOpc == ARM::VLD1d64Twb_fixed ||
  576. TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_fixed ||
  577. TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_fixed ||
  578. TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_fixed) {
  579. assert(AM6Offset.getReg() == 0 &&
  580. "A fixed writing-back pseudo instruction provides an offset "
  581. "register!");
  582. } else {
  583. MIB.add(AM6Offset);
  584. }
  585. }
  586. // For an instruction writing double-spaced subregs, the pseudo instruction
  587. // has an extra operand that is a use of the super-register. Record the
  588. // operand index and skip over it.
  589. unsigned SrcOpIdx = 0;
  590. if (!IsVLD2DUP) {
  591. if (RegSpc == EvenDblSpc || RegSpc == OddDblSpc ||
  592. RegSpc == SingleLowSpc || RegSpc == SingleHighQSpc ||
  593. RegSpc == SingleHighTSpc)
  594. SrcOpIdx = OpIdx++;
  595. }
  596. // Copy the predicate operands.
  597. MIB.add(MI.getOperand(OpIdx++));
  598. MIB.add(MI.getOperand(OpIdx++));
  599. // Copy the super-register source operand used for double-spaced subregs over
  600. // to the new instruction as an implicit operand.
  601. if (SrcOpIdx != 0) {
  602. MachineOperand MO = MI.getOperand(SrcOpIdx);
  603. MO.setImplicit(true);
  604. MIB.add(MO);
  605. }
  606. // Add an implicit def for the super-register.
  607. MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
  608. TransferImpOps(MI, MIB, MIB);
  609. // Transfer memoperands.
  610. MIB.cloneMemRefs(MI);
  611. MI.eraseFromParent();
  612. LLVM_DEBUG(dbgs() << "To: "; MIB.getInstr()->dump(););
  613. }
  614. /// ExpandVST - Translate VST pseudo instructions with Q, QQ or QQQQ register
  615. /// operands to real VST instructions with D register operands.
  616. void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI) {
  617. MachineInstr &MI = *MBBI;
  618. MachineBasicBlock &MBB = *MI.getParent();
  619. LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
  620. const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
  621. assert(TableEntry && !TableEntry->IsLoad && "NEONLdStTable lookup failed");
  622. NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
  623. unsigned NumRegs = TableEntry->NumRegs;
  624. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
  625. TII->get(TableEntry->RealOpc));
  626. unsigned OpIdx = 0;
  627. if (TableEntry->isUpdating)
  628. MIB.add(MI.getOperand(OpIdx++));
  629. // Copy the addrmode6 operands.
  630. MIB.add(MI.getOperand(OpIdx++));
  631. MIB.add(MI.getOperand(OpIdx++));
  632. if (TableEntry->hasWritebackOperand) {
  633. // TODO: The writing-back pseudo instructions we translate here are all
  634. // defined to take am6offset nodes that are capable to represent both fixed
  635. // and register forms. Some real instructions, however, do not rely on
  636. // am6offset and have separate definitions for such forms. When this is the
  637. // case, fixed forms do not take any offset nodes, so here we skip them for
  638. // such instructions. Once all real and pseudo writing-back instructions are
  639. // rewritten without use of am6offset nodes, this code will go away.
  640. const MachineOperand &AM6Offset = MI.getOperand(OpIdx++);
  641. if (TableEntry->RealOpc == ARM::VST1d8Qwb_fixed ||
  642. TableEntry->RealOpc == ARM::VST1d16Qwb_fixed ||
  643. TableEntry->RealOpc == ARM::VST1d32Qwb_fixed ||
  644. TableEntry->RealOpc == ARM::VST1d64Qwb_fixed ||
  645. TableEntry->RealOpc == ARM::VST1d8Twb_fixed ||
  646. TableEntry->RealOpc == ARM::VST1d16Twb_fixed ||
  647. TableEntry->RealOpc == ARM::VST1d32Twb_fixed ||
  648. TableEntry->RealOpc == ARM::VST1d64Twb_fixed) {
  649. assert(AM6Offset.getReg() == 0 &&
  650. "A fixed writing-back pseudo instruction provides an offset "
  651. "register!");
  652. } else {
  653. MIB.add(AM6Offset);
  654. }
  655. }
  656. bool SrcIsKill = MI.getOperand(OpIdx).isKill();
  657. bool SrcIsUndef = MI.getOperand(OpIdx).isUndef();
  658. Register SrcReg = MI.getOperand(OpIdx++).getReg();
  659. unsigned D0, D1, D2, D3;
  660. GetDSubRegs(SrcReg, RegSpc, TRI, D0, D1, D2, D3);
  661. MIB.addReg(D0, getUndefRegState(SrcIsUndef));
  662. if (NumRegs > 1 && TableEntry->copyAllListRegs)
  663. MIB.addReg(D1, getUndefRegState(SrcIsUndef));
  664. if (NumRegs > 2 && TableEntry->copyAllListRegs)
  665. MIB.addReg(D2, getUndefRegState(SrcIsUndef));
  666. if (NumRegs > 3 && TableEntry->copyAllListRegs)
  667. MIB.addReg(D3, getUndefRegState(SrcIsUndef));
  668. // Copy the predicate operands.
  669. MIB.add(MI.getOperand(OpIdx++));
  670. MIB.add(MI.getOperand(OpIdx++));
  671. if (SrcIsKill && !SrcIsUndef) // Add an implicit kill for the super-reg.
  672. MIB->addRegisterKilled(SrcReg, TRI, true);
  673. else if (!SrcIsUndef)
  674. MIB.addReg(SrcReg, RegState::Implicit); // Add implicit uses for src reg.
  675. TransferImpOps(MI, MIB, MIB);
  676. // Transfer memoperands.
  677. MIB.cloneMemRefs(MI);
  678. MI.eraseFromParent();
  679. LLVM_DEBUG(dbgs() << "To: "; MIB.getInstr()->dump(););
  680. }
  681. /// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ
  682. /// register operands to real instructions with D register operands.
  683. void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) {
  684. MachineInstr &MI = *MBBI;
  685. MachineBasicBlock &MBB = *MI.getParent();
  686. LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
  687. const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
  688. assert(TableEntry && "NEONLdStTable lookup failed");
  689. NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
  690. unsigned NumRegs = TableEntry->NumRegs;
  691. unsigned RegElts = TableEntry->RegElts;
  692. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
  693. TII->get(TableEntry->RealOpc));
  694. unsigned OpIdx = 0;
  695. // The lane operand is always the 3rd from last operand, before the 2
  696. // predicate operands.
  697. unsigned Lane = MI.getOperand(MI.getDesc().getNumOperands() - 3).getImm();
  698. // Adjust the lane and spacing as needed for Q registers.
  699. assert(RegSpc != OddDblSpc && "unexpected register spacing for VLD/VST-lane");
  700. if (RegSpc == EvenDblSpc && Lane >= RegElts) {
  701. RegSpc = OddDblSpc;
  702. Lane -= RegElts;
  703. }
  704. assert(Lane < RegElts && "out of range lane for VLD/VST-lane");
  705. unsigned D0 = 0, D1 = 0, D2 = 0, D3 = 0;
  706. unsigned DstReg = 0;
  707. bool DstIsDead = false;
  708. if (TableEntry->IsLoad) {
  709. DstIsDead = MI.getOperand(OpIdx).isDead();
  710. DstReg = MI.getOperand(OpIdx++).getReg();
  711. GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3);
  712. MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead));
  713. if (NumRegs > 1)
  714. MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
  715. if (NumRegs > 2)
  716. MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead));
  717. if (NumRegs > 3)
  718. MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
  719. }
  720. if (TableEntry->isUpdating)
  721. MIB.add(MI.getOperand(OpIdx++));
  722. // Copy the addrmode6 operands.
  723. MIB.add(MI.getOperand(OpIdx++));
  724. MIB.add(MI.getOperand(OpIdx++));
  725. // Copy the am6offset operand.
  726. if (TableEntry->hasWritebackOperand)
  727. MIB.add(MI.getOperand(OpIdx++));
  728. // Grab the super-register source.
  729. MachineOperand MO = MI.getOperand(OpIdx++);
  730. if (!TableEntry->IsLoad)
  731. GetDSubRegs(MO.getReg(), RegSpc, TRI, D0, D1, D2, D3);
  732. // Add the subregs as sources of the new instruction.
  733. unsigned SrcFlags = (getUndefRegState(MO.isUndef()) |
  734. getKillRegState(MO.isKill()));
  735. MIB.addReg(D0, SrcFlags);
  736. if (NumRegs > 1)
  737. MIB.addReg(D1, SrcFlags);
  738. if (NumRegs > 2)
  739. MIB.addReg(D2, SrcFlags);
  740. if (NumRegs > 3)
  741. MIB.addReg(D3, SrcFlags);
  742. // Add the lane number operand.
  743. MIB.addImm(Lane);
  744. OpIdx += 1;
  745. // Copy the predicate operands.
  746. MIB.add(MI.getOperand(OpIdx++));
  747. MIB.add(MI.getOperand(OpIdx++));
  748. // Copy the super-register source to be an implicit source.
  749. MO.setImplicit(true);
  750. MIB.add(MO);
  751. if (TableEntry->IsLoad)
  752. // Add an implicit def for the super-register.
  753. MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
  754. TransferImpOps(MI, MIB, MIB);
  755. // Transfer memoperands.
  756. MIB.cloneMemRefs(MI);
  757. MI.eraseFromParent();
  758. }
  759. /// ExpandVTBL - Translate VTBL and VTBX pseudo instructions with Q or QQ
  760. /// register operands to real instructions with D register operands.
  761. void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI,
  762. unsigned Opc, bool IsExt) {
  763. MachineInstr &MI = *MBBI;
  764. MachineBasicBlock &MBB = *MI.getParent();
  765. LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
  766. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc));
  767. unsigned OpIdx = 0;
  768. // Transfer the destination register operand.
  769. MIB.add(MI.getOperand(OpIdx++));
  770. if (IsExt) {
  771. MachineOperand VdSrc(MI.getOperand(OpIdx++));
  772. MIB.add(VdSrc);
  773. }
  774. bool SrcIsKill = MI.getOperand(OpIdx).isKill();
  775. Register SrcReg = MI.getOperand(OpIdx++).getReg();
  776. unsigned D0, D1, D2, D3;
  777. GetDSubRegs(SrcReg, SingleSpc, TRI, D0, D1, D2, D3);
  778. MIB.addReg(D0);
  779. // Copy the other source register operand.
  780. MachineOperand VmSrc(MI.getOperand(OpIdx++));
  781. MIB.add(VmSrc);
  782. // Copy the predicate operands.
  783. MIB.add(MI.getOperand(OpIdx++));
  784. MIB.add(MI.getOperand(OpIdx++));
  785. // Add an implicit kill and use for the super-reg.
  786. MIB.addReg(SrcReg, RegState::Implicit | getKillRegState(SrcIsKill));
  787. TransferImpOps(MI, MIB, MIB);
  788. MI.eraseFromParent();
  789. LLVM_DEBUG(dbgs() << "To: "; MIB.getInstr()->dump(););
  790. }
  791. void ARMExpandPseudo::ExpandMQQPRLoadStore(MachineBasicBlock::iterator &MBBI) {
  792. MachineInstr &MI = *MBBI;
  793. MachineBasicBlock &MBB = *MI.getParent();
  794. unsigned NewOpc =
  795. MI.getOpcode() == ARM::MQQPRStore || MI.getOpcode() == ARM::MQQQQPRStore
  796. ? ARM::VSTMDIA
  797. : ARM::VLDMDIA;
  798. MachineInstrBuilder MIB =
  799. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
  800. unsigned Flags = getKillRegState(MI.getOperand(0).isKill()) |
  801. getDefRegState(MI.getOperand(0).isDef());
  802. Register SrcReg = MI.getOperand(0).getReg();
  803. // Copy the destination register.
  804. MIB.add(MI.getOperand(1));
  805. MIB.add(predOps(ARMCC::AL));
  806. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_0), Flags);
  807. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_1), Flags);
  808. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_2), Flags);
  809. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_3), Flags);
  810. if (MI.getOpcode() == ARM::MQQQQPRStore ||
  811. MI.getOpcode() == ARM::MQQQQPRLoad) {
  812. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_4), Flags);
  813. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_5), Flags);
  814. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_6), Flags);
  815. MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_7), Flags);
  816. }
  817. if (NewOpc == ARM::VSTMDIA)
  818. MIB.addReg(SrcReg, RegState::Implicit);
  819. TransferImpOps(MI, MIB, MIB);
  820. MIB.cloneMemRefs(MI);
  821. MI.eraseFromParent();
  822. }
  823. static bool IsAnAddressOperand(const MachineOperand &MO) {
  824. // This check is overly conservative. Unless we are certain that the machine
  825. // operand is not a symbol reference, we return that it is a symbol reference.
  826. // This is important as the load pair may not be split up Windows.
  827. switch (MO.getType()) {
  828. case MachineOperand::MO_Register:
  829. case MachineOperand::MO_Immediate:
  830. case MachineOperand::MO_CImmediate:
  831. case MachineOperand::MO_FPImmediate:
  832. case MachineOperand::MO_ShuffleMask:
  833. return false;
  834. case MachineOperand::MO_MachineBasicBlock:
  835. return true;
  836. case MachineOperand::MO_FrameIndex:
  837. return false;
  838. case MachineOperand::MO_ConstantPoolIndex:
  839. case MachineOperand::MO_TargetIndex:
  840. case MachineOperand::MO_JumpTableIndex:
  841. case MachineOperand::MO_ExternalSymbol:
  842. case MachineOperand::MO_GlobalAddress:
  843. case MachineOperand::MO_BlockAddress:
  844. return true;
  845. case MachineOperand::MO_RegisterMask:
  846. case MachineOperand::MO_RegisterLiveOut:
  847. return false;
  848. case MachineOperand::MO_Metadata:
  849. case MachineOperand::MO_MCSymbol:
  850. return true;
  851. case MachineOperand::MO_CFIIndex:
  852. return false;
  853. case MachineOperand::MO_IntrinsicID:
  854. case MachineOperand::MO_Predicate:
  855. llvm_unreachable("should not exist post-isel");
  856. }
  857. llvm_unreachable("unhandled machine operand type");
  858. }
  859. static MachineOperand makeImplicit(const MachineOperand &MO) {
  860. MachineOperand NewMO = MO;
  861. NewMO.setImplicit();
  862. return NewMO;
  863. }
  864. void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
  865. MachineBasicBlock::iterator &MBBI) {
  866. MachineInstr &MI = *MBBI;
  867. unsigned Opcode = MI.getOpcode();
  868. Register PredReg;
  869. ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
  870. Register DstReg = MI.getOperand(0).getReg();
  871. bool DstIsDead = MI.getOperand(0).isDead();
  872. bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
  873. const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
  874. bool RequiresBundling = STI->isTargetWindows() && IsAnAddressOperand(MO);
  875. MachineInstrBuilder LO16, HI16;
  876. LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
  877. if (!STI->hasV6T2Ops() &&
  878. (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) {
  879. // FIXME Windows CE supports older ARM CPUs
  880. assert(!STI->isTargetWindows() && "Windows on ARM requires ARMv7+");
  881. assert (MO.isImm() && "MOVi32imm w/ non-immediate source operand!");
  882. unsigned ImmVal = (unsigned)MO.getImm();
  883. unsigned SOImmValV1 = 0, SOImmValV2 = 0;
  884. if (ARM_AM::isSOImmTwoPartVal(ImmVal)) { // Expand into a movi + orr.
  885. LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
  886. HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))
  887. .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
  888. .addReg(DstReg);
  889. SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
  890. SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
  891. } else { // Expand into a mvn + sub.
  892. LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MVNi), DstReg);
  893. HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri))
  894. .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
  895. .addReg(DstReg);
  896. SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(-ImmVal);
  897. SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(-ImmVal);
  898. SOImmValV1 = ~(-SOImmValV1);
  899. }
  900. unsigned MIFlags = MI.getFlags();
  901. LO16 = LO16.addImm(SOImmValV1);
  902. HI16 = HI16.addImm(SOImmValV2);
  903. LO16.cloneMemRefs(MI);
  904. HI16.cloneMemRefs(MI);
  905. LO16.setMIFlags(MIFlags);
  906. HI16.setMIFlags(MIFlags);
  907. LO16.addImm(Pred).addReg(PredReg).add(condCodeOp());
  908. HI16.addImm(Pred).addReg(PredReg).add(condCodeOp());
  909. if (isCC)
  910. LO16.add(makeImplicit(MI.getOperand(1)));
  911. TransferImpOps(MI, LO16, HI16);
  912. MI.eraseFromParent();
  913. return;
  914. }
  915. unsigned LO16Opc = 0;
  916. unsigned HI16Opc = 0;
  917. unsigned MIFlags = MI.getFlags();
  918. if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
  919. LO16Opc = ARM::t2MOVi16;
  920. HI16Opc = ARM::t2MOVTi16;
  921. } else {
  922. LO16Opc = ARM::MOVi16;
  923. HI16Opc = ARM::MOVTi16;
  924. }
  925. LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
  926. HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
  927. .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
  928. .addReg(DstReg);
  929. LO16.setMIFlags(MIFlags);
  930. HI16.setMIFlags(MIFlags);
  931. switch (MO.getType()) {
  932. case MachineOperand::MO_Immediate: {
  933. unsigned Imm = MO.getImm();
  934. unsigned Lo16 = Imm & 0xffff;
  935. unsigned Hi16 = (Imm >> 16) & 0xffff;
  936. LO16 = LO16.addImm(Lo16);
  937. HI16 = HI16.addImm(Hi16);
  938. break;
  939. }
  940. case MachineOperand::MO_ExternalSymbol: {
  941. const char *ES = MO.getSymbolName();
  942. unsigned TF = MO.getTargetFlags();
  943. LO16 = LO16.addExternalSymbol(ES, TF | ARMII::MO_LO16);
  944. HI16 = HI16.addExternalSymbol(ES, TF | ARMII::MO_HI16);
  945. break;
  946. }
  947. default: {
  948. const GlobalValue *GV = MO.getGlobal();
  949. unsigned TF = MO.getTargetFlags();
  950. LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
  951. HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
  952. break;
  953. }
  954. }
  955. LO16.cloneMemRefs(MI);
  956. HI16.cloneMemRefs(MI);
  957. LO16.addImm(Pred).addReg(PredReg);
  958. HI16.addImm(Pred).addReg(PredReg);
  959. if (RequiresBundling)
  960. finalizeBundle(MBB, LO16->getIterator(), MBBI->getIterator());
  961. if (isCC)
  962. LO16.add(makeImplicit(MI.getOperand(1)));
  963. TransferImpOps(MI, LO16, HI16);
  964. MI.eraseFromParent();
  965. LLVM_DEBUG(dbgs() << "To: "; LO16.getInstr()->dump(););
  966. LLVM_DEBUG(dbgs() << "And: "; HI16.getInstr()->dump(););
  967. }
  968. // The size of the area, accessed by that VLSTM/VLLDM
  969. // S0-S31 + FPSCR + 8 more bytes (VPR + pad, or just pad)
  970. static const int CMSE_FP_SAVE_SIZE = 136;
  971. static void determineGPRegsToClear(const MachineInstr &MI,
  972. const std::initializer_list<unsigned> &Regs,
  973. SmallVectorImpl<unsigned> &ClearRegs) {
  974. SmallVector<unsigned, 4> OpRegs;
  975. for (const MachineOperand &Op : MI.operands()) {
  976. if (!Op.isReg() || !Op.isUse())
  977. continue;
  978. OpRegs.push_back(Op.getReg());
  979. }
  980. llvm::sort(OpRegs);
  981. std::set_difference(Regs.begin(), Regs.end(), OpRegs.begin(), OpRegs.end(),
  982. std::back_inserter(ClearRegs));
  983. }
  984. void ARMExpandPseudo::CMSEClearGPRegs(
  985. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
  986. const DebugLoc &DL, const SmallVectorImpl<unsigned> &ClearRegs,
  987. unsigned ClobberReg) {
  988. if (STI->hasV8_1MMainlineOps()) {
  989. // Clear the registers using the CLRM instruction.
  990. MachineInstrBuilder CLRM =
  991. BuildMI(MBB, MBBI, DL, TII->get(ARM::t2CLRM)).add(predOps(ARMCC::AL));
  992. for (unsigned R : ClearRegs)
  993. CLRM.addReg(R, RegState::Define);
  994. CLRM.addReg(ARM::APSR, RegState::Define);
  995. CLRM.addReg(ARM::CPSR, RegState::Define | RegState::Implicit);
  996. } else {
  997. // Clear the registers and flags by copying ClobberReg into them.
  998. // (Baseline can't do a high register clear in one instruction).
  999. for (unsigned Reg : ClearRegs) {
  1000. if (Reg == ClobberReg)
  1001. continue;
  1002. BuildMI(MBB, MBBI, DL, TII->get(ARM::tMOVr), Reg)
  1003. .addReg(ClobberReg)
  1004. .add(predOps(ARMCC::AL));
  1005. }
  1006. BuildMI(MBB, MBBI, DL, TII->get(ARM::t2MSR_M))
  1007. .addImm(STI->hasDSP() ? 0xc00 : 0x800)
  1008. .addReg(ClobberReg)
  1009. .add(predOps(ARMCC::AL));
  1010. }
  1011. }
  1012. // Find which FP registers need to be cleared. The parameter `ClearRegs` is
  1013. // initialised with all elements set to true, and this function resets all the
  1014. // bits, which correspond to register uses. Returns true if any floating point
  1015. // register is defined, false otherwise.
  1016. static bool determineFPRegsToClear(const MachineInstr &MI,
  1017. BitVector &ClearRegs) {
  1018. bool DefFP = false;
  1019. for (const MachineOperand &Op : MI.operands()) {
  1020. if (!Op.isReg())
  1021. continue;
  1022. Register Reg = Op.getReg();
  1023. if (Op.isDef()) {
  1024. if ((Reg >= ARM::Q0 && Reg <= ARM::Q7) ||
  1025. (Reg >= ARM::D0 && Reg <= ARM::D15) ||
  1026. (Reg >= ARM::S0 && Reg <= ARM::S31))
  1027. DefFP = true;
  1028. continue;
  1029. }
  1030. if (Reg >= ARM::Q0 && Reg <= ARM::Q7) {
  1031. int R = Reg - ARM::Q0;
  1032. ClearRegs.reset(R * 4, (R + 1) * 4);
  1033. } else if (Reg >= ARM::D0 && Reg <= ARM::D15) {
  1034. int R = Reg - ARM::D0;
  1035. ClearRegs.reset(R * 2, (R + 1) * 2);
  1036. } else if (Reg >= ARM::S0 && Reg <= ARM::S31) {
  1037. ClearRegs[Reg - ARM::S0] = false;
  1038. }
  1039. }
  1040. return DefFP;
  1041. }
  1042. MachineBasicBlock &
  1043. ARMExpandPseudo::CMSEClearFPRegs(MachineBasicBlock &MBB,
  1044. MachineBasicBlock::iterator MBBI) {
  1045. BitVector ClearRegs(16, true);
  1046. (void)determineFPRegsToClear(*MBBI, ClearRegs);
  1047. if (STI->hasV8_1MMainlineOps())
  1048. return CMSEClearFPRegsV81(MBB, MBBI, ClearRegs);
  1049. else
  1050. return CMSEClearFPRegsV8(MBB, MBBI, ClearRegs);
  1051. }
  1052. // Clear the FP registers for v8.0-M, by copying over the content
  1053. // of LR. Uses R12 as a scratch register.
  1054. MachineBasicBlock &
  1055. ARMExpandPseudo::CMSEClearFPRegsV8(MachineBasicBlock &MBB,
  1056. MachineBasicBlock::iterator MBBI,
  1057. const BitVector &ClearRegs) {
  1058. if (!STI->hasFPRegs())
  1059. return MBB;
  1060. auto &RetI = *MBBI;
  1061. const DebugLoc &DL = RetI.getDebugLoc();
  1062. // If optimising for minimum size, clear FP registers unconditionally.
  1063. // Otherwise, check the CONTROL.SFPA (Secure Floating-Point Active) bit and
  1064. // don't clear them if they belong to the non-secure state.
  1065. MachineBasicBlock *ClearBB, *DoneBB;
  1066. if (STI->hasMinSize()) {
  1067. ClearBB = DoneBB = &MBB;
  1068. } else {
  1069. MachineFunction *MF = MBB.getParent();
  1070. ClearBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1071. DoneBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1072. MF->insert(++MBB.getIterator(), ClearBB);
  1073. MF->insert(++ClearBB->getIterator(), DoneBB);
  1074. DoneBB->splice(DoneBB->end(), &MBB, MBBI, MBB.end());
  1075. DoneBB->transferSuccessors(&MBB);
  1076. MBB.addSuccessor(ClearBB);
  1077. MBB.addSuccessor(DoneBB);
  1078. ClearBB->addSuccessor(DoneBB);
  1079. // At the new basic blocks we need to have live-in the registers, used
  1080. // for the return value as well as LR, used to clear registers.
  1081. for (const MachineOperand &Op : RetI.operands()) {
  1082. if (!Op.isReg())
  1083. continue;
  1084. Register Reg = Op.getReg();
  1085. if (Reg == ARM::NoRegister || Reg == ARM::LR)
  1086. continue;
  1087. assert(Register::isPhysicalRegister(Reg) && "Unallocated register");
  1088. ClearBB->addLiveIn(Reg);
  1089. DoneBB->addLiveIn(Reg);
  1090. }
  1091. ClearBB->addLiveIn(ARM::LR);
  1092. DoneBB->addLiveIn(ARM::LR);
  1093. // Read the CONTROL register.
  1094. BuildMI(MBB, MBB.end(), DL, TII->get(ARM::t2MRS_M), ARM::R12)
  1095. .addImm(20)
  1096. .add(predOps(ARMCC::AL));
  1097. // Check bit 3 (SFPA).
  1098. BuildMI(MBB, MBB.end(), DL, TII->get(ARM::t2TSTri))
  1099. .addReg(ARM::R12)
  1100. .addImm(8)
  1101. .add(predOps(ARMCC::AL));
  1102. // If SFPA is clear, jump over ClearBB to DoneBB.
  1103. BuildMI(MBB, MBB.end(), DL, TII->get(ARM::tBcc))
  1104. .addMBB(DoneBB)
  1105. .addImm(ARMCC::EQ)
  1106. .addReg(ARM::CPSR, RegState::Kill);
  1107. }
  1108. // Emit the clearing sequence
  1109. for (unsigned D = 0; D < 8; D++) {
  1110. // Attempt to clear as double
  1111. if (ClearRegs[D * 2 + 0] && ClearRegs[D * 2 + 1]) {
  1112. unsigned Reg = ARM::D0 + D;
  1113. BuildMI(ClearBB, DL, TII->get(ARM::VMOVDRR), Reg)
  1114. .addReg(ARM::LR)
  1115. .addReg(ARM::LR)
  1116. .add(predOps(ARMCC::AL));
  1117. } else {
  1118. // Clear first part as single
  1119. if (ClearRegs[D * 2 + 0]) {
  1120. unsigned Reg = ARM::S0 + D * 2;
  1121. BuildMI(ClearBB, DL, TII->get(ARM::VMOVSR), Reg)
  1122. .addReg(ARM::LR)
  1123. .add(predOps(ARMCC::AL));
  1124. }
  1125. // Clear second part as single
  1126. if (ClearRegs[D * 2 + 1]) {
  1127. unsigned Reg = ARM::S0 + D * 2 + 1;
  1128. BuildMI(ClearBB, DL, TII->get(ARM::VMOVSR), Reg)
  1129. .addReg(ARM::LR)
  1130. .add(predOps(ARMCC::AL));
  1131. }
  1132. }
  1133. }
  1134. // Clear FPSCR bits 0-4, 7, 28-31
  1135. // The other bits are program global according to the AAPCS
  1136. BuildMI(ClearBB, DL, TII->get(ARM::VMRS), ARM::R12)
  1137. .add(predOps(ARMCC::AL));
  1138. BuildMI(ClearBB, DL, TII->get(ARM::t2BICri), ARM::R12)
  1139. .addReg(ARM::R12)
  1140. .addImm(0x0000009F)
  1141. .add(predOps(ARMCC::AL))
  1142. .add(condCodeOp());
  1143. BuildMI(ClearBB, DL, TII->get(ARM::t2BICri), ARM::R12)
  1144. .addReg(ARM::R12)
  1145. .addImm(0xF0000000)
  1146. .add(predOps(ARMCC::AL))
  1147. .add(condCodeOp());
  1148. BuildMI(ClearBB, DL, TII->get(ARM::VMSR))
  1149. .addReg(ARM::R12)
  1150. .add(predOps(ARMCC::AL));
  1151. return *DoneBB;
  1152. }
  1153. MachineBasicBlock &
  1154. ARMExpandPseudo::CMSEClearFPRegsV81(MachineBasicBlock &MBB,
  1155. MachineBasicBlock::iterator MBBI,
  1156. const BitVector &ClearRegs) {
  1157. auto &RetI = *MBBI;
  1158. // Emit a sequence of VSCCLRM <sreglist> instructions, one instruction for
  1159. // each contiguous sequence of S-registers.
  1160. int Start = -1, End = -1;
  1161. for (int S = 0, E = ClearRegs.size(); S != E; ++S) {
  1162. if (ClearRegs[S] && S == End + 1) {
  1163. End = S; // extend range
  1164. continue;
  1165. }
  1166. // Emit current range.
  1167. if (Start < End) {
  1168. MachineInstrBuilder VSCCLRM =
  1169. BuildMI(MBB, MBBI, RetI.getDebugLoc(), TII->get(ARM::VSCCLRMS))
  1170. .add(predOps(ARMCC::AL));
  1171. while (++Start <= End)
  1172. VSCCLRM.addReg(ARM::S0 + Start, RegState::Define);
  1173. VSCCLRM.addReg(ARM::VPR, RegState::Define);
  1174. }
  1175. Start = End = S;
  1176. }
  1177. // Emit last range.
  1178. if (Start < End) {
  1179. MachineInstrBuilder VSCCLRM =
  1180. BuildMI(MBB, MBBI, RetI.getDebugLoc(), TII->get(ARM::VSCCLRMS))
  1181. .add(predOps(ARMCC::AL));
  1182. while (++Start <= End)
  1183. VSCCLRM.addReg(ARM::S0 + Start, RegState::Define);
  1184. VSCCLRM.addReg(ARM::VPR, RegState::Define);
  1185. }
  1186. return MBB;
  1187. }
  1188. void ARMExpandPseudo::CMSESaveClearFPRegs(
  1189. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  1190. const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
  1191. if (STI->hasV8_1MMainlineOps())
  1192. CMSESaveClearFPRegsV81(MBB, MBBI, DL, LiveRegs);
  1193. else if (STI->hasV8MMainlineOps())
  1194. CMSESaveClearFPRegsV8(MBB, MBBI, DL, LiveRegs, ScratchRegs);
  1195. }
  1196. // Save and clear FP registers if present
  1197. void ARMExpandPseudo::CMSESaveClearFPRegsV8(
  1198. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  1199. const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
  1200. // Store an available register for FPSCR clearing
  1201. assert(!ScratchRegs.empty());
  1202. unsigned SpareReg = ScratchRegs.front();
  1203. // save space on stack for VLSTM
  1204. BuildMI(MBB, MBBI, DL, TII->get(ARM::tSUBspi), ARM::SP)
  1205. .addReg(ARM::SP)
  1206. .addImm(CMSE_FP_SAVE_SIZE >> 2)
  1207. .add(predOps(ARMCC::AL));
  1208. // Use ScratchRegs to store the fp regs
  1209. std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
  1210. std::vector<unsigned> NonclearedFPRegs;
  1211. for (const MachineOperand &Op : MBBI->operands()) {
  1212. if (Op.isReg() && Op.isUse()) {
  1213. Register Reg = Op.getReg();
  1214. assert(!ARM::DPRRegClass.contains(Reg) ||
  1215. ARM::DPR_VFP2RegClass.contains(Reg));
  1216. assert(!ARM::QPRRegClass.contains(Reg));
  1217. if (ARM::DPR_VFP2RegClass.contains(Reg)) {
  1218. if (ScratchRegs.size() >= 2) {
  1219. unsigned SaveReg2 = ScratchRegs.pop_back_val();
  1220. unsigned SaveReg1 = ScratchRegs.pop_back_val();
  1221. ClearedFPRegs.emplace_back(Reg, SaveReg1, SaveReg2);
  1222. // Save the fp register to the normal registers
  1223. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRRD))
  1224. .addReg(SaveReg1, RegState::Define)
  1225. .addReg(SaveReg2, RegState::Define)
  1226. .addReg(Reg)
  1227. .add(predOps(ARMCC::AL));
  1228. } else {
  1229. NonclearedFPRegs.push_back(Reg);
  1230. }
  1231. } else if (ARM::SPRRegClass.contains(Reg)) {
  1232. if (ScratchRegs.size() >= 1) {
  1233. unsigned SaveReg = ScratchRegs.pop_back_val();
  1234. ClearedFPRegs.emplace_back(Reg, SaveReg, 0);
  1235. // Save the fp register to the normal registers
  1236. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRS), SaveReg)
  1237. .addReg(Reg)
  1238. .add(predOps(ARMCC::AL));
  1239. } else {
  1240. NonclearedFPRegs.push_back(Reg);
  1241. }
  1242. }
  1243. }
  1244. }
  1245. bool passesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
  1246. if (passesFPReg)
  1247. assert(STI->hasFPRegs() && "Subtarget needs fpregs");
  1248. // Lazy store all fp registers to the stack.
  1249. // This executes as NOP in the absence of floating-point support.
  1250. MachineInstrBuilder VLSTM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLSTM))
  1251. .addReg(ARM::SP)
  1252. .add(predOps(ARMCC::AL));
  1253. for (auto R : {ARM::VPR, ARM::FPSCR, ARM::FPSCR_NZCV, ARM::Q0, ARM::Q1,
  1254. ARM::Q2, ARM::Q3, ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7})
  1255. VLSTM.addReg(R, RegState::Implicit |
  1256. (LiveRegs.contains(R) ? 0 : RegState::Undef));
  1257. // Restore all arguments
  1258. for (const auto &Regs : ClearedFPRegs) {
  1259. unsigned Reg, SaveReg1, SaveReg2;
  1260. std::tie(Reg, SaveReg1, SaveReg2) = Regs;
  1261. if (ARM::DPR_VFP2RegClass.contains(Reg))
  1262. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVDRR), Reg)
  1263. .addReg(SaveReg1)
  1264. .addReg(SaveReg2)
  1265. .add(predOps(ARMCC::AL));
  1266. else if (ARM::SPRRegClass.contains(Reg))
  1267. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVSR), Reg)
  1268. .addReg(SaveReg1)
  1269. .add(predOps(ARMCC::AL));
  1270. }
  1271. for (unsigned Reg : NonclearedFPRegs) {
  1272. if (ARM::DPR_VFP2RegClass.contains(Reg)) {
  1273. if (STI->isLittle()) {
  1274. BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRD), Reg)
  1275. .addReg(ARM::SP)
  1276. .addImm((Reg - ARM::D0) * 2)
  1277. .add(predOps(ARMCC::AL));
  1278. } else {
  1279. // For big-endian targets we need to load the two subregisters of Reg
  1280. // manually because VLDRD would load them in wrong order
  1281. unsigned SReg0 = TRI->getSubReg(Reg, ARM::ssub_0);
  1282. BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRS), SReg0)
  1283. .addReg(ARM::SP)
  1284. .addImm((Reg - ARM::D0) * 2)
  1285. .add(predOps(ARMCC::AL));
  1286. BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRS), SReg0 + 1)
  1287. .addReg(ARM::SP)
  1288. .addImm((Reg - ARM::D0) * 2 + 1)
  1289. .add(predOps(ARMCC::AL));
  1290. }
  1291. } else if (ARM::SPRRegClass.contains(Reg)) {
  1292. BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRS), Reg)
  1293. .addReg(ARM::SP)
  1294. .addImm(Reg - ARM::S0)
  1295. .add(predOps(ARMCC::AL));
  1296. }
  1297. }
  1298. // restore FPSCR from stack and clear bits 0-4, 7, 28-31
  1299. // The other bits are program global according to the AAPCS
  1300. if (passesFPReg) {
  1301. BuildMI(MBB, MBBI, DL, TII->get(ARM::tLDRspi), SpareReg)
  1302. .addReg(ARM::SP)
  1303. .addImm(0x10)
  1304. .add(predOps(ARMCC::AL));
  1305. BuildMI(MBB, MBBI, DL, TII->get(ARM::t2BICri), SpareReg)
  1306. .addReg(SpareReg)
  1307. .addImm(0x0000009F)
  1308. .add(predOps(ARMCC::AL))
  1309. .add(condCodeOp());
  1310. BuildMI(MBB, MBBI, DL, TII->get(ARM::t2BICri), SpareReg)
  1311. .addReg(SpareReg)
  1312. .addImm(0xF0000000)
  1313. .add(predOps(ARMCC::AL))
  1314. .add(condCodeOp());
  1315. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMSR))
  1316. .addReg(SpareReg)
  1317. .add(predOps(ARMCC::AL));
  1318. // The ldr must happen after a floating point instruction. To prevent the
  1319. // post-ra scheduler to mess with the order, we create a bundle.
  1320. finalizeBundle(MBB, VLSTM->getIterator(), MBBI->getIterator());
  1321. }
  1322. }
  1323. void ARMExpandPseudo::CMSESaveClearFPRegsV81(MachineBasicBlock &MBB,
  1324. MachineBasicBlock::iterator MBBI,
  1325. DebugLoc &DL,
  1326. const LivePhysRegs &LiveRegs) {
  1327. BitVector ClearRegs(32, true);
  1328. bool DefFP = determineFPRegsToClear(*MBBI, ClearRegs);
  1329. // If the instruction does not write to a FP register and no elements were
  1330. // removed from the set, then no FP registers were used to pass
  1331. // arguments/returns.
  1332. if (!DefFP && ClearRegs.count() == ClearRegs.size()) {
  1333. // save space on stack for VLSTM
  1334. BuildMI(MBB, MBBI, DL, TII->get(ARM::tSUBspi), ARM::SP)
  1335. .addReg(ARM::SP)
  1336. .addImm(CMSE_FP_SAVE_SIZE >> 2)
  1337. .add(predOps(ARMCC::AL));
  1338. // Lazy store all FP registers to the stack
  1339. MachineInstrBuilder VLSTM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLSTM))
  1340. .addReg(ARM::SP)
  1341. .add(predOps(ARMCC::AL));
  1342. for (auto R : {ARM::VPR, ARM::FPSCR, ARM::FPSCR_NZCV, ARM::Q0, ARM::Q1,
  1343. ARM::Q2, ARM::Q3, ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7})
  1344. VLSTM.addReg(R, RegState::Implicit |
  1345. (LiveRegs.contains(R) ? 0 : RegState::Undef));
  1346. } else {
  1347. // Push all the callee-saved registers (s16-s31).
  1348. MachineInstrBuilder VPUSH =
  1349. BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTMSDB_UPD), ARM::SP)
  1350. .addReg(ARM::SP)
  1351. .add(predOps(ARMCC::AL));
  1352. for (int Reg = ARM::S16; Reg <= ARM::S31; ++Reg)
  1353. VPUSH.addReg(Reg);
  1354. // Clear FP registers with a VSCCLRM.
  1355. (void)CMSEClearFPRegsV81(MBB, MBBI, ClearRegs);
  1356. // Save floating-point context.
  1357. BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTR_FPCXTS_pre), ARM::SP)
  1358. .addReg(ARM::SP)
  1359. .addImm(-8)
  1360. .add(predOps(ARMCC::AL));
  1361. }
  1362. }
  1363. // Restore FP registers if present
  1364. void ARMExpandPseudo::CMSERestoreFPRegs(
  1365. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  1366. SmallVectorImpl<unsigned> &AvailableRegs) {
  1367. if (STI->hasV8_1MMainlineOps())
  1368. CMSERestoreFPRegsV81(MBB, MBBI, DL, AvailableRegs);
  1369. else if (STI->hasV8MMainlineOps())
  1370. CMSERestoreFPRegsV8(MBB, MBBI, DL, AvailableRegs);
  1371. }
  1372. void ARMExpandPseudo::CMSERestoreFPRegsV8(
  1373. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  1374. SmallVectorImpl<unsigned> &AvailableRegs) {
  1375. // Keep a scratch register for the mitigation sequence.
  1376. unsigned ScratchReg = ARM::NoRegister;
  1377. if (STI->fixCMSE_CVE_2021_35465())
  1378. ScratchReg = AvailableRegs.pop_back_val();
  1379. // Use AvailableRegs to store the fp regs
  1380. std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
  1381. std::vector<unsigned> NonclearedFPRegs;
  1382. for (const MachineOperand &Op : MBBI->operands()) {
  1383. if (Op.isReg() && Op.isDef()) {
  1384. Register Reg = Op.getReg();
  1385. assert(!ARM::DPRRegClass.contains(Reg) ||
  1386. ARM::DPR_VFP2RegClass.contains(Reg));
  1387. assert(!ARM::QPRRegClass.contains(Reg));
  1388. if (ARM::DPR_VFP2RegClass.contains(Reg)) {
  1389. if (AvailableRegs.size() >= 2) {
  1390. unsigned SaveReg2 = AvailableRegs.pop_back_val();
  1391. unsigned SaveReg1 = AvailableRegs.pop_back_val();
  1392. ClearedFPRegs.emplace_back(Reg, SaveReg1, SaveReg2);
  1393. // Save the fp register to the normal registers
  1394. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRRD))
  1395. .addReg(SaveReg1, RegState::Define)
  1396. .addReg(SaveReg2, RegState::Define)
  1397. .addReg(Reg)
  1398. .add(predOps(ARMCC::AL));
  1399. } else {
  1400. NonclearedFPRegs.push_back(Reg);
  1401. }
  1402. } else if (ARM::SPRRegClass.contains(Reg)) {
  1403. if (AvailableRegs.size() >= 1) {
  1404. unsigned SaveReg = AvailableRegs.pop_back_val();
  1405. ClearedFPRegs.emplace_back(Reg, SaveReg, 0);
  1406. // Save the fp register to the normal registers
  1407. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRS), SaveReg)
  1408. .addReg(Reg)
  1409. .add(predOps(ARMCC::AL));
  1410. } else {
  1411. NonclearedFPRegs.push_back(Reg);
  1412. }
  1413. }
  1414. }
  1415. }
  1416. bool returnsFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
  1417. if (returnsFPReg)
  1418. assert(STI->hasFPRegs() && "Subtarget needs fpregs");
  1419. // Push FP regs that cannot be restored via normal registers on the stack
  1420. for (unsigned Reg : NonclearedFPRegs) {
  1421. if (ARM::DPR_VFP2RegClass.contains(Reg))
  1422. BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTRD))
  1423. .addReg(Reg)
  1424. .addReg(ARM::SP)
  1425. .addImm((Reg - ARM::D0) * 2)
  1426. .add(predOps(ARMCC::AL));
  1427. else if (ARM::SPRRegClass.contains(Reg))
  1428. BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTRS))
  1429. .addReg(Reg)
  1430. .addReg(ARM::SP)
  1431. .addImm(Reg - ARM::S0)
  1432. .add(predOps(ARMCC::AL));
  1433. }
  1434. // Lazy load fp regs from stack.
  1435. // This executes as NOP in the absence of floating-point support.
  1436. MachineInstrBuilder VLLDM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
  1437. .addReg(ARM::SP)
  1438. .add(predOps(ARMCC::AL));
  1439. if (STI->fixCMSE_CVE_2021_35465()) {
  1440. auto Bundler = MIBundleBuilder(MBB, VLLDM);
  1441. // Read the CONTROL register.
  1442. Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2MRS_M))
  1443. .addReg(ScratchReg, RegState::Define)
  1444. .addImm(20)
  1445. .add(predOps(ARMCC::AL)));
  1446. // Check bit 3 (SFPA).
  1447. Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2TSTri))
  1448. .addReg(ScratchReg)
  1449. .addImm(8)
  1450. .add(predOps(ARMCC::AL)));
  1451. // Emit the IT block.
  1452. Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2IT))
  1453. .addImm(ARMCC::NE)
  1454. .addImm(8));
  1455. // If SFPA is clear jump over to VLLDM, otherwise execute an instruction
  1456. // which has no functional effect apart from causing context creation:
  1457. // vmovne s0, s0. In the absence of FPU we emit .inst.w 0xeeb00a40,
  1458. // which is defined as NOP if not executed.
  1459. if (STI->hasFPRegs())
  1460. Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::VMOVS))
  1461. .addReg(ARM::S0, RegState::Define)
  1462. .addReg(ARM::S0, RegState::Undef)
  1463. .add(predOps(ARMCC::NE)));
  1464. else
  1465. Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::INLINEASM))
  1466. .addExternalSymbol(".inst.w 0xeeb00a40")
  1467. .addImm(InlineAsm::Extra_HasSideEffects));
  1468. finalizeBundle(MBB, Bundler.begin(), Bundler.end());
  1469. }
  1470. // Restore all FP registers via normal registers
  1471. for (const auto &Regs : ClearedFPRegs) {
  1472. unsigned Reg, SaveReg1, SaveReg2;
  1473. std::tie(Reg, SaveReg1, SaveReg2) = Regs;
  1474. if (ARM::DPR_VFP2RegClass.contains(Reg))
  1475. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVDRR), Reg)
  1476. .addReg(SaveReg1)
  1477. .addReg(SaveReg2)
  1478. .add(predOps(ARMCC::AL));
  1479. else if (ARM::SPRRegClass.contains(Reg))
  1480. BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVSR), Reg)
  1481. .addReg(SaveReg1)
  1482. .add(predOps(ARMCC::AL));
  1483. }
  1484. // Pop the stack space
  1485. BuildMI(MBB, MBBI, DL, TII->get(ARM::tADDspi), ARM::SP)
  1486. .addReg(ARM::SP)
  1487. .addImm(CMSE_FP_SAVE_SIZE >> 2)
  1488. .add(predOps(ARMCC::AL));
  1489. }
  1490. static bool definesOrUsesFPReg(const MachineInstr &MI) {
  1491. for (const MachineOperand &Op : MI.operands()) {
  1492. if (!Op.isReg())
  1493. continue;
  1494. Register Reg = Op.getReg();
  1495. if ((Reg >= ARM::Q0 && Reg <= ARM::Q7) ||
  1496. (Reg >= ARM::D0 && Reg <= ARM::D15) ||
  1497. (Reg >= ARM::S0 && Reg <= ARM::S31))
  1498. return true;
  1499. }
  1500. return false;
  1501. }
  1502. void ARMExpandPseudo::CMSERestoreFPRegsV81(
  1503. MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc &DL,
  1504. SmallVectorImpl<unsigned> &AvailableRegs) {
  1505. if (!definesOrUsesFPReg(*MBBI)) {
  1506. if (STI->fixCMSE_CVE_2021_35465()) {
  1507. BuildMI(MBB, MBBI, DL, TII->get(ARM::VSCCLRMS))
  1508. .add(predOps(ARMCC::AL))
  1509. .addReg(ARM::VPR, RegState::Define);
  1510. }
  1511. // Load FP registers from stack.
  1512. BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
  1513. .addReg(ARM::SP)
  1514. .add(predOps(ARMCC::AL));
  1515. // Pop the stack space
  1516. BuildMI(MBB, MBBI, DL, TII->get(ARM::tADDspi), ARM::SP)
  1517. .addReg(ARM::SP)
  1518. .addImm(CMSE_FP_SAVE_SIZE >> 2)
  1519. .add(predOps(ARMCC::AL));
  1520. } else {
  1521. // Restore the floating point context.
  1522. BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(ARM::VLDR_FPCXTS_post),
  1523. ARM::SP)
  1524. .addReg(ARM::SP)
  1525. .addImm(8)
  1526. .add(predOps(ARMCC::AL));
  1527. // Pop all the callee-saved registers (s16-s31).
  1528. MachineInstrBuilder VPOP =
  1529. BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDMSIA_UPD), ARM::SP)
  1530. .addReg(ARM::SP)
  1531. .add(predOps(ARMCC::AL));
  1532. for (int Reg = ARM::S16; Reg <= ARM::S31; ++Reg)
  1533. VPOP.addReg(Reg, RegState::Define);
  1534. }
  1535. }
  1536. /// Expand a CMP_SWAP pseudo-inst to an ldrex/strex loop as simply as
  1537. /// possible. This only gets used at -O0 so we don't care about efficiency of
  1538. /// the generated code.
  1539. bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
  1540. MachineBasicBlock::iterator MBBI,
  1541. unsigned LdrexOp, unsigned StrexOp,
  1542. unsigned UxtOp,
  1543. MachineBasicBlock::iterator &NextMBBI) {
  1544. bool IsThumb = STI->isThumb();
  1545. MachineInstr &MI = *MBBI;
  1546. DebugLoc DL = MI.getDebugLoc();
  1547. const MachineOperand &Dest = MI.getOperand(0);
  1548. Register TempReg = MI.getOperand(1).getReg();
  1549. // Duplicating undef operands into 2 instructions does not guarantee the same
  1550. // value on both; However undef should be replaced by xzr anyway.
  1551. assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
  1552. Register AddrReg = MI.getOperand(2).getReg();
  1553. Register DesiredReg = MI.getOperand(3).getReg();
  1554. Register NewReg = MI.getOperand(4).getReg();
  1555. if (IsThumb) {
  1556. assert(STI->hasV8MBaselineOps() &&
  1557. "CMP_SWAP not expected to be custom expanded for Thumb1");
  1558. assert((UxtOp == 0 || UxtOp == ARM::tUXTB || UxtOp == ARM::tUXTH) &&
  1559. "ARMv8-M.baseline does not have t2UXTB/t2UXTH");
  1560. assert((UxtOp == 0 || ARM::tGPRRegClass.contains(DesiredReg)) &&
  1561. "DesiredReg used for UXT op must be tGPR");
  1562. }
  1563. MachineFunction *MF = MBB.getParent();
  1564. auto LoadCmpBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1565. auto StoreBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1566. auto DoneBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1567. MF->insert(++MBB.getIterator(), LoadCmpBB);
  1568. MF->insert(++LoadCmpBB->getIterator(), StoreBB);
  1569. MF->insert(++StoreBB->getIterator(), DoneBB);
  1570. if (UxtOp) {
  1571. MachineInstrBuilder MIB =
  1572. BuildMI(MBB, MBBI, DL, TII->get(UxtOp), DesiredReg)
  1573. .addReg(DesiredReg, RegState::Kill);
  1574. if (!IsThumb)
  1575. MIB.addImm(0);
  1576. MIB.add(predOps(ARMCC::AL));
  1577. }
  1578. // .Lloadcmp:
  1579. // ldrex rDest, [rAddr]
  1580. // cmp rDest, rDesired
  1581. // bne .Ldone
  1582. MachineInstrBuilder MIB;
  1583. MIB = BuildMI(LoadCmpBB, DL, TII->get(LdrexOp), Dest.getReg());
  1584. MIB.addReg(AddrReg);
  1585. if (LdrexOp == ARM::t2LDREX)
  1586. MIB.addImm(0); // a 32-bit Thumb ldrex (only) allows an offset.
  1587. MIB.add(predOps(ARMCC::AL));
  1588. unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
  1589. BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
  1590. .addReg(Dest.getReg(), getKillRegState(Dest.isDead()))
  1591. .addReg(DesiredReg)
  1592. .add(predOps(ARMCC::AL));
  1593. unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
  1594. BuildMI(LoadCmpBB, DL, TII->get(Bcc))
  1595. .addMBB(DoneBB)
  1596. .addImm(ARMCC::NE)
  1597. .addReg(ARM::CPSR, RegState::Kill);
  1598. LoadCmpBB->addSuccessor(DoneBB);
  1599. LoadCmpBB->addSuccessor(StoreBB);
  1600. // .Lstore:
  1601. // strex rTempReg, rNew, [rAddr]
  1602. // cmp rTempReg, #0
  1603. // bne .Lloadcmp
  1604. MIB = BuildMI(StoreBB, DL, TII->get(StrexOp), TempReg)
  1605. .addReg(NewReg)
  1606. .addReg(AddrReg);
  1607. if (StrexOp == ARM::t2STREX)
  1608. MIB.addImm(0); // a 32-bit Thumb strex (only) allows an offset.
  1609. MIB.add(predOps(ARMCC::AL));
  1610. unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
  1611. BuildMI(StoreBB, DL, TII->get(CMPri))
  1612. .addReg(TempReg, RegState::Kill)
  1613. .addImm(0)
  1614. .add(predOps(ARMCC::AL));
  1615. BuildMI(StoreBB, DL, TII->get(Bcc))
  1616. .addMBB(LoadCmpBB)
  1617. .addImm(ARMCC::NE)
  1618. .addReg(ARM::CPSR, RegState::Kill);
  1619. StoreBB->addSuccessor(LoadCmpBB);
  1620. StoreBB->addSuccessor(DoneBB);
  1621. DoneBB->splice(DoneBB->end(), &MBB, MI, MBB.end());
  1622. DoneBB->transferSuccessors(&MBB);
  1623. MBB.addSuccessor(LoadCmpBB);
  1624. NextMBBI = MBB.end();
  1625. MI.eraseFromParent();
  1626. // Recompute livein lists.
  1627. LivePhysRegs LiveRegs;
  1628. computeAndAddLiveIns(LiveRegs, *DoneBB);
  1629. computeAndAddLiveIns(LiveRegs, *StoreBB);
  1630. computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
  1631. // Do an extra pass around the loop to get loop carried registers right.
  1632. StoreBB->clearLiveIns();
  1633. computeAndAddLiveIns(LiveRegs, *StoreBB);
  1634. LoadCmpBB->clearLiveIns();
  1635. computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
  1636. return true;
  1637. }
  1638. /// ARM's ldrexd/strexd take a consecutive register pair (represented as a
  1639. /// single GPRPair register), Thumb's take two separate registers so we need to
  1640. /// extract the subregs from the pair.
  1641. static void addExclusiveRegPair(MachineInstrBuilder &MIB, MachineOperand &Reg,
  1642. unsigned Flags, bool IsThumb,
  1643. const TargetRegisterInfo *TRI) {
  1644. if (IsThumb) {
  1645. Register RegLo = TRI->getSubReg(Reg.getReg(), ARM::gsub_0);
  1646. Register RegHi = TRI->getSubReg(Reg.getReg(), ARM::gsub_1);
  1647. MIB.addReg(RegLo, Flags);
  1648. MIB.addReg(RegHi, Flags);
  1649. } else
  1650. MIB.addReg(Reg.getReg(), Flags);
  1651. }
  1652. /// Expand a 64-bit CMP_SWAP to an ldrexd/strexd loop.
  1653. bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
  1654. MachineBasicBlock::iterator MBBI,
  1655. MachineBasicBlock::iterator &NextMBBI) {
  1656. bool IsThumb = STI->isThumb();
  1657. MachineInstr &MI = *MBBI;
  1658. DebugLoc DL = MI.getDebugLoc();
  1659. MachineOperand &Dest = MI.getOperand(0);
  1660. Register TempReg = MI.getOperand(1).getReg();
  1661. // Duplicating undef operands into 2 instructions does not guarantee the same
  1662. // value on both; However undef should be replaced by xzr anyway.
  1663. assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
  1664. Register AddrReg = MI.getOperand(2).getReg();
  1665. Register DesiredReg = MI.getOperand(3).getReg();
  1666. MachineOperand New = MI.getOperand(4);
  1667. New.setIsKill(false);
  1668. Register DestLo = TRI->getSubReg(Dest.getReg(), ARM::gsub_0);
  1669. Register DestHi = TRI->getSubReg(Dest.getReg(), ARM::gsub_1);
  1670. Register DesiredLo = TRI->getSubReg(DesiredReg, ARM::gsub_0);
  1671. Register DesiredHi = TRI->getSubReg(DesiredReg, ARM::gsub_1);
  1672. MachineFunction *MF = MBB.getParent();
  1673. auto LoadCmpBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1674. auto StoreBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1675. auto DoneBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
  1676. MF->insert(++MBB.getIterator(), LoadCmpBB);
  1677. MF->insert(++LoadCmpBB->getIterator(), StoreBB);
  1678. MF->insert(++StoreBB->getIterator(), DoneBB);
  1679. // .Lloadcmp:
  1680. // ldrexd rDestLo, rDestHi, [rAddr]
  1681. // cmp rDestLo, rDesiredLo
  1682. // sbcs dead rTempReg, rDestHi, rDesiredHi
  1683. // bne .Ldone
  1684. unsigned LDREXD = IsThumb ? ARM::t2LDREXD : ARM::LDREXD;
  1685. MachineInstrBuilder MIB;
  1686. MIB = BuildMI(LoadCmpBB, DL, TII->get(LDREXD));
  1687. addExclusiveRegPair(MIB, Dest, RegState::Define, IsThumb, TRI);
  1688. MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
  1689. unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
  1690. BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
  1691. .addReg(DestLo, getKillRegState(Dest.isDead()))
  1692. .addReg(DesiredLo)
  1693. .add(predOps(ARMCC::AL));
  1694. BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
  1695. .addReg(DestHi, getKillRegState(Dest.isDead()))
  1696. .addReg(DesiredHi)
  1697. .addImm(ARMCC::EQ).addReg(ARM::CPSR, RegState::Kill);
  1698. unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
  1699. BuildMI(LoadCmpBB, DL, TII->get(Bcc))
  1700. .addMBB(DoneBB)
  1701. .addImm(ARMCC::NE)
  1702. .addReg(ARM::CPSR, RegState::Kill);
  1703. LoadCmpBB->addSuccessor(DoneBB);
  1704. LoadCmpBB->addSuccessor(StoreBB);
  1705. // .Lstore:
  1706. // strexd rTempReg, rNewLo, rNewHi, [rAddr]
  1707. // cmp rTempReg, #0
  1708. // bne .Lloadcmp
  1709. unsigned STREXD = IsThumb ? ARM::t2STREXD : ARM::STREXD;
  1710. MIB = BuildMI(StoreBB, DL, TII->get(STREXD), TempReg);
  1711. unsigned Flags = getKillRegState(New.isDead());
  1712. addExclusiveRegPair(MIB, New, Flags, IsThumb, TRI);
  1713. MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
  1714. unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
  1715. BuildMI(StoreBB, DL, TII->get(CMPri))
  1716. .addReg(TempReg, RegState::Kill)
  1717. .addImm(0)
  1718. .add(predOps(ARMCC::AL));
  1719. BuildMI(StoreBB, DL, TII->get(Bcc))
  1720. .addMBB(LoadCmpBB)
  1721. .addImm(ARMCC::NE)
  1722. .addReg(ARM::CPSR, RegState::Kill);
  1723. StoreBB->addSuccessor(LoadCmpBB);
  1724. StoreBB->addSuccessor(DoneBB);
  1725. DoneBB->splice(DoneBB->end(), &MBB, MI, MBB.end());
  1726. DoneBB->transferSuccessors(&MBB);
  1727. MBB.addSuccessor(LoadCmpBB);
  1728. NextMBBI = MBB.end();
  1729. MI.eraseFromParent();
  1730. // Recompute livein lists.
  1731. LivePhysRegs LiveRegs;
  1732. computeAndAddLiveIns(LiveRegs, *DoneBB);
  1733. computeAndAddLiveIns(LiveRegs, *StoreBB);
  1734. computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
  1735. // Do an extra pass around the loop to get loop carried registers right.
  1736. StoreBB->clearLiveIns();
  1737. computeAndAddLiveIns(LiveRegs, *StoreBB);
  1738. LoadCmpBB->clearLiveIns();
  1739. computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
  1740. return true;
  1741. }
  1742. static void CMSEPushCalleeSaves(const TargetInstrInfo &TII,
  1743. MachineBasicBlock &MBB,
  1744. MachineBasicBlock::iterator MBBI, int JumpReg,
  1745. const LivePhysRegs &LiveRegs, bool Thumb1Only) {
  1746. const DebugLoc &DL = MBBI->getDebugLoc();
  1747. if (Thumb1Only) { // push Lo and Hi regs separately
  1748. MachineInstrBuilder PushMIB =
  1749. BuildMI(MBB, MBBI, DL, TII.get(ARM::tPUSH)).add(predOps(ARMCC::AL));
  1750. for (int Reg = ARM::R4; Reg < ARM::R8; ++Reg) {
  1751. PushMIB.addReg(
  1752. Reg, Reg == JumpReg || LiveRegs.contains(Reg) ? 0 : RegState::Undef);
  1753. }
  1754. // Thumb1 can only tPUSH low regs, so we copy the high regs to the low
  1755. // regs that we just saved and push the low regs again, taking care to
  1756. // not clobber JumpReg. If JumpReg is one of the low registers, push first
  1757. // the values of r9-r11, and then r8. That would leave them ordered in
  1758. // memory, and allow us to later pop them with a single instructions.
  1759. // FIXME: Could also use any of r0-r3 that are free (including in the
  1760. // first PUSH above).
  1761. for (int LoReg = ARM::R7, HiReg = ARM::R11; LoReg >= ARM::R4; --LoReg) {
  1762. if (JumpReg == LoReg)
  1763. continue;
  1764. BuildMI(MBB, MBBI, DL, TII.get(ARM::tMOVr), LoReg)
  1765. .addReg(HiReg, LiveRegs.contains(HiReg) ? 0 : RegState::Undef)
  1766. .add(predOps(ARMCC::AL));
  1767. --HiReg;
  1768. }
  1769. MachineInstrBuilder PushMIB2 =
  1770. BuildMI(MBB, MBBI, DL, TII.get(ARM::tPUSH)).add(predOps(ARMCC::AL));
  1771. for (int Reg = ARM::R4; Reg < ARM::R8; ++Reg) {
  1772. if (Reg == JumpReg)
  1773. continue;
  1774. PushMIB2.addReg(Reg, RegState::Kill);
  1775. }
  1776. // If we couldn't use a low register for temporary storage (because it was
  1777. // the JumpReg), use r4 or r5, whichever is not JumpReg. It has already been
  1778. // saved.
  1779. if (JumpReg >= ARM::R4 && JumpReg <= ARM::R7) {
  1780. int LoReg = JumpReg == ARM::R4 ? ARM::R5 : ARM::R4;
  1781. BuildMI(MBB, MBBI, DL, TII.get(ARM::tMOVr), LoReg)
  1782. .addReg(ARM::R8, LiveRegs.contains(ARM::R8) ? 0 : RegState::Undef)
  1783. .add(predOps(ARMCC::AL));
  1784. BuildMI(MBB, MBBI, DL, TII.get(ARM::tPUSH))
  1785. .add(predOps(ARMCC::AL))
  1786. .addReg(LoReg, RegState::Kill);
  1787. }
  1788. } else { // push Lo and Hi registers with a single instruction
  1789. MachineInstrBuilder PushMIB =
  1790. BuildMI(MBB, MBBI, DL, TII.get(ARM::t2STMDB_UPD), ARM::SP)
  1791. .addReg(ARM::SP)
  1792. .add(predOps(ARMCC::AL));
  1793. for (int Reg = ARM::R4; Reg < ARM::R12; ++Reg) {
  1794. PushMIB.addReg(
  1795. Reg, Reg == JumpReg || LiveRegs.contains(Reg) ? 0 : RegState::Undef);
  1796. }
  1797. }
  1798. }
  1799. static void CMSEPopCalleeSaves(const TargetInstrInfo &TII,
  1800. MachineBasicBlock &MBB,
  1801. MachineBasicBlock::iterator MBBI, int JumpReg,
  1802. bool Thumb1Only) {
  1803. const DebugLoc &DL = MBBI->getDebugLoc();
  1804. if (Thumb1Only) {
  1805. MachineInstrBuilder PopMIB =
  1806. BuildMI(MBB, MBBI, DL, TII.get(ARM::tPOP)).add(predOps(ARMCC::AL));
  1807. for (int R = 0; R < 4; ++R) {
  1808. PopMIB.addReg(ARM::R4 + R, RegState::Define);
  1809. BuildMI(MBB, MBBI, DL, TII.get(ARM::tMOVr), ARM::R8 + R)
  1810. .addReg(ARM::R4 + R, RegState::Kill)
  1811. .add(predOps(ARMCC::AL));
  1812. }
  1813. MachineInstrBuilder PopMIB2 =
  1814. BuildMI(MBB, MBBI, DL, TII.get(ARM::tPOP)).add(predOps(ARMCC::AL));
  1815. for (int R = 0; R < 4; ++R)
  1816. PopMIB2.addReg(ARM::R4 + R, RegState::Define);
  1817. } else { // pop Lo and Hi registers with a single instruction
  1818. MachineInstrBuilder PopMIB =
  1819. BuildMI(MBB, MBBI, DL, TII.get(ARM::t2LDMIA_UPD), ARM::SP)
  1820. .addReg(ARM::SP)
  1821. .add(predOps(ARMCC::AL));
  1822. for (int Reg = ARM::R4; Reg < ARM::R12; ++Reg)
  1823. PopMIB.addReg(Reg, RegState::Define);
  1824. }
  1825. }
  1826. bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
  1827. MachineBasicBlock::iterator MBBI,
  1828. MachineBasicBlock::iterator &NextMBBI) {
  1829. MachineInstr &MI = *MBBI;
  1830. unsigned Opcode = MI.getOpcode();
  1831. switch (Opcode) {
  1832. default:
  1833. return false;
  1834. case ARM::VBSPd:
  1835. case ARM::VBSPq: {
  1836. Register DstReg = MI.getOperand(0).getReg();
  1837. if (DstReg == MI.getOperand(3).getReg()) {
  1838. // Expand to VBIT
  1839. unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBITd : ARM::VBITq;
  1840. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
  1841. .add(MI.getOperand(0))
  1842. .add(MI.getOperand(3))
  1843. .add(MI.getOperand(2))
  1844. .add(MI.getOperand(1))
  1845. .addImm(MI.getOperand(4).getImm())
  1846. .add(MI.getOperand(5));
  1847. } else if (DstReg == MI.getOperand(2).getReg()) {
  1848. // Expand to VBIF
  1849. unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBIFd : ARM::VBIFq;
  1850. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
  1851. .add(MI.getOperand(0))
  1852. .add(MI.getOperand(2))
  1853. .add(MI.getOperand(3))
  1854. .add(MI.getOperand(1))
  1855. .addImm(MI.getOperand(4).getImm())
  1856. .add(MI.getOperand(5));
  1857. } else {
  1858. // Expand to VBSL
  1859. unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBSLd : ARM::VBSLq;
  1860. if (DstReg == MI.getOperand(1).getReg()) {
  1861. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
  1862. .add(MI.getOperand(0))
  1863. .add(MI.getOperand(1))
  1864. .add(MI.getOperand(2))
  1865. .add(MI.getOperand(3))
  1866. .addImm(MI.getOperand(4).getImm())
  1867. .add(MI.getOperand(5));
  1868. } else {
  1869. // Use move to satisfy constraints
  1870. unsigned MoveOpc = Opcode == ARM::VBSPd ? ARM::VORRd : ARM::VORRq;
  1871. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(MoveOpc))
  1872. .addReg(DstReg,
  1873. RegState::Define |
  1874. getRenamableRegState(MI.getOperand(0).isRenamable()))
  1875. .add(MI.getOperand(1))
  1876. .add(MI.getOperand(1))
  1877. .addImm(MI.getOperand(4).getImm())
  1878. .add(MI.getOperand(5));
  1879. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
  1880. .add(MI.getOperand(0))
  1881. .addReg(DstReg,
  1882. RegState::Kill |
  1883. getRenamableRegState(MI.getOperand(0).isRenamable()))
  1884. .add(MI.getOperand(2))
  1885. .add(MI.getOperand(3))
  1886. .addImm(MI.getOperand(4).getImm())
  1887. .add(MI.getOperand(5));
  1888. }
  1889. }
  1890. MI.eraseFromParent();
  1891. return true;
  1892. }
  1893. case ARM::TCRETURNdi:
  1894. case ARM::TCRETURNri: {
  1895. MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
  1896. assert(MBBI->isReturn() &&
  1897. "Can only insert epilog into returning blocks");
  1898. unsigned RetOpcode = MBBI->getOpcode();
  1899. DebugLoc dl = MBBI->getDebugLoc();
  1900. const ARMBaseInstrInfo &TII = *static_cast<const ARMBaseInstrInfo *>(
  1901. MBB.getParent()->getSubtarget().getInstrInfo());
  1902. // Tail call return: adjust the stack pointer and jump to callee.
  1903. MBBI = MBB.getLastNonDebugInstr();
  1904. MachineOperand &JumpTarget = MBBI->getOperand(0);
  1905. // Jump to label or value in register.
  1906. if (RetOpcode == ARM::TCRETURNdi) {
  1907. unsigned TCOpcode =
  1908. STI->isThumb()
  1909. ? (STI->isTargetMachO() ? ARM::tTAILJMPd : ARM::tTAILJMPdND)
  1910. : ARM::TAILJMPd;
  1911. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode));
  1912. if (JumpTarget.isGlobal())
  1913. MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
  1914. JumpTarget.getTargetFlags());
  1915. else {
  1916. assert(JumpTarget.isSymbol());
  1917. MIB.addExternalSymbol(JumpTarget.getSymbolName(),
  1918. JumpTarget.getTargetFlags());
  1919. }
  1920. // Add the default predicate in Thumb mode.
  1921. if (STI->isThumb())
  1922. MIB.add(predOps(ARMCC::AL));
  1923. } else if (RetOpcode == ARM::TCRETURNri) {
  1924. unsigned Opcode =
  1925. STI->isThumb() ? ARM::tTAILJMPr
  1926. : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4);
  1927. BuildMI(MBB, MBBI, dl,
  1928. TII.get(Opcode))
  1929. .addReg(JumpTarget.getReg(), RegState::Kill);
  1930. }
  1931. auto NewMI = std::prev(MBBI);
  1932. for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
  1933. NewMI->addOperand(MBBI->getOperand(i));
  1934. // Update call site info and delete the pseudo instruction TCRETURN.
  1935. if (MI.isCandidateForCallSiteEntry())
  1936. MI.getMF()->moveCallSiteInfo(&MI, &*NewMI);
  1937. MBB.erase(MBBI);
  1938. MBBI = NewMI;
  1939. return true;
  1940. }
  1941. case ARM::tBXNS_RET: {
  1942. // For v8.0-M.Main we need to authenticate LR before clearing FPRs, which
  1943. // uses R12 as a scratch register.
  1944. if (!STI->hasV8_1MMainlineOps() && AFI->shouldSignReturnAddress())
  1945. BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARM::t2AUT));
  1946. MachineBasicBlock &AfterBB = CMSEClearFPRegs(MBB, MBBI);
  1947. if (STI->hasV8_1MMainlineOps()) {
  1948. // Restore the non-secure floating point context.
  1949. BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
  1950. TII->get(ARM::VLDR_FPCXTNS_post), ARM::SP)
  1951. .addReg(ARM::SP)
  1952. .addImm(4)
  1953. .add(predOps(ARMCC::AL));
  1954. if (AFI->shouldSignReturnAddress())
  1955. BuildMI(AfterBB, AfterBB.end(), DebugLoc(), TII->get(ARM::t2AUT));
  1956. }
  1957. // Clear all GPR that are not a use of the return instruction.
  1958. assert(llvm::all_of(MBBI->operands(), [](const MachineOperand &Op) {
  1959. return !Op.isReg() || Op.getReg() != ARM::R12;
  1960. }));
  1961. SmallVector<unsigned, 5> ClearRegs;
  1962. determineGPRegsToClear(
  1963. *MBBI, {ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R12}, ClearRegs);
  1964. CMSEClearGPRegs(AfterBB, AfterBB.end(), MBBI->getDebugLoc(), ClearRegs,
  1965. ARM::LR);
  1966. MachineInstrBuilder NewMI =
  1967. BuildMI(AfterBB, AfterBB.end(), MBBI->getDebugLoc(),
  1968. TII->get(ARM::tBXNS))
  1969. .addReg(ARM::LR)
  1970. .add(predOps(ARMCC::AL));
  1971. for (const MachineOperand &Op : MI.operands())
  1972. NewMI->addOperand(Op);
  1973. MI.eraseFromParent();
  1974. return true;
  1975. }
  1976. case ARM::tBLXNS_CALL: {
  1977. DebugLoc DL = MBBI->getDebugLoc();
  1978. Register JumpReg = MBBI->getOperand(0).getReg();
  1979. // Figure out which registers are live at the point immediately before the
  1980. // call. When we indiscriminately push a set of registers, the live
  1981. // registers are added as ordinary use operands, whereas dead registers
  1982. // are "undef".
  1983. LivePhysRegs LiveRegs(*TRI);
  1984. LiveRegs.addLiveOuts(MBB);
  1985. for (const MachineInstr &MI : make_range(MBB.rbegin(), MBBI.getReverse()))
  1986. LiveRegs.stepBackward(MI);
  1987. LiveRegs.stepBackward(*MBBI);
  1988. CMSEPushCalleeSaves(*TII, MBB, MBBI, JumpReg, LiveRegs,
  1989. AFI->isThumb1OnlyFunction());
  1990. SmallVector<unsigned, 16> ClearRegs;
  1991. determineGPRegsToClear(*MBBI,
  1992. {ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R4,
  1993. ARM::R5, ARM::R6, ARM::R7, ARM::R8, ARM::R9,
  1994. ARM::R10, ARM::R11, ARM::R12},
  1995. ClearRegs);
  1996. auto OriginalClearRegs = ClearRegs;
  1997. // Get the first cleared register as a scratch (to use later with tBIC).
  1998. // We need to use the first so we can ensure it is a low register.
  1999. unsigned ScratchReg = ClearRegs.front();
  2000. // Clear LSB of JumpReg
  2001. if (AFI->isThumb2Function()) {
  2002. BuildMI(MBB, MBBI, DL, TII->get(ARM::t2BICri), JumpReg)
  2003. .addReg(JumpReg)
  2004. .addImm(1)
  2005. .add(predOps(ARMCC::AL))
  2006. .add(condCodeOp());
  2007. } else {
  2008. // We need to use an extra register to cope with 8M Baseline,
  2009. // since we have saved all of the registers we are ok to trash a non
  2010. // argument register here.
  2011. BuildMI(MBB, MBBI, DL, TII->get(ARM::tMOVi8), ScratchReg)
  2012. .add(condCodeOp())
  2013. .addImm(1)
  2014. .add(predOps(ARMCC::AL));
  2015. BuildMI(MBB, MBBI, DL, TII->get(ARM::tBIC), JumpReg)
  2016. .addReg(ARM::CPSR, RegState::Define)
  2017. .addReg(JumpReg)
  2018. .addReg(ScratchReg)
  2019. .add(predOps(ARMCC::AL));
  2020. }
  2021. CMSESaveClearFPRegs(MBB, MBBI, DL, LiveRegs,
  2022. ClearRegs); // save+clear FP regs with ClearRegs
  2023. CMSEClearGPRegs(MBB, MBBI, DL, ClearRegs, JumpReg);
  2024. const MachineInstrBuilder NewCall =
  2025. BuildMI(MBB, MBBI, DL, TII->get(ARM::tBLXNSr))
  2026. .add(predOps(ARMCC::AL))
  2027. .addReg(JumpReg, RegState::Kill);
  2028. for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
  2029. NewCall->addOperand(MO);
  2030. if (MI.isCandidateForCallSiteEntry())
  2031. MI.getMF()->moveCallSiteInfo(&MI, NewCall.getInstr());
  2032. CMSERestoreFPRegs(MBB, MBBI, DL, OriginalClearRegs); // restore FP registers
  2033. CMSEPopCalleeSaves(*TII, MBB, MBBI, JumpReg, AFI->isThumb1OnlyFunction());
  2034. MI.eraseFromParent();
  2035. return true;
  2036. }
  2037. case ARM::VMOVHcc:
  2038. case ARM::VMOVScc:
  2039. case ARM::VMOVDcc: {
  2040. unsigned newOpc = Opcode != ARM::VMOVDcc ? ARM::VMOVS : ARM::VMOVD;
  2041. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(newOpc),
  2042. MI.getOperand(1).getReg())
  2043. .add(MI.getOperand(2))
  2044. .addImm(MI.getOperand(3).getImm()) // 'pred'
  2045. .add(MI.getOperand(4))
  2046. .add(makeImplicit(MI.getOperand(1)));
  2047. MI.eraseFromParent();
  2048. return true;
  2049. }
  2050. case ARM::t2MOVCCr:
  2051. case ARM::MOVCCr: {
  2052. unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVr : ARM::MOVr;
  2053. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
  2054. MI.getOperand(1).getReg())
  2055. .add(MI.getOperand(2))
  2056. .addImm(MI.getOperand(3).getImm()) // 'pred'
  2057. .add(MI.getOperand(4))
  2058. .add(condCodeOp()) // 's' bit
  2059. .add(makeImplicit(MI.getOperand(1)));
  2060. MI.eraseFromParent();
  2061. return true;
  2062. }
  2063. case ARM::MOVCCsi: {
  2064. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
  2065. (MI.getOperand(1).getReg()))
  2066. .add(MI.getOperand(2))
  2067. .addImm(MI.getOperand(3).getImm())
  2068. .addImm(MI.getOperand(4).getImm()) // 'pred'
  2069. .add(MI.getOperand(5))
  2070. .add(condCodeOp()) // 's' bit
  2071. .add(makeImplicit(MI.getOperand(1)));
  2072. MI.eraseFromParent();
  2073. return true;
  2074. }
  2075. case ARM::MOVCCsr: {
  2076. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsr),
  2077. (MI.getOperand(1).getReg()))
  2078. .add(MI.getOperand(2))
  2079. .add(MI.getOperand(3))
  2080. .addImm(MI.getOperand(4).getImm())
  2081. .addImm(MI.getOperand(5).getImm()) // 'pred'
  2082. .add(MI.getOperand(6))
  2083. .add(condCodeOp()) // 's' bit
  2084. .add(makeImplicit(MI.getOperand(1)));
  2085. MI.eraseFromParent();
  2086. return true;
  2087. }
  2088. case ARM::t2MOVCCi16:
  2089. case ARM::MOVCCi16: {
  2090. unsigned NewOpc = AFI->isThumbFunction() ? ARM::t2MOVi16 : ARM::MOVi16;
  2091. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc),
  2092. MI.getOperand(1).getReg())
  2093. .addImm(MI.getOperand(2).getImm())
  2094. .addImm(MI.getOperand(3).getImm()) // 'pred'
  2095. .add(MI.getOperand(4))
  2096. .add(makeImplicit(MI.getOperand(1)));
  2097. MI.eraseFromParent();
  2098. return true;
  2099. }
  2100. case ARM::t2MOVCCi:
  2101. case ARM::MOVCCi: {
  2102. unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVi : ARM::MOVi;
  2103. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
  2104. MI.getOperand(1).getReg())
  2105. .addImm(MI.getOperand(2).getImm())
  2106. .addImm(MI.getOperand(3).getImm()) // 'pred'
  2107. .add(MI.getOperand(4))
  2108. .add(condCodeOp()) // 's' bit
  2109. .add(makeImplicit(MI.getOperand(1)));
  2110. MI.eraseFromParent();
  2111. return true;
  2112. }
  2113. case ARM::t2MVNCCi:
  2114. case ARM::MVNCCi: {
  2115. unsigned Opc = AFI->isThumbFunction() ? ARM::t2MVNi : ARM::MVNi;
  2116. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
  2117. MI.getOperand(1).getReg())
  2118. .addImm(MI.getOperand(2).getImm())
  2119. .addImm(MI.getOperand(3).getImm()) // 'pred'
  2120. .add(MI.getOperand(4))
  2121. .add(condCodeOp()) // 's' bit
  2122. .add(makeImplicit(MI.getOperand(1)));
  2123. MI.eraseFromParent();
  2124. return true;
  2125. }
  2126. case ARM::t2MOVCClsl:
  2127. case ARM::t2MOVCClsr:
  2128. case ARM::t2MOVCCasr:
  2129. case ARM::t2MOVCCror: {
  2130. unsigned NewOpc;
  2131. switch (Opcode) {
  2132. case ARM::t2MOVCClsl: NewOpc = ARM::t2LSLri; break;
  2133. case ARM::t2MOVCClsr: NewOpc = ARM::t2LSRri; break;
  2134. case ARM::t2MOVCCasr: NewOpc = ARM::t2ASRri; break;
  2135. case ARM::t2MOVCCror: NewOpc = ARM::t2RORri; break;
  2136. default: llvm_unreachable("unexpeced conditional move");
  2137. }
  2138. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc),
  2139. MI.getOperand(1).getReg())
  2140. .add(MI.getOperand(2))
  2141. .addImm(MI.getOperand(3).getImm())
  2142. .addImm(MI.getOperand(4).getImm()) // 'pred'
  2143. .add(MI.getOperand(5))
  2144. .add(condCodeOp()) // 's' bit
  2145. .add(makeImplicit(MI.getOperand(1)));
  2146. MI.eraseFromParent();
  2147. return true;
  2148. }
  2149. case ARM::Int_eh_sjlj_dispatchsetup: {
  2150. MachineFunction &MF = *MI.getParent()->getParent();
  2151. const ARMBaseInstrInfo *AII =
  2152. static_cast<const ARMBaseInstrInfo*>(TII);
  2153. const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
  2154. // For functions using a base pointer, we rematerialize it (via the frame
  2155. // pointer) here since eh.sjlj.setjmp and eh.sjlj.longjmp don't do it
  2156. // for us. Otherwise, expand to nothing.
  2157. if (RI.hasBasePointer(MF)) {
  2158. int32_t NumBytes = AFI->getFramePtrSpillOffset();
  2159. Register FramePtr = RI.getFrameRegister(MF);
  2160. assert(MF.getSubtarget().getFrameLowering()->hasFP(MF) &&
  2161. "base pointer without frame pointer?");
  2162. if (AFI->isThumb2Function()) {
  2163. emitT2RegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
  2164. FramePtr, -NumBytes, ARMCC::AL, 0, *TII);
  2165. } else if (AFI->isThumbFunction()) {
  2166. emitThumbRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
  2167. FramePtr, -NumBytes, *TII, RI);
  2168. } else {
  2169. emitARMRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
  2170. FramePtr, -NumBytes, ARMCC::AL, 0,
  2171. *TII);
  2172. }
  2173. // If there's dynamic realignment, adjust for it.
  2174. if (RI.hasStackRealignment(MF)) {
  2175. MachineFrameInfo &MFI = MF.getFrameInfo();
  2176. Align MaxAlign = MFI.getMaxAlign();
  2177. assert (!AFI->isThumb1OnlyFunction());
  2178. // Emit bic r6, r6, MaxAlign
  2179. assert(MaxAlign <= Align(256) &&
  2180. "The BIC instruction cannot encode "
  2181. "immediates larger than 256 with all lower "
  2182. "bits set.");
  2183. unsigned bicOpc = AFI->isThumbFunction() ?
  2184. ARM::t2BICri : ARM::BICri;
  2185. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(bicOpc), ARM::R6)
  2186. .addReg(ARM::R6, RegState::Kill)
  2187. .addImm(MaxAlign.value() - 1)
  2188. .add(predOps(ARMCC::AL))
  2189. .add(condCodeOp());
  2190. }
  2191. }
  2192. MI.eraseFromParent();
  2193. return true;
  2194. }
  2195. case ARM::MOVsrl_flag:
  2196. case ARM::MOVsra_flag: {
  2197. // These are just fancy MOVs instructions.
  2198. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
  2199. MI.getOperand(0).getReg())
  2200. .add(MI.getOperand(1))
  2201. .addImm(ARM_AM::getSORegOpc(
  2202. (Opcode == ARM::MOVsrl_flag ? ARM_AM::lsr : ARM_AM::asr), 1))
  2203. .add(predOps(ARMCC::AL))
  2204. .addReg(ARM::CPSR, RegState::Define);
  2205. MI.eraseFromParent();
  2206. return true;
  2207. }
  2208. case ARM::RRX: {
  2209. // This encodes as "MOVs Rd, Rm, rrx
  2210. MachineInstrBuilder MIB =
  2211. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
  2212. MI.getOperand(0).getReg())
  2213. .add(MI.getOperand(1))
  2214. .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0))
  2215. .add(predOps(ARMCC::AL))
  2216. .add(condCodeOp());
  2217. TransferImpOps(MI, MIB, MIB);
  2218. MI.eraseFromParent();
  2219. return true;
  2220. }
  2221. case ARM::tTPsoft:
  2222. case ARM::TPsoft: {
  2223. const bool Thumb = Opcode == ARM::tTPsoft;
  2224. MachineInstrBuilder MIB;
  2225. MachineFunction *MF = MBB.getParent();
  2226. if (STI->genLongCalls()) {
  2227. MachineConstantPool *MCP = MF->getConstantPool();
  2228. unsigned PCLabelID = AFI->createPICLabelUId();
  2229. MachineConstantPoolValue *CPV =
  2230. ARMConstantPoolSymbol::Create(MF->getFunction().getContext(),
  2231. "__aeabi_read_tp", PCLabelID, 0);
  2232. Register Reg = MI.getOperand(0).getReg();
  2233. MIB =
  2234. BuildMI(MBB, MBBI, MI.getDebugLoc(),
  2235. TII->get(Thumb ? ARM::tLDRpci : ARM::LDRi12), Reg)
  2236. .addConstantPoolIndex(MCP->getConstantPoolIndex(CPV, Align(4)));
  2237. if (!Thumb)
  2238. MIB.addImm(0);
  2239. MIB.add(predOps(ARMCC::AL));
  2240. MIB =
  2241. BuildMI(MBB, MBBI, MI.getDebugLoc(),
  2242. TII->get(Thumb ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF)));
  2243. if (Thumb)
  2244. MIB.add(predOps(ARMCC::AL));
  2245. MIB.addReg(Reg, RegState::Kill);
  2246. } else {
  2247. MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
  2248. TII->get(Thumb ? ARM::tBL : ARM::BL));
  2249. if (Thumb)
  2250. MIB.add(predOps(ARMCC::AL));
  2251. MIB.addExternalSymbol("__aeabi_read_tp", 0);
  2252. }
  2253. MIB.cloneMemRefs(MI);
  2254. TransferImpOps(MI, MIB, MIB);
  2255. // Update the call site info.
  2256. if (MI.isCandidateForCallSiteEntry())
  2257. MF->moveCallSiteInfo(&MI, &*MIB);
  2258. MI.eraseFromParent();
  2259. return true;
  2260. }
  2261. case ARM::tLDRpci_pic:
  2262. case ARM::t2LDRpci_pic: {
  2263. unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
  2264. ? ARM::tLDRpci : ARM::t2LDRpci;
  2265. Register DstReg = MI.getOperand(0).getReg();
  2266. bool DstIsDead = MI.getOperand(0).isDead();
  2267. MachineInstrBuilder MIB1 =
  2268. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewLdOpc), DstReg)
  2269. .add(MI.getOperand(1))
  2270. .add(predOps(ARMCC::AL));
  2271. MIB1.cloneMemRefs(MI);
  2272. MachineInstrBuilder MIB2 =
  2273. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPICADD))
  2274. .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
  2275. .addReg(DstReg)
  2276. .add(MI.getOperand(2));
  2277. TransferImpOps(MI, MIB1, MIB2);
  2278. MI.eraseFromParent();
  2279. return true;
  2280. }
  2281. case ARM::LDRLIT_ga_abs:
  2282. case ARM::LDRLIT_ga_pcrel:
  2283. case ARM::LDRLIT_ga_pcrel_ldr:
  2284. case ARM::tLDRLIT_ga_abs:
  2285. case ARM::t2LDRLIT_ga_pcrel:
  2286. case ARM::tLDRLIT_ga_pcrel: {
  2287. Register DstReg = MI.getOperand(0).getReg();
  2288. bool DstIsDead = MI.getOperand(0).isDead();
  2289. const MachineOperand &MO1 = MI.getOperand(1);
  2290. auto Flags = MO1.getTargetFlags();
  2291. const GlobalValue *GV = MO1.getGlobal();
  2292. bool IsARM = Opcode != ARM::tLDRLIT_ga_pcrel &&
  2293. Opcode != ARM::tLDRLIT_ga_abs &&
  2294. Opcode != ARM::t2LDRLIT_ga_pcrel;
  2295. bool IsPIC =
  2296. Opcode != ARM::LDRLIT_ga_abs && Opcode != ARM::tLDRLIT_ga_abs;
  2297. unsigned LDRLITOpc = IsARM ? ARM::LDRi12 : ARM::tLDRpci;
  2298. if (Opcode == ARM::t2LDRLIT_ga_pcrel)
  2299. LDRLITOpc = ARM::t2LDRpci;
  2300. unsigned PICAddOpc =
  2301. IsARM
  2302. ? (Opcode == ARM::LDRLIT_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
  2303. : ARM::tPICADD;
  2304. // We need a new const-pool entry to load from.
  2305. MachineConstantPool *MCP = MBB.getParent()->getConstantPool();
  2306. unsigned ARMPCLabelIndex = 0;
  2307. MachineConstantPoolValue *CPV;
  2308. if (IsPIC) {
  2309. unsigned PCAdj = IsARM ? 8 : 4;
  2310. auto Modifier = (Flags & ARMII::MO_GOT)
  2311. ? ARMCP::GOT_PREL
  2312. : ARMCP::no_modifier;
  2313. ARMPCLabelIndex = AFI->createPICLabelUId();
  2314. CPV = ARMConstantPoolConstant::Create(
  2315. GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, Modifier,
  2316. /*AddCurrentAddr*/ Modifier == ARMCP::GOT_PREL);
  2317. } else
  2318. CPV = ARMConstantPoolConstant::Create(GV, ARMCP::no_modifier);
  2319. MachineInstrBuilder MIB =
  2320. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LDRLITOpc), DstReg)
  2321. .addConstantPoolIndex(MCP->getConstantPoolIndex(CPV, Align(4)));
  2322. if (IsARM)
  2323. MIB.addImm(0);
  2324. MIB.add(predOps(ARMCC::AL));
  2325. if (IsPIC) {
  2326. MachineInstrBuilder MIB =
  2327. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(PICAddOpc))
  2328. .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
  2329. .addReg(DstReg)
  2330. .addImm(ARMPCLabelIndex);
  2331. if (IsARM)
  2332. MIB.add(predOps(ARMCC::AL));
  2333. }
  2334. MI.eraseFromParent();
  2335. return true;
  2336. }
  2337. case ARM::MOV_ga_pcrel:
  2338. case ARM::MOV_ga_pcrel_ldr:
  2339. case ARM::t2MOV_ga_pcrel: {
  2340. // Expand into movw + movw. Also "add pc" / ldr [pc] in PIC mode.
  2341. unsigned LabelId = AFI->createPICLabelUId();
  2342. Register DstReg = MI.getOperand(0).getReg();
  2343. bool DstIsDead = MI.getOperand(0).isDead();
  2344. const MachineOperand &MO1 = MI.getOperand(1);
  2345. const GlobalValue *GV = MO1.getGlobal();
  2346. unsigned TF = MO1.getTargetFlags();
  2347. bool isARM = Opcode != ARM::t2MOV_ga_pcrel;
  2348. unsigned LO16Opc = isARM ? ARM::MOVi16_ga_pcrel : ARM::t2MOVi16_ga_pcrel;
  2349. unsigned HI16Opc = isARM ? ARM::MOVTi16_ga_pcrel :ARM::t2MOVTi16_ga_pcrel;
  2350. unsigned LO16TF = TF | ARMII::MO_LO16;
  2351. unsigned HI16TF = TF | ARMII::MO_HI16;
  2352. unsigned PICAddOpc = isARM
  2353. ? (Opcode == ARM::MOV_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
  2354. : ARM::tPICADD;
  2355. MachineInstrBuilder MIB1 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
  2356. TII->get(LO16Opc), DstReg)
  2357. .addGlobalAddress(GV, MO1.getOffset(), TF | LO16TF)
  2358. .addImm(LabelId);
  2359. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc), DstReg)
  2360. .addReg(DstReg)
  2361. .addGlobalAddress(GV, MO1.getOffset(), TF | HI16TF)
  2362. .addImm(LabelId);
  2363. MachineInstrBuilder MIB3 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
  2364. TII->get(PICAddOpc))
  2365. .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
  2366. .addReg(DstReg).addImm(LabelId);
  2367. if (isARM) {
  2368. MIB3.add(predOps(ARMCC::AL));
  2369. if (Opcode == ARM::MOV_ga_pcrel_ldr)
  2370. MIB3.cloneMemRefs(MI);
  2371. }
  2372. TransferImpOps(MI, MIB1, MIB3);
  2373. MI.eraseFromParent();
  2374. return true;
  2375. }
  2376. case ARM::MOVi32imm:
  2377. case ARM::MOVCCi32imm:
  2378. case ARM::t2MOVi32imm:
  2379. case ARM::t2MOVCCi32imm:
  2380. ExpandMOV32BitImm(MBB, MBBI);
  2381. return true;
  2382. case ARM::SUBS_PC_LR: {
  2383. MachineInstrBuilder MIB =
  2384. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri), ARM::PC)
  2385. .addReg(ARM::LR)
  2386. .add(MI.getOperand(0))
  2387. .add(MI.getOperand(1))
  2388. .add(MI.getOperand(2))
  2389. .addReg(ARM::CPSR, RegState::Undef);
  2390. TransferImpOps(MI, MIB, MIB);
  2391. MI.eraseFromParent();
  2392. return true;
  2393. }
  2394. case ARM::VLDMQIA: {
  2395. unsigned NewOpc = ARM::VLDMDIA;
  2396. MachineInstrBuilder MIB =
  2397. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
  2398. unsigned OpIdx = 0;
  2399. // Grab the Q register destination.
  2400. bool DstIsDead = MI.getOperand(OpIdx).isDead();
  2401. Register DstReg = MI.getOperand(OpIdx++).getReg();
  2402. // Copy the source register.
  2403. MIB.add(MI.getOperand(OpIdx++));
  2404. // Copy the predicate operands.
  2405. MIB.add(MI.getOperand(OpIdx++));
  2406. MIB.add(MI.getOperand(OpIdx++));
  2407. // Add the destination operands (D subregs).
  2408. Register D0 = TRI->getSubReg(DstReg, ARM::dsub_0);
  2409. Register D1 = TRI->getSubReg(DstReg, ARM::dsub_1);
  2410. MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead))
  2411. .addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
  2412. // Add an implicit def for the super-register.
  2413. MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
  2414. TransferImpOps(MI, MIB, MIB);
  2415. MIB.cloneMemRefs(MI);
  2416. MI.eraseFromParent();
  2417. return true;
  2418. }
  2419. case ARM::VSTMQIA: {
  2420. unsigned NewOpc = ARM::VSTMDIA;
  2421. MachineInstrBuilder MIB =
  2422. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
  2423. unsigned OpIdx = 0;
  2424. // Grab the Q register source.
  2425. bool SrcIsKill = MI.getOperand(OpIdx).isKill();
  2426. Register SrcReg = MI.getOperand(OpIdx++).getReg();
  2427. // Copy the destination register.
  2428. MachineOperand Dst(MI.getOperand(OpIdx++));
  2429. MIB.add(Dst);
  2430. // Copy the predicate operands.
  2431. MIB.add(MI.getOperand(OpIdx++));
  2432. MIB.add(MI.getOperand(OpIdx++));
  2433. // Add the source operands (D subregs).
  2434. Register D0 = TRI->getSubReg(SrcReg, ARM::dsub_0);
  2435. Register D1 = TRI->getSubReg(SrcReg, ARM::dsub_1);
  2436. MIB.addReg(D0, SrcIsKill ? RegState::Kill : 0)
  2437. .addReg(D1, SrcIsKill ? RegState::Kill : 0);
  2438. if (SrcIsKill) // Add an implicit kill for the Q register.
  2439. MIB->addRegisterKilled(SrcReg, TRI, true);
  2440. TransferImpOps(MI, MIB, MIB);
  2441. MIB.cloneMemRefs(MI);
  2442. MI.eraseFromParent();
  2443. return true;
  2444. }
  2445. case ARM::VLD2q8Pseudo:
  2446. case ARM::VLD2q16Pseudo:
  2447. case ARM::VLD2q32Pseudo:
  2448. case ARM::VLD2q8PseudoWB_fixed:
  2449. case ARM::VLD2q16PseudoWB_fixed:
  2450. case ARM::VLD2q32PseudoWB_fixed:
  2451. case ARM::VLD2q8PseudoWB_register:
  2452. case ARM::VLD2q16PseudoWB_register:
  2453. case ARM::VLD2q32PseudoWB_register:
  2454. case ARM::VLD3d8Pseudo:
  2455. case ARM::VLD3d16Pseudo:
  2456. case ARM::VLD3d32Pseudo:
  2457. case ARM::VLD1d8TPseudo:
  2458. case ARM::VLD1d8TPseudoWB_fixed:
  2459. case ARM::VLD1d8TPseudoWB_register:
  2460. case ARM::VLD1d16TPseudo:
  2461. case ARM::VLD1d16TPseudoWB_fixed:
  2462. case ARM::VLD1d16TPseudoWB_register:
  2463. case ARM::VLD1d32TPseudo:
  2464. case ARM::VLD1d32TPseudoWB_fixed:
  2465. case ARM::VLD1d32TPseudoWB_register:
  2466. case ARM::VLD1d64TPseudo:
  2467. case ARM::VLD1d64TPseudoWB_fixed:
  2468. case ARM::VLD1d64TPseudoWB_register:
  2469. case ARM::VLD3d8Pseudo_UPD:
  2470. case ARM::VLD3d16Pseudo_UPD:
  2471. case ARM::VLD3d32Pseudo_UPD:
  2472. case ARM::VLD3q8Pseudo_UPD:
  2473. case ARM::VLD3q16Pseudo_UPD:
  2474. case ARM::VLD3q32Pseudo_UPD:
  2475. case ARM::VLD3q8oddPseudo:
  2476. case ARM::VLD3q16oddPseudo:
  2477. case ARM::VLD3q32oddPseudo:
  2478. case ARM::VLD3q8oddPseudo_UPD:
  2479. case ARM::VLD3q16oddPseudo_UPD:
  2480. case ARM::VLD3q32oddPseudo_UPD:
  2481. case ARM::VLD4d8Pseudo:
  2482. case ARM::VLD4d16Pseudo:
  2483. case ARM::VLD4d32Pseudo:
  2484. case ARM::VLD1d8QPseudo:
  2485. case ARM::VLD1d8QPseudoWB_fixed:
  2486. case ARM::VLD1d8QPseudoWB_register:
  2487. case ARM::VLD1d16QPseudo:
  2488. case ARM::VLD1d16QPseudoWB_fixed:
  2489. case ARM::VLD1d16QPseudoWB_register:
  2490. case ARM::VLD1d32QPseudo:
  2491. case ARM::VLD1d32QPseudoWB_fixed:
  2492. case ARM::VLD1d32QPseudoWB_register:
  2493. case ARM::VLD1d64QPseudo:
  2494. case ARM::VLD1d64QPseudoWB_fixed:
  2495. case ARM::VLD1d64QPseudoWB_register:
  2496. case ARM::VLD1q8HighQPseudo:
  2497. case ARM::VLD1q8HighQPseudo_UPD:
  2498. case ARM::VLD1q8LowQPseudo_UPD:
  2499. case ARM::VLD1q8HighTPseudo:
  2500. case ARM::VLD1q8HighTPseudo_UPD:
  2501. case ARM::VLD1q8LowTPseudo_UPD:
  2502. case ARM::VLD1q16HighQPseudo:
  2503. case ARM::VLD1q16HighQPseudo_UPD:
  2504. case ARM::VLD1q16LowQPseudo_UPD:
  2505. case ARM::VLD1q16HighTPseudo:
  2506. case ARM::VLD1q16HighTPseudo_UPD:
  2507. case ARM::VLD1q16LowTPseudo_UPD:
  2508. case ARM::VLD1q32HighQPseudo:
  2509. case ARM::VLD1q32HighQPseudo_UPD:
  2510. case ARM::VLD1q32LowQPseudo_UPD:
  2511. case ARM::VLD1q32HighTPseudo:
  2512. case ARM::VLD1q32HighTPseudo_UPD:
  2513. case ARM::VLD1q32LowTPseudo_UPD:
  2514. case ARM::VLD1q64HighQPseudo:
  2515. case ARM::VLD1q64HighQPseudo_UPD:
  2516. case ARM::VLD1q64LowQPseudo_UPD:
  2517. case ARM::VLD1q64HighTPseudo:
  2518. case ARM::VLD1q64HighTPseudo_UPD:
  2519. case ARM::VLD1q64LowTPseudo_UPD:
  2520. case ARM::VLD4d8Pseudo_UPD:
  2521. case ARM::VLD4d16Pseudo_UPD:
  2522. case ARM::VLD4d32Pseudo_UPD:
  2523. case ARM::VLD4q8Pseudo_UPD:
  2524. case ARM::VLD4q16Pseudo_UPD:
  2525. case ARM::VLD4q32Pseudo_UPD:
  2526. case ARM::VLD4q8oddPseudo:
  2527. case ARM::VLD4q16oddPseudo:
  2528. case ARM::VLD4q32oddPseudo:
  2529. case ARM::VLD4q8oddPseudo_UPD:
  2530. case ARM::VLD4q16oddPseudo_UPD:
  2531. case ARM::VLD4q32oddPseudo_UPD:
  2532. case ARM::VLD3DUPd8Pseudo:
  2533. case ARM::VLD3DUPd16Pseudo:
  2534. case ARM::VLD3DUPd32Pseudo:
  2535. case ARM::VLD3DUPd8Pseudo_UPD:
  2536. case ARM::VLD3DUPd16Pseudo_UPD:
  2537. case ARM::VLD3DUPd32Pseudo_UPD:
  2538. case ARM::VLD4DUPd8Pseudo:
  2539. case ARM::VLD4DUPd16Pseudo:
  2540. case ARM::VLD4DUPd32Pseudo:
  2541. case ARM::VLD4DUPd8Pseudo_UPD:
  2542. case ARM::VLD4DUPd16Pseudo_UPD:
  2543. case ARM::VLD4DUPd32Pseudo_UPD:
  2544. case ARM::VLD2DUPq8EvenPseudo:
  2545. case ARM::VLD2DUPq8OddPseudo:
  2546. case ARM::VLD2DUPq16EvenPseudo:
  2547. case ARM::VLD2DUPq16OddPseudo:
  2548. case ARM::VLD2DUPq32EvenPseudo:
  2549. case ARM::VLD2DUPq32OddPseudo:
  2550. case ARM::VLD2DUPq8OddPseudoWB_fixed:
  2551. case ARM::VLD2DUPq8OddPseudoWB_register:
  2552. case ARM::VLD2DUPq16OddPseudoWB_fixed:
  2553. case ARM::VLD2DUPq16OddPseudoWB_register:
  2554. case ARM::VLD2DUPq32OddPseudoWB_fixed:
  2555. case ARM::VLD2DUPq32OddPseudoWB_register:
  2556. case ARM::VLD3DUPq8EvenPseudo:
  2557. case ARM::VLD3DUPq8OddPseudo:
  2558. case ARM::VLD3DUPq16EvenPseudo:
  2559. case ARM::VLD3DUPq16OddPseudo:
  2560. case ARM::VLD3DUPq32EvenPseudo:
  2561. case ARM::VLD3DUPq32OddPseudo:
  2562. case ARM::VLD3DUPq8OddPseudo_UPD:
  2563. case ARM::VLD3DUPq16OddPseudo_UPD:
  2564. case ARM::VLD3DUPq32OddPseudo_UPD:
  2565. case ARM::VLD4DUPq8EvenPseudo:
  2566. case ARM::VLD4DUPq8OddPseudo:
  2567. case ARM::VLD4DUPq16EvenPseudo:
  2568. case ARM::VLD4DUPq16OddPseudo:
  2569. case ARM::VLD4DUPq32EvenPseudo:
  2570. case ARM::VLD4DUPq32OddPseudo:
  2571. case ARM::VLD4DUPq8OddPseudo_UPD:
  2572. case ARM::VLD4DUPq16OddPseudo_UPD:
  2573. case ARM::VLD4DUPq32OddPseudo_UPD:
  2574. ExpandVLD(MBBI);
  2575. return true;
  2576. case ARM::VST2q8Pseudo:
  2577. case ARM::VST2q16Pseudo:
  2578. case ARM::VST2q32Pseudo:
  2579. case ARM::VST2q8PseudoWB_fixed:
  2580. case ARM::VST2q16PseudoWB_fixed:
  2581. case ARM::VST2q32PseudoWB_fixed:
  2582. case ARM::VST2q8PseudoWB_register:
  2583. case ARM::VST2q16PseudoWB_register:
  2584. case ARM::VST2q32PseudoWB_register:
  2585. case ARM::VST3d8Pseudo:
  2586. case ARM::VST3d16Pseudo:
  2587. case ARM::VST3d32Pseudo:
  2588. case ARM::VST1d8TPseudo:
  2589. case ARM::VST1d8TPseudoWB_fixed:
  2590. case ARM::VST1d8TPseudoWB_register:
  2591. case ARM::VST1d16TPseudo:
  2592. case ARM::VST1d16TPseudoWB_fixed:
  2593. case ARM::VST1d16TPseudoWB_register:
  2594. case ARM::VST1d32TPseudo:
  2595. case ARM::VST1d32TPseudoWB_fixed:
  2596. case ARM::VST1d32TPseudoWB_register:
  2597. case ARM::VST1d64TPseudo:
  2598. case ARM::VST1d64TPseudoWB_fixed:
  2599. case ARM::VST1d64TPseudoWB_register:
  2600. case ARM::VST3d8Pseudo_UPD:
  2601. case ARM::VST3d16Pseudo_UPD:
  2602. case ARM::VST3d32Pseudo_UPD:
  2603. case ARM::VST3q8Pseudo_UPD:
  2604. case ARM::VST3q16Pseudo_UPD:
  2605. case ARM::VST3q32Pseudo_UPD:
  2606. case ARM::VST3q8oddPseudo:
  2607. case ARM::VST3q16oddPseudo:
  2608. case ARM::VST3q32oddPseudo:
  2609. case ARM::VST3q8oddPseudo_UPD:
  2610. case ARM::VST3q16oddPseudo_UPD:
  2611. case ARM::VST3q32oddPseudo_UPD:
  2612. case ARM::VST4d8Pseudo:
  2613. case ARM::VST4d16Pseudo:
  2614. case ARM::VST4d32Pseudo:
  2615. case ARM::VST1d8QPseudo:
  2616. case ARM::VST1d8QPseudoWB_fixed:
  2617. case ARM::VST1d8QPseudoWB_register:
  2618. case ARM::VST1d16QPseudo:
  2619. case ARM::VST1d16QPseudoWB_fixed:
  2620. case ARM::VST1d16QPseudoWB_register:
  2621. case ARM::VST1d32QPseudo:
  2622. case ARM::VST1d32QPseudoWB_fixed:
  2623. case ARM::VST1d32QPseudoWB_register:
  2624. case ARM::VST1d64QPseudo:
  2625. case ARM::VST1d64QPseudoWB_fixed:
  2626. case ARM::VST1d64QPseudoWB_register:
  2627. case ARM::VST4d8Pseudo_UPD:
  2628. case ARM::VST4d16Pseudo_UPD:
  2629. case ARM::VST4d32Pseudo_UPD:
  2630. case ARM::VST1q8HighQPseudo:
  2631. case ARM::VST1q8LowQPseudo_UPD:
  2632. case ARM::VST1q8HighTPseudo:
  2633. case ARM::VST1q8LowTPseudo_UPD:
  2634. case ARM::VST1q16HighQPseudo:
  2635. case ARM::VST1q16LowQPseudo_UPD:
  2636. case ARM::VST1q16HighTPseudo:
  2637. case ARM::VST1q16LowTPseudo_UPD:
  2638. case ARM::VST1q32HighQPseudo:
  2639. case ARM::VST1q32LowQPseudo_UPD:
  2640. case ARM::VST1q32HighTPseudo:
  2641. case ARM::VST1q32LowTPseudo_UPD:
  2642. case ARM::VST1q64HighQPseudo:
  2643. case ARM::VST1q64LowQPseudo_UPD:
  2644. case ARM::VST1q64HighTPseudo:
  2645. case ARM::VST1q64LowTPseudo_UPD:
  2646. case ARM::VST1q8HighTPseudo_UPD:
  2647. case ARM::VST1q16HighTPseudo_UPD:
  2648. case ARM::VST1q32HighTPseudo_UPD:
  2649. case ARM::VST1q64HighTPseudo_UPD:
  2650. case ARM::VST1q8HighQPseudo_UPD:
  2651. case ARM::VST1q16HighQPseudo_UPD:
  2652. case ARM::VST1q32HighQPseudo_UPD:
  2653. case ARM::VST1q64HighQPseudo_UPD:
  2654. case ARM::VST4q8Pseudo_UPD:
  2655. case ARM::VST4q16Pseudo_UPD:
  2656. case ARM::VST4q32Pseudo_UPD:
  2657. case ARM::VST4q8oddPseudo:
  2658. case ARM::VST4q16oddPseudo:
  2659. case ARM::VST4q32oddPseudo:
  2660. case ARM::VST4q8oddPseudo_UPD:
  2661. case ARM::VST4q16oddPseudo_UPD:
  2662. case ARM::VST4q32oddPseudo_UPD:
  2663. ExpandVST(MBBI);
  2664. return true;
  2665. case ARM::VLD1LNq8Pseudo:
  2666. case ARM::VLD1LNq16Pseudo:
  2667. case ARM::VLD1LNq32Pseudo:
  2668. case ARM::VLD1LNq8Pseudo_UPD:
  2669. case ARM::VLD1LNq16Pseudo_UPD:
  2670. case ARM::VLD1LNq32Pseudo_UPD:
  2671. case ARM::VLD2LNd8Pseudo:
  2672. case ARM::VLD2LNd16Pseudo:
  2673. case ARM::VLD2LNd32Pseudo:
  2674. case ARM::VLD2LNq16Pseudo:
  2675. case ARM::VLD2LNq32Pseudo:
  2676. case ARM::VLD2LNd8Pseudo_UPD:
  2677. case ARM::VLD2LNd16Pseudo_UPD:
  2678. case ARM::VLD2LNd32Pseudo_UPD:
  2679. case ARM::VLD2LNq16Pseudo_UPD:
  2680. case ARM::VLD2LNq32Pseudo_UPD:
  2681. case ARM::VLD3LNd8Pseudo:
  2682. case ARM::VLD3LNd16Pseudo:
  2683. case ARM::VLD3LNd32Pseudo:
  2684. case ARM::VLD3LNq16Pseudo:
  2685. case ARM::VLD3LNq32Pseudo:
  2686. case ARM::VLD3LNd8Pseudo_UPD:
  2687. case ARM::VLD3LNd16Pseudo_UPD:
  2688. case ARM::VLD3LNd32Pseudo_UPD:
  2689. case ARM::VLD3LNq16Pseudo_UPD:
  2690. case ARM::VLD3LNq32Pseudo_UPD:
  2691. case ARM::VLD4LNd8Pseudo:
  2692. case ARM::VLD4LNd16Pseudo:
  2693. case ARM::VLD4LNd32Pseudo:
  2694. case ARM::VLD4LNq16Pseudo:
  2695. case ARM::VLD4LNq32Pseudo:
  2696. case ARM::VLD4LNd8Pseudo_UPD:
  2697. case ARM::VLD4LNd16Pseudo_UPD:
  2698. case ARM::VLD4LNd32Pseudo_UPD:
  2699. case ARM::VLD4LNq16Pseudo_UPD:
  2700. case ARM::VLD4LNq32Pseudo_UPD:
  2701. case ARM::VST1LNq8Pseudo:
  2702. case ARM::VST1LNq16Pseudo:
  2703. case ARM::VST1LNq32Pseudo:
  2704. case ARM::VST1LNq8Pseudo_UPD:
  2705. case ARM::VST1LNq16Pseudo_UPD:
  2706. case ARM::VST1LNq32Pseudo_UPD:
  2707. case ARM::VST2LNd8Pseudo:
  2708. case ARM::VST2LNd16Pseudo:
  2709. case ARM::VST2LNd32Pseudo:
  2710. case ARM::VST2LNq16Pseudo:
  2711. case ARM::VST2LNq32Pseudo:
  2712. case ARM::VST2LNd8Pseudo_UPD:
  2713. case ARM::VST2LNd16Pseudo_UPD:
  2714. case ARM::VST2LNd32Pseudo_UPD:
  2715. case ARM::VST2LNq16Pseudo_UPD:
  2716. case ARM::VST2LNq32Pseudo_UPD:
  2717. case ARM::VST3LNd8Pseudo:
  2718. case ARM::VST3LNd16Pseudo:
  2719. case ARM::VST3LNd32Pseudo:
  2720. case ARM::VST3LNq16Pseudo:
  2721. case ARM::VST3LNq32Pseudo:
  2722. case ARM::VST3LNd8Pseudo_UPD:
  2723. case ARM::VST3LNd16Pseudo_UPD:
  2724. case ARM::VST3LNd32Pseudo_UPD:
  2725. case ARM::VST3LNq16Pseudo_UPD:
  2726. case ARM::VST3LNq32Pseudo_UPD:
  2727. case ARM::VST4LNd8Pseudo:
  2728. case ARM::VST4LNd16Pseudo:
  2729. case ARM::VST4LNd32Pseudo:
  2730. case ARM::VST4LNq16Pseudo:
  2731. case ARM::VST4LNq32Pseudo:
  2732. case ARM::VST4LNd8Pseudo_UPD:
  2733. case ARM::VST4LNd16Pseudo_UPD:
  2734. case ARM::VST4LNd32Pseudo_UPD:
  2735. case ARM::VST4LNq16Pseudo_UPD:
  2736. case ARM::VST4LNq32Pseudo_UPD:
  2737. ExpandLaneOp(MBBI);
  2738. return true;
  2739. case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false); return true;
  2740. case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true;
  2741. case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true;
  2742. case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true;
  2743. case ARM::MQQPRLoad:
  2744. case ARM::MQQPRStore:
  2745. case ARM::MQQQQPRLoad:
  2746. case ARM::MQQQQPRStore:
  2747. ExpandMQQPRLoadStore(MBBI);
  2748. return true;
  2749. case ARM::tCMP_SWAP_8:
  2750. assert(STI->isThumb());
  2751. return ExpandCMP_SWAP(MBB, MBBI, ARM::t2LDREXB, ARM::t2STREXB, ARM::tUXTB,
  2752. NextMBBI);
  2753. case ARM::tCMP_SWAP_16:
  2754. assert(STI->isThumb());
  2755. return ExpandCMP_SWAP(MBB, MBBI, ARM::t2LDREXH, ARM::t2STREXH, ARM::tUXTH,
  2756. NextMBBI);
  2757. case ARM::CMP_SWAP_8:
  2758. assert(!STI->isThumb());
  2759. return ExpandCMP_SWAP(MBB, MBBI, ARM::LDREXB, ARM::STREXB, ARM::UXTB,
  2760. NextMBBI);
  2761. case ARM::CMP_SWAP_16:
  2762. assert(!STI->isThumb());
  2763. return ExpandCMP_SWAP(MBB, MBBI, ARM::LDREXH, ARM::STREXH, ARM::UXTH,
  2764. NextMBBI);
  2765. case ARM::CMP_SWAP_32:
  2766. if (STI->isThumb())
  2767. return ExpandCMP_SWAP(MBB, MBBI, ARM::t2LDREX, ARM::t2STREX, 0,
  2768. NextMBBI);
  2769. else
  2770. return ExpandCMP_SWAP(MBB, MBBI, ARM::LDREX, ARM::STREX, 0, NextMBBI);
  2771. case ARM::CMP_SWAP_64:
  2772. return ExpandCMP_SWAP_64(MBB, MBBI, NextMBBI);
  2773. case ARM::tBL_PUSHLR:
  2774. case ARM::BL_PUSHLR: {
  2775. const bool Thumb = Opcode == ARM::tBL_PUSHLR;
  2776. Register Reg = MI.getOperand(0).getReg();
  2777. assert(Reg == ARM::LR && "expect LR register!");
  2778. MachineInstrBuilder MIB;
  2779. if (Thumb) {
  2780. // push {lr}
  2781. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPUSH))
  2782. .add(predOps(ARMCC::AL))
  2783. .addReg(Reg);
  2784. // bl __gnu_mcount_nc
  2785. MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tBL));
  2786. } else {
  2787. // stmdb sp!, {lr}
  2788. BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::STMDB_UPD))
  2789. .addReg(ARM::SP, RegState::Define)
  2790. .addReg(ARM::SP)
  2791. .add(predOps(ARMCC::AL))
  2792. .addReg(Reg);
  2793. // bl __gnu_mcount_nc
  2794. MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::BL));
  2795. }
  2796. MIB.cloneMemRefs(MI);
  2797. for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
  2798. MIB.add(MO);
  2799. MI.eraseFromParent();
  2800. return true;
  2801. }
  2802. case ARM::t2CALL_BTI: {
  2803. MachineFunction &MF = *MI.getMF();
  2804. MachineInstrBuilder MIB =
  2805. BuildMI(MF, MI.getDebugLoc(), TII->get(ARM::tBL));
  2806. MIB.cloneMemRefs(MI);
  2807. for (unsigned i = 0; i < MI.getNumOperands(); ++i)
  2808. MIB.add(MI.getOperand(i));
  2809. if (MI.isCandidateForCallSiteEntry())
  2810. MF.moveCallSiteInfo(&MI, MIB.getInstr());
  2811. MIBundleBuilder Bundler(MBB, MI);
  2812. Bundler.append(MIB);
  2813. Bundler.append(BuildMI(MF, MI.getDebugLoc(), TII->get(ARM::t2BTI)));
  2814. finalizeBundle(MBB, Bundler.begin(), Bundler.end());
  2815. MI.eraseFromParent();
  2816. return true;
  2817. }
  2818. case ARM::LOADDUAL:
  2819. case ARM::STOREDUAL: {
  2820. Register PairReg = MI.getOperand(0).getReg();
  2821. MachineInstrBuilder MIB =
  2822. BuildMI(MBB, MBBI, MI.getDebugLoc(),
  2823. TII->get(Opcode == ARM::LOADDUAL ? ARM::LDRD : ARM::STRD))
  2824. .addReg(TRI->getSubReg(PairReg, ARM::gsub_0),
  2825. Opcode == ARM::LOADDUAL ? RegState::Define : 0)
  2826. .addReg(TRI->getSubReg(PairReg, ARM::gsub_1),
  2827. Opcode == ARM::LOADDUAL ? RegState::Define : 0);
  2828. for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
  2829. MIB.add(MO);
  2830. MIB.add(predOps(ARMCC::AL));
  2831. MIB.cloneMemRefs(MI);
  2832. MI.eraseFromParent();
  2833. return true;
  2834. }
  2835. }
  2836. }
  2837. bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
  2838. bool Modified = false;
  2839. MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
  2840. while (MBBI != E) {
  2841. MachineBasicBlock::iterator NMBBI = std::next(MBBI);
  2842. Modified |= ExpandMI(MBB, MBBI, NMBBI);
  2843. MBBI = NMBBI;
  2844. }
  2845. return Modified;
  2846. }
  2847. bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
  2848. STI = &static_cast<const ARMSubtarget &>(MF.getSubtarget());
  2849. TII = STI->getInstrInfo();
  2850. TRI = STI->getRegisterInfo();
  2851. AFI = MF.getInfo<ARMFunctionInfo>();
  2852. LLVM_DEBUG(dbgs() << "********** ARM EXPAND PSEUDO INSTRUCTIONS **********\n"
  2853. << "********** Function: " << MF.getName() << '\n');
  2854. bool Modified = false;
  2855. for (MachineBasicBlock &MBB : MF)
  2856. Modified |= ExpandMBB(MBB);
  2857. if (VerifyARMPseudo)
  2858. MF.verify(this, "After expanding ARM pseudo instructions.");
  2859. LLVM_DEBUG(dbgs() << "***************************************************\n");
  2860. return Modified;
  2861. }
  2862. /// createARMExpandPseudoPass - returns an instance of the pseudo instruction
  2863. /// expansion pass.
  2864. FunctionPass *llvm::createARMExpandPseudoPass() {
  2865. return new ARMExpandPseudo();
  2866. }