AArch64SchedThunderX.td 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. //==- AArch64SchedThunderX.td - Cavium ThunderX T8X Scheduling Definitions -*- tablegen -*-=//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines the itinerary class data for the ARM ThunderX T8X
  10. // (T88, T81, T83) processors.
  11. // Loosely based on Cortex-A53 which is somewhat similar.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. // ===---------------------------------------------------------------------===//
  15. // The following definitions describe the simpler per-operand machine model.
  16. // This works with MachineScheduler. See llvm/MC/MCSchedule.h for details.
  17. // Cavium ThunderX T8X scheduling machine model.
  18. def ThunderXT8XModel : SchedMachineModel {
  19. let IssueWidth = 2; // 2 micro-ops dispatched per cycle.
  20. let MicroOpBufferSize = 0; // ThunderX T88/T81/T83 are in-order.
  21. let LoadLatency = 3; // Optimistic load latency.
  22. let MispredictPenalty = 8; // Branch mispredict penalty.
  23. let PostRAScheduler = 1; // Use PostRA scheduler.
  24. let CompleteModel = 1;
  25. list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
  26. PAUnsupported.F,
  27. SMEUnsupported.F);
  28. // FIXME: Remove when all errors have been fixed.
  29. let FullInstRWOverlapCheck = 0;
  30. }
  31. // Modeling each pipeline with BufferSize == 0 since T8X is in-order.
  32. def THXT8XUnitALU : ProcResource<2> { let BufferSize = 0; } // Int ALU
  33. def THXT8XUnitMAC : ProcResource<1> { let BufferSize = 0; } // Int MAC
  34. def THXT8XUnitDiv : ProcResource<1> { let BufferSize = 0; } // Int Division
  35. def THXT8XUnitLdSt : ProcResource<1> { let BufferSize = 0; } // Load/Store
  36. def THXT8XUnitBr : ProcResource<1> { let BufferSize = 0; } // Branch
  37. def THXT8XUnitFPALU : ProcResource<1> { let BufferSize = 0; } // FP ALU
  38. def THXT8XUnitFPMDS : ProcResource<1> { let BufferSize = 0; } // FP Mul/Div/Sqrt
  39. //===----------------------------------------------------------------------===//
  40. // Subtarget-specific SchedWrite types mapping the ProcResources and
  41. // latencies.
  42. let SchedModel = ThunderXT8XModel in {
  43. // ALU
  44. def : WriteRes<WriteImm, [THXT8XUnitALU]> { let Latency = 1; }
  45. def : WriteRes<WriteI, [THXT8XUnitALU]> { let Latency = 1; }
  46. def : WriteRes<WriteISReg, [THXT8XUnitALU]> { let Latency = 2; }
  47. def : WriteRes<WriteIEReg, [THXT8XUnitALU]> { let Latency = 2; }
  48. def : WriteRes<WriteIS, [THXT8XUnitALU]> { let Latency = 2; }
  49. def : WriteRes<WriteExtr, [THXT8XUnitALU]> { let Latency = 2; }
  50. // MAC
  51. def : WriteRes<WriteIM32, [THXT8XUnitMAC]> {
  52. let Latency = 4;
  53. let ResourceCycles = [1];
  54. }
  55. def : WriteRes<WriteIM64, [THXT8XUnitMAC]> {
  56. let Latency = 4;
  57. let ResourceCycles = [1];
  58. }
  59. // Div
  60. def : WriteRes<WriteID32, [THXT8XUnitDiv]> {
  61. let Latency = 12;
  62. let ResourceCycles = [6];
  63. }
  64. def : WriteRes<WriteID64, [THXT8XUnitDiv]> {
  65. let Latency = 14;
  66. let ResourceCycles = [8];
  67. }
  68. // Load
  69. def : WriteRes<WriteLD, [THXT8XUnitLdSt]> { let Latency = 3; }
  70. def : WriteRes<WriteLDIdx, [THXT8XUnitLdSt]> { let Latency = 3; }
  71. def : WriteRes<WriteLDHi, [THXT8XUnitLdSt]> { let Latency = 3; }
  72. // Vector Load
  73. def : WriteRes<WriteVLD, [THXT8XUnitLdSt]> {
  74. let Latency = 8;
  75. let ResourceCycles = [3];
  76. }
  77. def THXT8XWriteVLD1 : SchedWriteRes<[THXT8XUnitLdSt]> {
  78. let Latency = 6;
  79. let ResourceCycles = [1];
  80. }
  81. def THXT8XWriteVLD2 : SchedWriteRes<[THXT8XUnitLdSt]> {
  82. let Latency = 11;
  83. let ResourceCycles = [7];
  84. }
  85. def THXT8XWriteVLD3 : SchedWriteRes<[THXT8XUnitLdSt]> {
  86. let Latency = 12;
  87. let ResourceCycles = [8];
  88. }
  89. def THXT8XWriteVLD4 : SchedWriteRes<[THXT8XUnitLdSt]> {
  90. let Latency = 13;
  91. let ResourceCycles = [9];
  92. }
  93. def THXT8XWriteVLD5 : SchedWriteRes<[THXT8XUnitLdSt]> {
  94. let Latency = 13;
  95. let ResourceCycles = [9];
  96. }
  97. // Pre/Post Indexing
  98. def : WriteRes<WriteAdr, []> { let Latency = 0; }
  99. // Store
  100. def : WriteRes<WriteST, [THXT8XUnitLdSt]> { let Latency = 1; }
  101. def : WriteRes<WriteSTP, [THXT8XUnitLdSt]> { let Latency = 1; }
  102. def : WriteRes<WriteSTIdx, [THXT8XUnitLdSt]> { let Latency = 1; }
  103. def : WriteRes<WriteSTX, [THXT8XUnitLdSt]> { let Latency = 1; }
  104. // Vector Store
  105. def : WriteRes<WriteVST, [THXT8XUnitLdSt]>;
  106. def THXT8XWriteVST1 : SchedWriteRes<[THXT8XUnitLdSt]>;
  107. def THXT8XWriteVST2 : SchedWriteRes<[THXT8XUnitLdSt]> {
  108. let Latency = 10;
  109. let ResourceCycles = [9];
  110. }
  111. def THXT8XWriteVST3 : SchedWriteRes<[THXT8XUnitLdSt]> {
  112. let Latency = 11;
  113. let ResourceCycles = [10];
  114. }
  115. def : WriteRes<WriteAtomic, []> { let Unsupported = 1; }
  116. // Branch
  117. def : WriteRes<WriteBr, [THXT8XUnitBr]>;
  118. def THXT8XWriteBR : SchedWriteRes<[THXT8XUnitBr]>;
  119. def : WriteRes<WriteBrReg, [THXT8XUnitBr]>;
  120. def THXT8XWriteBRR : SchedWriteRes<[THXT8XUnitBr]>;
  121. def THXT8XWriteRET : SchedWriteRes<[THXT8XUnitALU]>;
  122. def : WriteRes<WriteSys, [THXT8XUnitBr]>;
  123. def : WriteRes<WriteBarrier, [THXT8XUnitBr]>;
  124. def : WriteRes<WriteHint, [THXT8XUnitBr]>;
  125. // FP ALU
  126. def : WriteRes<WriteF, [THXT8XUnitFPALU]> { let Latency = 6; }
  127. def : WriteRes<WriteFCmp, [THXT8XUnitFPALU]> { let Latency = 6; }
  128. def : WriteRes<WriteFCvt, [THXT8XUnitFPALU]> { let Latency = 6; }
  129. def : WriteRes<WriteFCopy, [THXT8XUnitFPALU]> { let Latency = 6; }
  130. def : WriteRes<WriteFImm, [THXT8XUnitFPALU]> { let Latency = 6; }
  131. def : WriteRes<WriteVd, [THXT8XUnitFPALU]> { let Latency = 6; }
  132. def : WriteRes<WriteVq, [THXT8XUnitFPALU]> { let Latency = 6; }
  133. // FP Mul, Div, Sqrt
  134. def : WriteRes<WriteFMul, [THXT8XUnitFPMDS]> { let Latency = 6; }
  135. def : WriteRes<WriteFDiv, [THXT8XUnitFPMDS]> {
  136. let Latency = 22;
  137. let ResourceCycles = [19];
  138. }
  139. def THXT8XWriteFMAC : SchedWriteRes<[THXT8XUnitFPMDS]> { let Latency = 10; }
  140. def THXT8XWriteFDivSP : SchedWriteRes<[THXT8XUnitFPMDS]> {
  141. let Latency = 12;
  142. let ResourceCycles = [9];
  143. }
  144. def THXT8XWriteFDivDP : SchedWriteRes<[THXT8XUnitFPMDS]> {
  145. let Latency = 22;
  146. let ResourceCycles = [19];
  147. }
  148. def THXT8XWriteFSqrtSP : SchedWriteRes<[THXT8XUnitFPMDS]> {
  149. let Latency = 17;
  150. let ResourceCycles = [14];
  151. }
  152. def THXT8XWriteFSqrtDP : SchedWriteRes<[THXT8XUnitFPMDS]> {
  153. let Latency = 31;
  154. let ResourceCycles = [28];
  155. }
  156. //===----------------------------------------------------------------------===//
  157. // Subtarget-specific SchedRead types.
  158. // No forwarding for these reads.
  159. def : ReadAdvance<ReadExtrHi, 1>;
  160. def : ReadAdvance<ReadAdrBase, 2>;
  161. def : ReadAdvance<ReadVLD, 2>;
  162. def : ReadAdvance<ReadST, 2>;
  163. // FIXME: This needs more targeted benchmarking.
  164. // ALU - Most operands in the ALU pipes are not needed for two cycles. Shiftable
  165. // operands are needed one cycle later if and only if they are to be
  166. // shifted. Otherwise, they too are needed two cycles later. This same
  167. // ReadAdvance applies to Extended registers as well, even though there is
  168. // a separate SchedPredicate for them.
  169. def : ReadAdvance<ReadI, 2, [WriteImm, WriteI,
  170. WriteISReg, WriteIEReg, WriteIS,
  171. WriteID32, WriteID64,
  172. WriteIM32, WriteIM64]>;
  173. def THXT8XReadShifted : SchedReadAdvance<1, [WriteImm, WriteI,
  174. WriteISReg, WriteIEReg, WriteIS,
  175. WriteID32, WriteID64,
  176. WriteIM32, WriteIM64]>;
  177. def THXT8XReadNotShifted : SchedReadAdvance<2, [WriteImm, WriteI,
  178. WriteISReg, WriteIEReg, WriteIS,
  179. WriteID32, WriteID64,
  180. WriteIM32, WriteIM64]>;
  181. def THXT8XReadISReg : SchedReadVariant<[
  182. SchedVar<RegShiftedPred, [THXT8XReadShifted]>,
  183. SchedVar<NoSchedPred, [THXT8XReadNotShifted]>]>;
  184. def : SchedAlias<ReadISReg, THXT8XReadISReg>;
  185. def THXT8XReadIEReg : SchedReadVariant<[
  186. SchedVar<RegExtendedPred, [THXT8XReadShifted]>,
  187. SchedVar<NoSchedPred, [THXT8XReadNotShifted]>]>;
  188. def : SchedAlias<ReadIEReg, THXT8XReadIEReg>;
  189. // MAC - Operands are generally needed one cycle later in the MAC pipe.
  190. // Accumulator operands are needed two cycles later.
  191. def : ReadAdvance<ReadIM, 1, [WriteImm,WriteI,
  192. WriteISReg, WriteIEReg, WriteIS,
  193. WriteID32, WriteID64,
  194. WriteIM32, WriteIM64]>;
  195. def : ReadAdvance<ReadIMA, 2, [WriteImm, WriteI,
  196. WriteISReg, WriteIEReg, WriteIS,
  197. WriteID32, WriteID64,
  198. WriteIM32, WriteIM64]>;
  199. // Div
  200. def : ReadAdvance<ReadID, 1, [WriteImm, WriteI,
  201. WriteISReg, WriteIEReg, WriteIS,
  202. WriteID32, WriteID64,
  203. WriteIM32, WriteIM64]>;
  204. //===----------------------------------------------------------------------===//
  205. // Subtarget-specific InstRW.
  206. //---
  207. // Branch
  208. //---
  209. def : InstRW<[THXT8XWriteBR], (instregex "^B$")>;
  210. def : InstRW<[THXT8XWriteBR], (instregex "^BL$")>;
  211. def : InstRW<[THXT8XWriteBR], (instregex "^B..$")>;
  212. def : InstRW<[THXT8XWriteBR], (instregex "^CBNZ")>;
  213. def : InstRW<[THXT8XWriteBR], (instregex "^CBZ")>;
  214. def : InstRW<[THXT8XWriteBR], (instregex "^TBNZ")>;
  215. def : InstRW<[THXT8XWriteBR], (instregex "^TBZ")>;
  216. def : InstRW<[THXT8XWriteBRR], (instregex "^BR$")>;
  217. def : InstRW<[THXT8XWriteBRR], (instregex "^BLR$")>;
  218. //---
  219. // Ret
  220. //---
  221. def : InstRW<[THXT8XWriteRET], (instregex "^RET$")>;
  222. //---
  223. // Miscellaneous
  224. //---
  225. def : InstRW<[WriteI], (instrs COPY)>;
  226. //---
  227. // Vector Loads
  228. //---
  229. def : InstRW<[THXT8XWriteVLD1], (instregex "LD1i(8|16|32|64)$")>;
  230. def : InstRW<[THXT8XWriteVLD1], (instregex "LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  231. def : InstRW<[THXT8XWriteVLD1], (instregex "LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  232. def : InstRW<[THXT8XWriteVLD2], (instregex "LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  233. def : InstRW<[THXT8XWriteVLD3], (instregex "LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  234. def : InstRW<[THXT8XWriteVLD4], (instregex "LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  235. def : InstRW<[THXT8XWriteVLD1, WriteAdr], (instregex "LD1i(8|16|32|64)_POST$")>;
  236. def : InstRW<[THXT8XWriteVLD1, WriteAdr], (instregex "LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  237. def : InstRW<[THXT8XWriteVLD1, WriteAdr], (instregex "LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  238. def : InstRW<[THXT8XWriteVLD2, WriteAdr], (instregex "LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  239. def : InstRW<[THXT8XWriteVLD3, WriteAdr], (instregex "LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  240. def : InstRW<[THXT8XWriteVLD4, WriteAdr], (instregex "LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  241. def : InstRW<[THXT8XWriteVLD1], (instregex "LD2i(8|16|32|64)$")>;
  242. def : InstRW<[THXT8XWriteVLD1], (instregex "LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  243. def : InstRW<[THXT8XWriteVLD2], (instregex "LD2Twov(8b|4h|2s)$")>;
  244. def : InstRW<[THXT8XWriteVLD4], (instregex "LD2Twov(16b|8h|4s|2d)$")>;
  245. def : InstRW<[THXT8XWriteVLD1, WriteAdr], (instregex "LD2i(8|16|32|64)(_POST)?$")>;
  246. def : InstRW<[THXT8XWriteVLD1, WriteAdr], (instregex "LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)(_POST)?$")>;
  247. def : InstRW<[THXT8XWriteVLD2, WriteAdr], (instregex "LD2Twov(8b|4h|2s)(_POST)?$")>;
  248. def : InstRW<[THXT8XWriteVLD4, WriteAdr], (instregex "LD2Twov(16b|8h|4s|2d)(_POST)?$")>;
  249. def : InstRW<[THXT8XWriteVLD2], (instregex "LD3i(8|16|32|64)$")>;
  250. def : InstRW<[THXT8XWriteVLD2], (instregex "LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  251. def : InstRW<[THXT8XWriteVLD4], (instregex "LD3Threev(8b|4h|2s|1d|16b|8h|4s)$")>;
  252. def : InstRW<[THXT8XWriteVLD3], (instregex "LD3Threev(2d)$")>;
  253. def : InstRW<[THXT8XWriteVLD2, WriteAdr], (instregex "LD3i(8|16|32|64)_POST$")>;
  254. def : InstRW<[THXT8XWriteVLD2, WriteAdr], (instregex "LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  255. def : InstRW<[THXT8XWriteVLD4, WriteAdr], (instregex "LD3Threev(8b|4h|2s|1d|16b|8h|4s)_POST$")>;
  256. def : InstRW<[THXT8XWriteVLD3, WriteAdr], (instregex "LD3Threev(2d)_POST$")>;
  257. def : InstRW<[THXT8XWriteVLD2], (instregex "LD4i(8|16|32|64)$")>;
  258. def : InstRW<[THXT8XWriteVLD2], (instregex "LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  259. def : InstRW<[THXT8XWriteVLD5], (instregex "LD4Fourv(8b|4h|2s|1d|16b|8h|4s)$")>;
  260. def : InstRW<[THXT8XWriteVLD4], (instregex "LD4Fourv(2d)$")>;
  261. def : InstRW<[THXT8XWriteVLD2, WriteAdr], (instregex "LD4i(8|16|32|64)_POST$")>;
  262. def : InstRW<[THXT8XWriteVLD2, WriteAdr], (instregex "LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  263. def : InstRW<[THXT8XWriteVLD5, WriteAdr], (instregex "LD4Fourv(8b|4h|2s|1d|16b|8h|4s)_POST$")>;
  264. def : InstRW<[THXT8XWriteVLD4, WriteAdr], (instregex "LD4Fourv(2d)_POST$")>;
  265. //---
  266. // Vector Stores
  267. //---
  268. def : InstRW<[THXT8XWriteVST1], (instregex "ST1i(8|16|32|64)$")>;
  269. def : InstRW<[THXT8XWriteVST1], (instregex "ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  270. def : InstRW<[THXT8XWriteVST1], (instregex "ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  271. def : InstRW<[THXT8XWriteVST2], (instregex "ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  272. def : InstRW<[THXT8XWriteVST2], (instregex "ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
  273. def : InstRW<[THXT8XWriteVST1, WriteAdr], (instregex "ST1i(8|16|32|64)_POST$")>;
  274. def : InstRW<[THXT8XWriteVST1, WriteAdr], (instregex "ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  275. def : InstRW<[THXT8XWriteVST1, WriteAdr], (instregex "ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  276. def : InstRW<[THXT8XWriteVST2, WriteAdr], (instregex "ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  277. def : InstRW<[THXT8XWriteVST2, WriteAdr], (instregex "ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
  278. def : InstRW<[THXT8XWriteVST1], (instregex "ST2i(8|16|32|64)$")>;
  279. def : InstRW<[THXT8XWriteVST1], (instregex "ST2Twov(8b|4h|2s)$")>;
  280. def : InstRW<[THXT8XWriteVST2], (instregex "ST2Twov(16b|8h|4s|2d)$")>;
  281. def : InstRW<[THXT8XWriteVST1, WriteAdr], (instregex "ST2i(8|16|32|64)_POST$")>;
  282. def : InstRW<[THXT8XWriteVST1, WriteAdr], (instregex "ST2Twov(8b|4h|2s)_POST$")>;
  283. def : InstRW<[THXT8XWriteVST2, WriteAdr], (instregex "ST2Twov(16b|8h|4s|2d)_POST$")>;
  284. def : InstRW<[THXT8XWriteVST2], (instregex "ST3i(8|16|32|64)$")>;
  285. def : InstRW<[THXT8XWriteVST3], (instregex "ST3Threev(8b|4h|2s|1d|16b|8h|4s)$")>;
  286. def : InstRW<[THXT8XWriteVST2], (instregex "ST3Threev(2d)$")>;
  287. def : InstRW<[THXT8XWriteVST2, WriteAdr], (instregex "ST3i(8|16|32|64)_POST$")>;
  288. def : InstRW<[THXT8XWriteVST3, WriteAdr], (instregex "ST3Threev(8b|4h|2s|1d|16b|8h|4s)_POST$")>;
  289. def : InstRW<[THXT8XWriteVST2, WriteAdr], (instregex "ST3Threev(2d)_POST$")>;
  290. def : InstRW<[THXT8XWriteVST2], (instregex "ST4i(8|16|32|64)$")>;
  291. def : InstRW<[THXT8XWriteVST3], (instregex "ST4Fourv(8b|4h|2s|1d|16b|8h|4s)$")>;
  292. def : InstRW<[THXT8XWriteVST2], (instregex "ST4Fourv(2d)$")>;
  293. def : InstRW<[THXT8XWriteVST2, WriteAdr], (instregex "ST4i(8|16|32|64)_POST$")>;
  294. def : InstRW<[THXT8XWriteVST3, WriteAdr], (instregex "ST4Fourv(8b|4h|2s|1d|16b|8h|4s)_POST$")>;
  295. def : InstRW<[THXT8XWriteVST2, WriteAdr], (instregex "ST4Fourv(2d)_POST$")>;
  296. //---
  297. // Floating Point MAC, DIV, SQRT
  298. //---
  299. def : InstRW<[THXT8XWriteFMAC], (instregex "^FN?M(ADD|SUB).*")>;
  300. def : InstRW<[THXT8XWriteFMAC], (instregex "^FML(A|S).*")>;
  301. def : InstRW<[THXT8XWriteFDivSP], (instrs FDIVSrr)>;
  302. def : InstRW<[THXT8XWriteFDivDP], (instrs FDIVDrr)>;
  303. def : InstRW<[THXT8XWriteFDivSP], (instregex "^FDIVv.*32$")>;
  304. def : InstRW<[THXT8XWriteFDivDP], (instregex "^FDIVv.*64$")>;
  305. def : InstRW<[THXT8XWriteFSqrtSP], (instregex "^.*SQRT.*32$")>;
  306. def : InstRW<[THXT8XWriteFSqrtDP], (instregex "^.*SQRT.*64$")>;
  307. }