cwsr_trap_handler_gfx8.asm 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. /*
  2. * Copyright 2015-2017 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #if 0
  23. HW (VI) source code for CWSR trap handler
  24. #Version 18 + multiple trap handler
  25. // this performance-optimal version was originally from Seven Xu at SRDC
  26. // Revison #18 --...
  27. /* Rev History
  28. ** #1. Branch from gc dv. //gfxip/gfx8/main/src/test/suites/block/cs/sr/cs_trap_handler.sp3#1,#50, #51, #52-53(Skip, Already Fixed by PV), #54-56(merged),#57-58(mergerd, skiped-already fixed by PV)
  29. ** #4. SR Memory Layout:
  30. ** 1. VGPR-SGPR-HWREG-{LDS}
  31. ** 2. tba_hi.bits.26 - reconfigured as the first wave in tg bits, for defer Save LDS for a threadgroup.. performance concern..
  32. ** #5. Update: 1. Accurate g8sr_ts_save_d timestamp
  33. ** #6. Update: 1. Fix s_barrier usage; 2. VGPR s/r using swizzle buffer?(NoNeed, already matched the swizzle pattern, more investigation)
  34. ** #7. Update: 1. don't barrier if noLDS
  35. ** #8. Branch: 1. Branch to ver#0, which is very similar to gc dv version
  36. ** 2. Fix SQ issue by s_sleep 2
  37. ** #9. Update: 1. Fix scc restore failed issue, restore wave_status at last
  38. ** 2. optimize s_buffer save by burst 16sgprs...
  39. ** #10. Update 1. Optimize restore sgpr by busrt 16 sgprs.
  40. ** #11. Update 1. Add 2 more timestamp for debug version
  41. ** #12. Update 1. Add VGPR SR using DWx4, some case improve and some case drop performance
  42. ** #13. Integ 1. Always use MUBUF for PV trap shader...
  43. ** #14. Update 1. s_buffer_store soft clause...
  44. ** #15. Update 1. PERF - sclar write with glc:0/mtype0 to allow L2 combine. perf improvement a lot.
  45. ** #16. Update 1. PRRF - UNROLL LDS_DMA got 2500cycle save in IP tree
  46. ** #17. Update 1. FUNC - LDS_DMA has issues while ATC, replace with ds_read/buffer_store for save part[TODO restore part]
  47. ** 2. PERF - Save LDS before save VGPR to cover LDS save long latency...
  48. ** #18. Update 1. FUNC - Implicitly estore STATUS.VCCZ, which is not writable by s_setreg_b32
  49. ** 2. FUNC - Handle non-CWSR traps
  50. */
  51. var G8SR_WDMEM_HWREG_OFFSET = 0
  52. var G8SR_WDMEM_SGPR_OFFSET = 128 // in bytes
  53. // Keep definition same as the app shader, These 2 time stamps are part of the app shader... Should before any Save and after restore.
  54. var G8SR_DEBUG_TIMESTAMP = 0
  55. var G8SR_DEBUG_TS_SAVE_D_OFFSET = 40*4 // ts_save_d timestamp offset relative to SGPR_SR_memory_offset
  56. var s_g8sr_ts_save_s = s[34:35] // save start
  57. var s_g8sr_ts_sq_save_msg = s[36:37] // The save shader send SAVEWAVE msg to spi
  58. var s_g8sr_ts_spi_wrexec = s[38:39] // the SPI write the sr address to SQ
  59. var s_g8sr_ts_save_d = s[40:41] // save end
  60. var s_g8sr_ts_restore_s = s[42:43] // restore start
  61. var s_g8sr_ts_restore_d = s[44:45] // restore end
  62. var G8SR_VGPR_SR_IN_DWX4 = 0
  63. var G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4 = 0x00100000 // DWx4 stride is 4*4Bytes
  64. var G8SR_RESTORE_BUF_RSRC_WORD1_STRIDE_DWx4 = G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4
  65. /*************************************************************************/
  66. /* control on how to run the shader */
  67. /*************************************************************************/
  68. //any hack that needs to be made to run this code in EMU (either because various EMU code are not ready or no compute save & restore in EMU run)
  69. var EMU_RUN_HACK = 0
  70. var EMU_RUN_HACK_RESTORE_NORMAL = 0
  71. var EMU_RUN_HACK_SAVE_NORMAL_EXIT = 0
  72. var EMU_RUN_HACK_SAVE_SINGLE_WAVE = 0
  73. var EMU_RUN_HACK_SAVE_FIRST_TIME = 0 //for interrupted restore in which the first save is through EMU_RUN_HACK
  74. var EMU_RUN_HACK_SAVE_FIRST_TIME_TBA_LO = 0 //for interrupted restore in which the first save is through EMU_RUN_HACK
  75. var EMU_RUN_HACK_SAVE_FIRST_TIME_TBA_HI = 0 //for interrupted restore in which the first save is through EMU_RUN_HACK
  76. var SAVE_LDS = 1
  77. var WG_BASE_ADDR_LO = 0x9000a000
  78. var WG_BASE_ADDR_HI = 0x0
  79. var WAVE_SPACE = 0x5000 //memory size that each wave occupies in workgroup state mem
  80. var CTX_SAVE_CONTROL = 0x0
  81. var CTX_RESTORE_CONTROL = CTX_SAVE_CONTROL
  82. var SIM_RUN_HACK = 0 //any hack that needs to be made to run this code in SIM (either because various RTL code are not ready or no compute save & restore in RTL run)
  83. var SGPR_SAVE_USE_SQC = 1 //use SQC D$ to do the write
  84. var USE_MTBUF_INSTEAD_OF_MUBUF = 0 //because TC EMU currently asserts on 0 of // overload DFMT field to carry 4 more bits of stride for MUBUF opcodes
  85. var SWIZZLE_EN = 0 //whether we use swizzled buffer addressing
  86. /**************************************************************************/
  87. /* variables */
  88. /**************************************************************************/
  89. var SQ_WAVE_STATUS_INST_ATC_SHIFT = 23
  90. var SQ_WAVE_STATUS_INST_ATC_MASK = 0x00800000
  91. var SQ_WAVE_STATUS_SPI_PRIO_MASK = 0x00000006
  92. var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT = 12
  93. var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE = 9
  94. var SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT = 8
  95. var SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE = 6
  96. var SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT = 24
  97. var SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE = 3 //FIXME sq.blk still has 4 bits at this time while SQ programming guide has 3 bits
  98. var SQ_WAVE_TRAPSTS_SAVECTX_MASK = 0x400
  99. var SQ_WAVE_TRAPSTS_EXCE_MASK = 0x1FF // Exception mask
  100. var SQ_WAVE_TRAPSTS_SAVECTX_SHIFT = 10
  101. var SQ_WAVE_TRAPSTS_MEM_VIOL_MASK = 0x100
  102. var SQ_WAVE_TRAPSTS_MEM_VIOL_SHIFT = 8
  103. var SQ_WAVE_TRAPSTS_PRE_SAVECTX_MASK = 0x3FF
  104. var SQ_WAVE_TRAPSTS_PRE_SAVECTX_SHIFT = 0x0
  105. var SQ_WAVE_TRAPSTS_PRE_SAVECTX_SIZE = 10
  106. var SQ_WAVE_TRAPSTS_POST_SAVECTX_MASK = 0xFFFFF800
  107. var SQ_WAVE_TRAPSTS_POST_SAVECTX_SHIFT = 11
  108. var SQ_WAVE_TRAPSTS_POST_SAVECTX_SIZE = 21
  109. var SQ_WAVE_IB_STS_RCNT_SHIFT = 16 //FIXME
  110. var SQ_WAVE_IB_STS_RCNT_SIZE = 4 //FIXME
  111. var SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT = 15 //FIXME
  112. var SQ_WAVE_IB_STS_FIRST_REPLAY_SIZE = 1 //FIXME
  113. var SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK_NEG = 0x00007FFF //FIXME
  114. var SQ_BUF_RSRC_WORD1_ATC_SHIFT = 24
  115. var SQ_BUF_RSRC_WORD3_MTYPE_SHIFT = 27
  116. /* Save */
  117. var S_SAVE_BUF_RSRC_WORD1_STRIDE = 0x00040000 //stride is 4 bytes
  118. var S_SAVE_BUF_RSRC_WORD3_MISC = 0x00807FAC //SQ_SEL_X/Y/Z/W, BUF_NUM_FORMAT_FLOAT, (0 for MUBUF stride[17:14] when ADD_TID_ENABLE and BUF_DATA_FORMAT_32 for MTBUF), ADD_TID_ENABLE
  119. var S_SAVE_SPI_INIT_ATC_MASK = 0x08000000 //bit[27]: ATC bit
  120. var S_SAVE_SPI_INIT_ATC_SHIFT = 27
  121. var S_SAVE_SPI_INIT_MTYPE_MASK = 0x70000000 //bit[30:28]: Mtype
  122. var S_SAVE_SPI_INIT_MTYPE_SHIFT = 28
  123. var S_SAVE_SPI_INIT_FIRST_WAVE_MASK = 0x04000000 //bit[26]: FirstWaveInTG
  124. var S_SAVE_SPI_INIT_FIRST_WAVE_SHIFT = 26
  125. var S_SAVE_PC_HI_RCNT_SHIFT = 28 //FIXME check with Brian to ensure all fields other than PC[47:0] can be used
  126. var S_SAVE_PC_HI_RCNT_MASK = 0xF0000000 //FIXME
  127. var S_SAVE_PC_HI_FIRST_REPLAY_SHIFT = 27 //FIXME
  128. var S_SAVE_PC_HI_FIRST_REPLAY_MASK = 0x08000000 //FIXME
  129. var s_save_spi_init_lo = exec_lo
  130. var s_save_spi_init_hi = exec_hi
  131. //tba_lo and tba_hi need to be saved/restored
  132. var s_save_pc_lo = ttmp0 //{TTMP1, TTMP0} = {3??h0,pc_rewind[3:0], HT[0],trapID[7:0], PC[47:0]}
  133. var s_save_pc_hi = ttmp1
  134. var s_save_exec_lo = ttmp2
  135. var s_save_exec_hi = ttmp3
  136. var s_save_status = ttmp4
  137. var s_save_trapsts = ttmp5 //not really used until the end of the SAVE routine
  138. var s_save_xnack_mask_lo = ttmp6
  139. var s_save_xnack_mask_hi = ttmp7
  140. var s_save_buf_rsrc0 = ttmp8
  141. var s_save_buf_rsrc1 = ttmp9
  142. var s_save_buf_rsrc2 = ttmp10
  143. var s_save_buf_rsrc3 = ttmp11
  144. var s_save_mem_offset = tma_lo
  145. var s_save_alloc_size = s_save_trapsts //conflict
  146. var s_save_tmp = s_save_buf_rsrc2 //shared with s_save_buf_rsrc2 (conflict: should not use mem access with s_save_tmp at the same time)
  147. var s_save_m0 = tma_hi
  148. /* Restore */
  149. var S_RESTORE_BUF_RSRC_WORD1_STRIDE = S_SAVE_BUF_RSRC_WORD1_STRIDE
  150. var S_RESTORE_BUF_RSRC_WORD3_MISC = S_SAVE_BUF_RSRC_WORD3_MISC
  151. var S_RESTORE_SPI_INIT_ATC_MASK = 0x08000000 //bit[27]: ATC bit
  152. var S_RESTORE_SPI_INIT_ATC_SHIFT = 27
  153. var S_RESTORE_SPI_INIT_MTYPE_MASK = 0x70000000 //bit[30:28]: Mtype
  154. var S_RESTORE_SPI_INIT_MTYPE_SHIFT = 28
  155. var S_RESTORE_SPI_INIT_FIRST_WAVE_MASK = 0x04000000 //bit[26]: FirstWaveInTG
  156. var S_RESTORE_SPI_INIT_FIRST_WAVE_SHIFT = 26
  157. var S_RESTORE_PC_HI_RCNT_SHIFT = S_SAVE_PC_HI_RCNT_SHIFT
  158. var S_RESTORE_PC_HI_RCNT_MASK = S_SAVE_PC_HI_RCNT_MASK
  159. var S_RESTORE_PC_HI_FIRST_REPLAY_SHIFT = S_SAVE_PC_HI_FIRST_REPLAY_SHIFT
  160. var S_RESTORE_PC_HI_FIRST_REPLAY_MASK = S_SAVE_PC_HI_FIRST_REPLAY_MASK
  161. var s_restore_spi_init_lo = exec_lo
  162. var s_restore_spi_init_hi = exec_hi
  163. var s_restore_mem_offset = ttmp2
  164. var s_restore_alloc_size = ttmp3
  165. var s_restore_tmp = ttmp6 //tba_lo/hi need to be restored
  166. var s_restore_mem_offset_save = s_restore_tmp //no conflict
  167. var s_restore_m0 = s_restore_alloc_size //no conflict
  168. var s_restore_mode = ttmp7
  169. var s_restore_pc_lo = ttmp0
  170. var s_restore_pc_hi = ttmp1
  171. var s_restore_exec_lo = tma_lo //no conflict
  172. var s_restore_exec_hi = tma_hi //no conflict
  173. var s_restore_status = ttmp4
  174. var s_restore_trapsts = ttmp5
  175. var s_restore_xnack_mask_lo = xnack_mask_lo
  176. var s_restore_xnack_mask_hi = xnack_mask_hi
  177. var s_restore_buf_rsrc0 = ttmp8
  178. var s_restore_buf_rsrc1 = ttmp9
  179. var s_restore_buf_rsrc2 = ttmp10
  180. var s_restore_buf_rsrc3 = ttmp11
  181. /**************************************************************************/
  182. /* trap handler entry points */
  183. /**************************************************************************/
  184. /* Shader Main*/
  185. shader main
  186. asic(VI)
  187. type(CS)
  188. if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL)) //hack to use trap_id for determining save/restore
  189. //FIXME VCCZ un-init assertion s_getreg_b32 s_save_status, hwreg(HW_REG_STATUS) //save STATUS since we will change SCC
  190. s_and_b32 s_save_tmp, s_save_pc_hi, 0xffff0000 //change SCC
  191. s_cmp_eq_u32 s_save_tmp, 0x007e0000 //Save: trap_id = 0x7e. Restore: trap_id = 0x7f.
  192. s_cbranch_scc0 L_JUMP_TO_RESTORE //do not need to recover STATUS here since we are going to RESTORE
  193. //FIXME s_setreg_b32 hwreg(HW_REG_STATUS), s_save_status //need to recover STATUS since we are going to SAVE
  194. s_branch L_SKIP_RESTORE //NOT restore, SAVE actually
  195. else
  196. s_branch L_SKIP_RESTORE //NOT restore. might be a regular trap or save
  197. end
  198. L_JUMP_TO_RESTORE:
  199. s_branch L_RESTORE //restore
  200. L_SKIP_RESTORE:
  201. s_getreg_b32 s_save_status, hwreg(HW_REG_STATUS) //save STATUS since we will change SCC
  202. s_andn2_b32 s_save_status, s_save_status, SQ_WAVE_STATUS_SPI_PRIO_MASK //check whether this is for save
  203. s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
  204. s_and_b32 s_save_trapsts, s_save_trapsts, SQ_WAVE_TRAPSTS_SAVECTX_MASK //check whether this is for save
  205. s_cbranch_scc1 L_SAVE //this is the operation for save
  206. // ********* Handle non-CWSR traps *******************
  207. if (!EMU_RUN_HACK)
  208. /* read tba and tma for next level trap handler, ttmp4 is used as s_save_status */
  209. s_load_dwordx4 [ttmp8,ttmp9,ttmp10, ttmp11], [tma_lo,tma_hi], 0
  210. s_waitcnt lgkmcnt(0)
  211. s_or_b32 ttmp7, ttmp8, ttmp9
  212. s_cbranch_scc0 L_NO_NEXT_TRAP //next level trap handler not been set
  213. s_setreg_b32 hwreg(HW_REG_STATUS), s_save_status //restore HW status(SCC)
  214. s_setpc_b64 [ttmp8,ttmp9] //jump to next level trap handler
  215. L_NO_NEXT_TRAP:
  216. s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
  217. s_and_b32 s_save_trapsts, s_save_trapsts, SQ_WAVE_TRAPSTS_EXCE_MASK // Check whether it is an exception
  218. s_cbranch_scc1 L_EXCP_CASE // Exception, jump back to the shader program directly.
  219. s_add_u32 ttmp0, ttmp0, 4 // S_TRAP case, add 4 to ttmp0
  220. s_addc_u32 ttmp1, ttmp1, 0
  221. L_EXCP_CASE:
  222. s_and_b32 ttmp1, ttmp1, 0xFFFF
  223. s_setreg_b32 hwreg(HW_REG_STATUS), s_save_status //restore HW status(SCC)
  224. s_rfe_b64 [ttmp0, ttmp1]
  225. end
  226. // ********* End handling of non-CWSR traps *******************
  227. /**************************************************************************/
  228. /* save routine */
  229. /**************************************************************************/
  230. L_SAVE:
  231. if G8SR_DEBUG_TIMESTAMP
  232. s_memrealtime s_g8sr_ts_save_s
  233. s_waitcnt lgkmcnt(0) //FIXME, will cause xnack??
  234. end
  235. //check whether there is mem_viol
  236. s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
  237. s_and_b32 s_save_trapsts, s_save_trapsts, SQ_WAVE_TRAPSTS_MEM_VIOL_MASK
  238. s_cbranch_scc0 L_NO_PC_REWIND
  239. //if so, need rewind PC assuming GDS operation gets NACKed
  240. s_mov_b32 s_save_tmp, 0 //clear mem_viol bit
  241. s_setreg_b32 hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_MEM_VIOL_SHIFT, 1), s_save_tmp //clear mem_viol bit
  242. s_and_b32 s_save_pc_hi, s_save_pc_hi, 0x0000ffff //pc[47:32]
  243. s_sub_u32 s_save_pc_lo, s_save_pc_lo, 8 //pc[31:0]-8
  244. s_subb_u32 s_save_pc_hi, s_save_pc_hi, 0x0 // -scc
  245. L_NO_PC_REWIND:
  246. s_mov_b32 s_save_tmp, 0 //clear saveCtx bit
  247. s_setreg_b32 hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_SAVECTX_SHIFT, 1), s_save_tmp //clear saveCtx bit
  248. s_mov_b32 s_save_xnack_mask_lo, xnack_mask_lo //save XNACK_MASK
  249. s_mov_b32 s_save_xnack_mask_hi, xnack_mask_hi //save XNACK must before any memory operation
  250. s_getreg_b32 s_save_tmp, hwreg(HW_REG_IB_STS, SQ_WAVE_IB_STS_RCNT_SHIFT, SQ_WAVE_IB_STS_RCNT_SIZE) //save RCNT
  251. s_lshl_b32 s_save_tmp, s_save_tmp, S_SAVE_PC_HI_RCNT_SHIFT
  252. s_or_b32 s_save_pc_hi, s_save_pc_hi, s_save_tmp
  253. s_getreg_b32 s_save_tmp, hwreg(HW_REG_IB_STS, SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT, SQ_WAVE_IB_STS_FIRST_REPLAY_SIZE) //save FIRST_REPLAY
  254. s_lshl_b32 s_save_tmp, s_save_tmp, S_SAVE_PC_HI_FIRST_REPLAY_SHIFT
  255. s_or_b32 s_save_pc_hi, s_save_pc_hi, s_save_tmp
  256. s_getreg_b32 s_save_tmp, hwreg(HW_REG_IB_STS) //clear RCNT and FIRST_REPLAY in IB_STS
  257. s_and_b32 s_save_tmp, s_save_tmp, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK_NEG
  258. s_setreg_b32 hwreg(HW_REG_IB_STS), s_save_tmp
  259. /* inform SPI the readiness and wait for SPI's go signal */
  260. s_mov_b32 s_save_exec_lo, exec_lo //save EXEC and use EXEC for the go signal from SPI
  261. s_mov_b32 s_save_exec_hi, exec_hi
  262. s_mov_b64 exec, 0x0 //clear EXEC to get ready to receive
  263. if G8SR_DEBUG_TIMESTAMP
  264. s_memrealtime s_g8sr_ts_sq_save_msg
  265. s_waitcnt lgkmcnt(0)
  266. end
  267. if (EMU_RUN_HACK)
  268. else
  269. s_sendmsg sendmsg(MSG_SAVEWAVE) //send SPI a message and wait for SPI's write to EXEC
  270. end
  271. L_SLEEP:
  272. s_sleep 0x2 // sleep 1 (64clk) is not enough for 8 waves per SIMD, which will cause SQ hang, since the 7,8th wave could not get arbit to exec inst, while other waves are stuck into the sleep-loop and waiting for wrexec!=0
  273. if (EMU_RUN_HACK)
  274. else
  275. s_cbranch_execz L_SLEEP
  276. end
  277. if G8SR_DEBUG_TIMESTAMP
  278. s_memrealtime s_g8sr_ts_spi_wrexec
  279. s_waitcnt lgkmcnt(0)
  280. end
  281. /* setup Resource Contants */
  282. if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_SAVE_SINGLE_WAVE))
  283. //calculate wd_addr using absolute thread id
  284. v_readlane_b32 s_save_tmp, v9, 0
  285. s_lshr_b32 s_save_tmp, s_save_tmp, 6
  286. s_mul_i32 s_save_tmp, s_save_tmp, WAVE_SPACE
  287. s_add_i32 s_save_spi_init_lo, s_save_tmp, WG_BASE_ADDR_LO
  288. s_mov_b32 s_save_spi_init_hi, WG_BASE_ADDR_HI
  289. s_and_b32 s_save_spi_init_hi, s_save_spi_init_hi, CTX_SAVE_CONTROL
  290. else
  291. end
  292. if ((EMU_RUN_HACK) && (EMU_RUN_HACK_SAVE_SINGLE_WAVE))
  293. s_add_i32 s_save_spi_init_lo, s_save_tmp, WG_BASE_ADDR_LO
  294. s_mov_b32 s_save_spi_init_hi, WG_BASE_ADDR_HI
  295. s_and_b32 s_save_spi_init_hi, s_save_spi_init_hi, CTX_SAVE_CONTROL
  296. else
  297. end
  298. s_mov_b32 s_save_buf_rsrc0, s_save_spi_init_lo //base_addr_lo
  299. s_and_b32 s_save_buf_rsrc1, s_save_spi_init_hi, 0x0000FFFF //base_addr_hi
  300. s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, S_SAVE_BUF_RSRC_WORD1_STRIDE
  301. s_mov_b32 s_save_buf_rsrc2, 0 //NUM_RECORDS initial value = 0 (in bytes) although not neccessarily inited
  302. s_mov_b32 s_save_buf_rsrc3, S_SAVE_BUF_RSRC_WORD3_MISC
  303. s_and_b32 s_save_tmp, s_save_spi_init_hi, S_SAVE_SPI_INIT_ATC_MASK
  304. s_lshr_b32 s_save_tmp, s_save_tmp, (S_SAVE_SPI_INIT_ATC_SHIFT-SQ_BUF_RSRC_WORD1_ATC_SHIFT) //get ATC bit into position
  305. s_or_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, s_save_tmp //or ATC
  306. s_and_b32 s_save_tmp, s_save_spi_init_hi, S_SAVE_SPI_INIT_MTYPE_MASK
  307. s_lshr_b32 s_save_tmp, s_save_tmp, (S_SAVE_SPI_INIT_MTYPE_SHIFT-SQ_BUF_RSRC_WORD3_MTYPE_SHIFT) //get MTYPE bits into position
  308. s_or_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, s_save_tmp //or MTYPE
  309. //FIXME right now s_save_m0/s_save_mem_offset use tma_lo/tma_hi (might need to save them before using them?)
  310. s_mov_b32 s_save_m0, m0 //save M0
  311. /* global mem offset */
  312. s_mov_b32 s_save_mem_offset, 0x0 //mem offset initial value = 0
  313. /* save HW registers */
  314. //////////////////////////////
  315. L_SAVE_HWREG:
  316. // HWREG SR memory offset : size(VGPR)+size(SGPR)
  317. get_vgpr_size_bytes(s_save_mem_offset)
  318. get_sgpr_size_bytes(s_save_tmp)
  319. s_add_u32 s_save_mem_offset, s_save_mem_offset, s_save_tmp
  320. s_mov_b32 s_save_buf_rsrc2, 0x4 //NUM_RECORDS in bytes
  321. if (SWIZZLE_EN)
  322. s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  323. else
  324. s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  325. end
  326. write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset) //M0
  327. if ((EMU_RUN_HACK) && (EMU_RUN_HACK_SAVE_FIRST_TIME))
  328. s_add_u32 s_save_pc_lo, s_save_pc_lo, 4 //pc[31:0]+4
  329. s_addc_u32 s_save_pc_hi, s_save_pc_hi, 0x0 //carry bit over
  330. s_mov_b32 tba_lo, EMU_RUN_HACK_SAVE_FIRST_TIME_TBA_LO
  331. s_mov_b32 tba_hi, EMU_RUN_HACK_SAVE_FIRST_TIME_TBA_HI
  332. end
  333. write_hwreg_to_mem(s_save_pc_lo, s_save_buf_rsrc0, s_save_mem_offset) //PC
  334. write_hwreg_to_mem(s_save_pc_hi, s_save_buf_rsrc0, s_save_mem_offset)
  335. write_hwreg_to_mem(s_save_exec_lo, s_save_buf_rsrc0, s_save_mem_offset) //EXEC
  336. write_hwreg_to_mem(s_save_exec_hi, s_save_buf_rsrc0, s_save_mem_offset)
  337. write_hwreg_to_mem(s_save_status, s_save_buf_rsrc0, s_save_mem_offset) //STATUS
  338. //s_save_trapsts conflicts with s_save_alloc_size
  339. s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
  340. write_hwreg_to_mem(s_save_trapsts, s_save_buf_rsrc0, s_save_mem_offset) //TRAPSTS
  341. write_hwreg_to_mem(s_save_xnack_mask_lo, s_save_buf_rsrc0, s_save_mem_offset) //XNACK_MASK_LO
  342. write_hwreg_to_mem(s_save_xnack_mask_hi, s_save_buf_rsrc0, s_save_mem_offset) //XNACK_MASK_HI
  343. //use s_save_tmp would introduce conflict here between s_save_tmp and s_save_buf_rsrc2
  344. s_getreg_b32 s_save_m0, hwreg(HW_REG_MODE) //MODE
  345. write_hwreg_to_mem(s_save_m0, s_save_buf_rsrc0, s_save_mem_offset)
  346. write_hwreg_to_mem(tba_lo, s_save_buf_rsrc0, s_save_mem_offset) //TBA_LO
  347. write_hwreg_to_mem(tba_hi, s_save_buf_rsrc0, s_save_mem_offset) //TBA_HI
  348. /* the first wave in the threadgroup */
  349. // save fist_wave bits in tba_hi unused bit.26
  350. s_and_b32 s_save_tmp, s_save_spi_init_hi, S_SAVE_SPI_INIT_FIRST_WAVE_MASK // extract fisrt wave bit
  351. //s_or_b32 tba_hi, s_save_tmp, tba_hi // save first wave bit to tba_hi.bits[26]
  352. s_mov_b32 s_save_exec_hi, 0x0
  353. s_or_b32 s_save_exec_hi, s_save_tmp, s_save_exec_hi // save first wave bit to s_save_exec_hi.bits[26]
  354. /* save SGPRs */
  355. // Save SGPR before LDS save, then the s0 to s4 can be used during LDS save...
  356. //////////////////////////////
  357. // SGPR SR memory offset : size(VGPR)
  358. get_vgpr_size_bytes(s_save_mem_offset)
  359. // TODO, change RSRC word to rearrange memory layout for SGPRS
  360. s_getreg_b32 s_save_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE) //spgr_size
  361. s_add_u32 s_save_alloc_size, s_save_alloc_size, 1
  362. s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 4 //Number of SGPRs = (sgpr_size + 1) * 16 (non-zero value)
  363. if (SGPR_SAVE_USE_SQC)
  364. s_lshl_b32 s_save_buf_rsrc2, s_save_alloc_size, 2 //NUM_RECORDS in bytes
  365. else
  366. s_lshl_b32 s_save_buf_rsrc2, s_save_alloc_size, 8 //NUM_RECORDS in bytes (64 threads)
  367. end
  368. if (SWIZZLE_EN)
  369. s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  370. else
  371. s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  372. end
  373. // backup s_save_buf_rsrc0,1 to s_save_pc_lo/hi, since write_16sgpr_to_mem function will change the rsrc0
  374. //s_mov_b64 s_save_pc_lo, s_save_buf_rsrc0
  375. s_mov_b64 s_save_xnack_mask_lo, s_save_buf_rsrc0
  376. s_add_u32 s_save_buf_rsrc0, s_save_buf_rsrc0, s_save_mem_offset
  377. s_addc_u32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0
  378. s_mov_b32 m0, 0x0 //SGPR initial index value =0
  379. L_SAVE_SGPR_LOOP:
  380. // SGPR is allocated in 16 SGPR granularity
  381. s_movrels_b64 s0, s0 //s0 = s[0+m0], s1 = s[1+m0]
  382. s_movrels_b64 s2, s2 //s2 = s[2+m0], s3 = s[3+m0]
  383. s_movrels_b64 s4, s4 //s4 = s[4+m0], s5 = s[5+m0]
  384. s_movrels_b64 s6, s6 //s6 = s[6+m0], s7 = s[7+m0]
  385. s_movrels_b64 s8, s8 //s8 = s[8+m0], s9 = s[9+m0]
  386. s_movrels_b64 s10, s10 //s10 = s[10+m0], s11 = s[11+m0]
  387. s_movrels_b64 s12, s12 //s12 = s[12+m0], s13 = s[13+m0]
  388. s_movrels_b64 s14, s14 //s14 = s[14+m0], s15 = s[15+m0]
  389. write_16sgpr_to_mem(s0, s_save_buf_rsrc0, s_save_mem_offset) //PV: the best performance should be using s_buffer_store_dwordx4
  390. s_add_u32 m0, m0, 16 //next sgpr index
  391. s_cmp_lt_u32 m0, s_save_alloc_size //scc = (m0 < s_save_alloc_size) ? 1 : 0
  392. s_cbranch_scc1 L_SAVE_SGPR_LOOP //SGPR save is complete?
  393. // restore s_save_buf_rsrc0,1
  394. //s_mov_b64 s_save_buf_rsrc0, s_save_pc_lo
  395. s_mov_b64 s_save_buf_rsrc0, s_save_xnack_mask_lo
  396. /* save first 4 VGPR, then LDS save could use */
  397. // each wave will alloc 4 vgprs at least...
  398. /////////////////////////////////////////////////////////////////////////////////////
  399. s_mov_b32 s_save_mem_offset, 0
  400. s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on
  401. s_mov_b32 exec_hi, 0xFFFFFFFF
  402. if (SWIZZLE_EN)
  403. s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  404. else
  405. s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  406. end
  407. // VGPR Allocated in 4-GPR granularity
  408. if G8SR_VGPR_SR_IN_DWX4
  409. // the const stride for DWx4 is 4*4 bytes
  410. s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
  411. s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4 // const stride to 4*4 bytes
  412. buffer_store_dwordx4 v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
  413. s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
  414. s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, S_SAVE_BUF_RSRC_WORD1_STRIDE // reset const stride to 4 bytes
  415. else
  416. buffer_store_dword v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
  417. buffer_store_dword v1, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256
  418. buffer_store_dword v2, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*2
  419. buffer_store_dword v3, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*3
  420. end
  421. /* save LDS */
  422. //////////////////////////////
  423. L_SAVE_LDS:
  424. // Change EXEC to all threads...
  425. s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on
  426. s_mov_b32 exec_hi, 0xFFFFFFFF
  427. s_getreg_b32 s_save_alloc_size, hwreg(HW_REG_LDS_ALLOC,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE) //lds_size
  428. s_and_b32 s_save_alloc_size, s_save_alloc_size, 0xFFFFFFFF //lds_size is zero?
  429. s_cbranch_scc0 L_SAVE_LDS_DONE //no lds used? jump to L_SAVE_DONE
  430. s_barrier //LDS is used? wait for other waves in the same TG
  431. //s_and_b32 s_save_tmp, tba_hi, S_SAVE_SPI_INIT_FIRST_WAVE_MASK //exec is still used here
  432. s_and_b32 s_save_tmp, s_save_exec_hi, S_SAVE_SPI_INIT_FIRST_WAVE_MASK //exec is still used here
  433. s_cbranch_scc0 L_SAVE_LDS_DONE
  434. // first wave do LDS save;
  435. s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 6 //LDS size in dwords = lds_size * 64dw
  436. s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 2 //LDS size in bytes
  437. s_mov_b32 s_save_buf_rsrc2, s_save_alloc_size //NUM_RECORDS in bytes
  438. // LDS at offset: size(VGPR)+SIZE(SGPR)+SIZE(HWREG)
  439. //
  440. get_vgpr_size_bytes(s_save_mem_offset)
  441. get_sgpr_size_bytes(s_save_tmp)
  442. s_add_u32 s_save_mem_offset, s_save_mem_offset, s_save_tmp
  443. s_add_u32 s_save_mem_offset, s_save_mem_offset, get_hwreg_size_bytes()
  444. if (SWIZZLE_EN)
  445. s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  446. else
  447. s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  448. end
  449. s_mov_b32 m0, 0x0 //lds_offset initial value = 0
  450. var LDS_DMA_ENABLE = 0
  451. var UNROLL = 0
  452. if UNROLL==0 && LDS_DMA_ENABLE==1
  453. s_mov_b32 s3, 256*2
  454. s_nop 0
  455. s_nop 0
  456. s_nop 0
  457. L_SAVE_LDS_LOOP:
  458. //TODO: looks the 2 buffer_store/load clause for s/r will hurt performance.???
  459. if (SAVE_LDS) //SPI always alloc LDS space in 128DW granularity
  460. buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 // first 64DW
  461. buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 offset:256 // second 64DW
  462. end
  463. s_add_u32 m0, m0, s3 //every buffer_store_lds does 256 bytes
  464. s_add_u32 s_save_mem_offset, s_save_mem_offset, s3 //mem offset increased by 256 bytes
  465. s_cmp_lt_u32 m0, s_save_alloc_size //scc=(m0 < s_save_alloc_size) ? 1 : 0
  466. s_cbranch_scc1 L_SAVE_LDS_LOOP //LDS save is complete?
  467. elsif LDS_DMA_ENABLE==1 && UNROLL==1 // UNROOL , has ichace miss
  468. // store from higest LDS address to lowest
  469. s_mov_b32 s3, 256*2
  470. s_sub_u32 m0, s_save_alloc_size, s3
  471. s_add_u32 s_save_mem_offset, s_save_mem_offset, m0
  472. s_lshr_b32 s_save_alloc_size, s_save_alloc_size, 9 // how many 128 trunks...
  473. s_sub_u32 s_save_alloc_size, 128, s_save_alloc_size // store from higheset addr to lowest
  474. s_mul_i32 s_save_alloc_size, s_save_alloc_size, 6*4 // PC offset increment, each LDS save block cost 6*4 Bytes instruction
  475. s_add_u32 s_save_alloc_size, s_save_alloc_size, 3*4 //2is the below 2 inst...//s_addc and s_setpc
  476. s_nop 0
  477. s_nop 0
  478. s_nop 0 //pad 3 dw to let LDS_DMA align with 64Bytes
  479. s_getpc_b64 s[0:1] // reuse s[0:1], since s[0:1] already saved
  480. s_add_u32 s0, s0,s_save_alloc_size
  481. s_addc_u32 s1, s1, 0
  482. s_setpc_b64 s[0:1]
  483. for var i =0; i< 128; i++
  484. // be careful to make here a 64Byte aligned address, which could improve performance...
  485. buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 offset:0 // first 64DW
  486. buffer_store_lds_dword s_save_buf_rsrc0, s_save_mem_offset lds:1 offset:256 // second 64DW
  487. if i!=127
  488. s_sub_u32 m0, m0, s3 // use a sgpr to shrink 2DW-inst to 1DW inst to improve performance , i.e. pack more LDS_DMA inst to one Cacheline
  489. s_sub_u32 s_save_mem_offset, s_save_mem_offset, s3
  490. end
  491. end
  492. else // BUFFER_STORE
  493. v_mbcnt_lo_u32_b32 v2, 0xffffffff, 0x0
  494. v_mbcnt_hi_u32_b32 v3, 0xffffffff, v2 // tid
  495. v_mul_i32_i24 v2, v3, 8 // tid*8
  496. v_mov_b32 v3, 256*2
  497. s_mov_b32 m0, 0x10000
  498. s_mov_b32 s0, s_save_buf_rsrc3
  499. s_and_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, 0xFF7FFFFF // disable add_tid
  500. s_or_b32 s_save_buf_rsrc3, s_save_buf_rsrc3, 0x58000 //DFMT
  501. L_SAVE_LDS_LOOP_VECTOR:
  502. ds_read_b64 v[0:1], v2 //x =LDS[a], byte address
  503. s_waitcnt lgkmcnt(0)
  504. buffer_store_dwordx2 v[0:1], v2, s_save_buf_rsrc0, s_save_mem_offset offen:1 glc:1 slc:1
  505. // s_waitcnt vmcnt(0)
  506. v_add_u32 v2, vcc[0:1], v2, v3
  507. v_cmp_lt_u32 vcc[0:1], v2, s_save_alloc_size
  508. s_cbranch_vccnz L_SAVE_LDS_LOOP_VECTOR
  509. // restore rsrc3
  510. s_mov_b32 s_save_buf_rsrc3, s0
  511. end
  512. L_SAVE_LDS_DONE:
  513. /* save VGPRs - set the Rest VGPRs */
  514. //////////////////////////////////////////////////////////////////////////////////////
  515. L_SAVE_VGPR:
  516. // VGPR SR memory offset: 0
  517. // TODO rearrange the RSRC words to use swizzle for VGPR save...
  518. s_mov_b32 s_save_mem_offset, (0+256*4) // for the rest VGPRs
  519. s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on
  520. s_mov_b32 exec_hi, 0xFFFFFFFF
  521. s_getreg_b32 s_save_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE) //vpgr_size
  522. s_add_u32 s_save_alloc_size, s_save_alloc_size, 1
  523. s_lshl_b32 s_save_alloc_size, s_save_alloc_size, 2 //Number of VGPRs = (vgpr_size + 1) * 4 (non-zero value) //FIXME for GFX, zero is possible
  524. s_lshl_b32 s_save_buf_rsrc2, s_save_alloc_size, 8 //NUM_RECORDS in bytes (64 threads*4)
  525. if (SWIZZLE_EN)
  526. s_add_u32 s_save_buf_rsrc2, s_save_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  527. else
  528. s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  529. end
  530. // VGPR Allocated in 4-GPR granularity
  531. if G8SR_VGPR_SR_IN_DWX4
  532. // the const stride for DWx4 is 4*4 bytes
  533. s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
  534. s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, G8SR_SAVE_BUF_RSRC_WORD1_STRIDE_DWx4 // const stride to 4*4 bytes
  535. s_mov_b32 m0, 4 // skip first 4 VGPRs
  536. s_cmp_lt_u32 m0, s_save_alloc_size
  537. s_cbranch_scc0 L_SAVE_VGPR_LOOP_END // no more vgprs
  538. s_set_gpr_idx_on m0, 0x1 // This will change M0
  539. s_add_u32 s_save_alloc_size, s_save_alloc_size, 0x1000 // because above inst change m0
  540. L_SAVE_VGPR_LOOP:
  541. v_mov_b32 v0, v0 // v0 = v[0+m0]
  542. v_mov_b32 v1, v1
  543. v_mov_b32 v2, v2
  544. v_mov_b32 v3, v3
  545. buffer_store_dwordx4 v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
  546. s_add_u32 m0, m0, 4
  547. s_add_u32 s_save_mem_offset, s_save_mem_offset, 256*4
  548. s_cmp_lt_u32 m0, s_save_alloc_size
  549. s_cbranch_scc1 L_SAVE_VGPR_LOOP //VGPR save is complete?
  550. s_set_gpr_idx_off
  551. L_SAVE_VGPR_LOOP_END:
  552. s_and_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, 0x0000FFFF // reset const stride to 0
  553. s_or_b32 s_save_buf_rsrc1, s_save_buf_rsrc1, S_SAVE_BUF_RSRC_WORD1_STRIDE // reset const stride to 4 bytes
  554. else
  555. // VGPR store using dw burst
  556. s_mov_b32 m0, 0x4 //VGPR initial index value =0
  557. s_cmp_lt_u32 m0, s_save_alloc_size
  558. s_cbranch_scc0 L_SAVE_VGPR_END
  559. s_set_gpr_idx_on m0, 0x1 //M0[7:0] = M0[7:0] and M0[15:12] = 0x1
  560. s_add_u32 s_save_alloc_size, s_save_alloc_size, 0x1000 //add 0x1000 since we compare m0 against it later
  561. L_SAVE_VGPR_LOOP:
  562. v_mov_b32 v0, v0 //v0 = v[0+m0]
  563. v_mov_b32 v1, v1 //v0 = v[0+m0]
  564. v_mov_b32 v2, v2 //v0 = v[0+m0]
  565. v_mov_b32 v3, v3 //v0 = v[0+m0]
  566. if(USE_MTBUF_INSTEAD_OF_MUBUF)
  567. tbuffer_store_format_x v0, v0, s_save_buf_rsrc0, s_save_mem_offset format:BUF_NUM_FORMAT_FLOAT format: BUF_DATA_FORMAT_32 slc:1 glc:1
  568. else
  569. buffer_store_dword v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
  570. buffer_store_dword v1, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256
  571. buffer_store_dword v2, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*2
  572. buffer_store_dword v3, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1 offset:256*3
  573. end
  574. s_add_u32 m0, m0, 4 //next vgpr index
  575. s_add_u32 s_save_mem_offset, s_save_mem_offset, 256*4 //every buffer_store_dword does 256 bytes
  576. s_cmp_lt_u32 m0, s_save_alloc_size //scc = (m0 < s_save_alloc_size) ? 1 : 0
  577. s_cbranch_scc1 L_SAVE_VGPR_LOOP //VGPR save is complete?
  578. s_set_gpr_idx_off
  579. end
  580. L_SAVE_VGPR_END:
  581. /* S_PGM_END_SAVED */ //FIXME graphics ONLY
  582. if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_SAVE_NORMAL_EXIT))
  583. s_and_b32 s_save_pc_hi, s_save_pc_hi, 0x0000ffff //pc[47:32]
  584. s_add_u32 s_save_pc_lo, s_save_pc_lo, 4 //pc[31:0]+4
  585. s_addc_u32 s_save_pc_hi, s_save_pc_hi, 0x0 //carry bit over
  586. s_rfe_b64 s_save_pc_lo //Return to the main shader program
  587. else
  588. end
  589. // Save Done timestamp
  590. if G8SR_DEBUG_TIMESTAMP
  591. s_memrealtime s_g8sr_ts_save_d
  592. // SGPR SR memory offset : size(VGPR)
  593. get_vgpr_size_bytes(s_save_mem_offset)
  594. s_add_u32 s_save_mem_offset, s_save_mem_offset, G8SR_DEBUG_TS_SAVE_D_OFFSET
  595. s_waitcnt lgkmcnt(0) //FIXME, will cause xnack??
  596. // Need reset rsrc2??
  597. s_mov_b32 m0, s_save_mem_offset
  598. s_mov_b32 s_save_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  599. s_buffer_store_dwordx2 s_g8sr_ts_save_d, s_save_buf_rsrc0, m0 glc:1
  600. end
  601. s_branch L_END_PGM
  602. /**************************************************************************/
  603. /* restore routine */
  604. /**************************************************************************/
  605. L_RESTORE:
  606. /* Setup Resource Contants */
  607. if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL))
  608. //calculate wd_addr using absolute thread id
  609. v_readlane_b32 s_restore_tmp, v9, 0
  610. s_lshr_b32 s_restore_tmp, s_restore_tmp, 6
  611. s_mul_i32 s_restore_tmp, s_restore_tmp, WAVE_SPACE
  612. s_add_i32 s_restore_spi_init_lo, s_restore_tmp, WG_BASE_ADDR_LO
  613. s_mov_b32 s_restore_spi_init_hi, WG_BASE_ADDR_HI
  614. s_and_b32 s_restore_spi_init_hi, s_restore_spi_init_hi, CTX_RESTORE_CONTROL
  615. else
  616. end
  617. if G8SR_DEBUG_TIMESTAMP
  618. s_memrealtime s_g8sr_ts_restore_s
  619. s_waitcnt lgkmcnt(0) //FIXME, will cause xnack??
  620. // tma_lo/hi are sgpr 110, 111, which will not used for 112 SGPR allocated case...
  621. s_mov_b32 s_restore_pc_lo, s_g8sr_ts_restore_s[0]
  622. s_mov_b32 s_restore_pc_hi, s_g8sr_ts_restore_s[1] //backup ts to ttmp0/1, sicne exec will be finally restored..
  623. end
  624. s_mov_b32 s_restore_buf_rsrc0, s_restore_spi_init_lo //base_addr_lo
  625. s_and_b32 s_restore_buf_rsrc1, s_restore_spi_init_hi, 0x0000FFFF //base_addr_hi
  626. s_or_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, S_RESTORE_BUF_RSRC_WORD1_STRIDE
  627. s_mov_b32 s_restore_buf_rsrc2, 0 //NUM_RECORDS initial value = 0 (in bytes)
  628. s_mov_b32 s_restore_buf_rsrc3, S_RESTORE_BUF_RSRC_WORD3_MISC
  629. s_and_b32 s_restore_tmp, s_restore_spi_init_hi, S_RESTORE_SPI_INIT_ATC_MASK
  630. s_lshr_b32 s_restore_tmp, s_restore_tmp, (S_RESTORE_SPI_INIT_ATC_SHIFT-SQ_BUF_RSRC_WORD1_ATC_SHIFT) //get ATC bit into position
  631. s_or_b32 s_restore_buf_rsrc3, s_restore_buf_rsrc3, s_restore_tmp //or ATC
  632. s_and_b32 s_restore_tmp, s_restore_spi_init_hi, S_RESTORE_SPI_INIT_MTYPE_MASK
  633. s_lshr_b32 s_restore_tmp, s_restore_tmp, (S_RESTORE_SPI_INIT_MTYPE_SHIFT-SQ_BUF_RSRC_WORD3_MTYPE_SHIFT) //get MTYPE bits into position
  634. s_or_b32 s_restore_buf_rsrc3, s_restore_buf_rsrc3, s_restore_tmp //or MTYPE
  635. /* global mem offset */
  636. // s_mov_b32 s_restore_mem_offset, 0x0 //mem offset initial value = 0
  637. /* the first wave in the threadgroup */
  638. s_and_b32 s_restore_tmp, s_restore_spi_init_hi, S_RESTORE_SPI_INIT_FIRST_WAVE_MASK
  639. s_cbranch_scc0 L_RESTORE_VGPR
  640. /* restore LDS */
  641. //////////////////////////////
  642. L_RESTORE_LDS:
  643. s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on //be consistent with SAVE although can be moved ahead
  644. s_mov_b32 exec_hi, 0xFFFFFFFF
  645. s_getreg_b32 s_restore_alloc_size, hwreg(HW_REG_LDS_ALLOC,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT,SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE) //lds_size
  646. s_and_b32 s_restore_alloc_size, s_restore_alloc_size, 0xFFFFFFFF //lds_size is zero?
  647. s_cbranch_scc0 L_RESTORE_VGPR //no lds used? jump to L_RESTORE_VGPR
  648. s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 6 //LDS size in dwords = lds_size * 64dw
  649. s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 2 //LDS size in bytes
  650. s_mov_b32 s_restore_buf_rsrc2, s_restore_alloc_size //NUM_RECORDS in bytes
  651. // LDS at offset: size(VGPR)+SIZE(SGPR)+SIZE(HWREG)
  652. //
  653. get_vgpr_size_bytes(s_restore_mem_offset)
  654. get_sgpr_size_bytes(s_restore_tmp)
  655. s_add_u32 s_restore_mem_offset, s_restore_mem_offset, s_restore_tmp
  656. s_add_u32 s_restore_mem_offset, s_restore_mem_offset, get_hwreg_size_bytes() //FIXME, Check if offset overflow???
  657. if (SWIZZLE_EN)
  658. s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  659. else
  660. s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  661. end
  662. s_mov_b32 m0, 0x0 //lds_offset initial value = 0
  663. L_RESTORE_LDS_LOOP:
  664. if (SAVE_LDS)
  665. buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset lds:1 // first 64DW
  666. buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset lds:1 offset:256 // second 64DW
  667. end
  668. s_add_u32 m0, m0, 256*2 // 128 DW
  669. s_add_u32 s_restore_mem_offset, s_restore_mem_offset, 256*2 //mem offset increased by 128DW
  670. s_cmp_lt_u32 m0, s_restore_alloc_size //scc=(m0 < s_restore_alloc_size) ? 1 : 0
  671. s_cbranch_scc1 L_RESTORE_LDS_LOOP //LDS restore is complete?
  672. /* restore VGPRs */
  673. //////////////////////////////
  674. L_RESTORE_VGPR:
  675. // VGPR SR memory offset : 0
  676. s_mov_b32 s_restore_mem_offset, 0x0
  677. s_mov_b32 exec_lo, 0xFFFFFFFF //need every thread from now on //be consistent with SAVE although can be moved ahead
  678. s_mov_b32 exec_hi, 0xFFFFFFFF
  679. s_getreg_b32 s_restore_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE) //vpgr_size
  680. s_add_u32 s_restore_alloc_size, s_restore_alloc_size, 1
  681. s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 2 //Number of VGPRs = (vgpr_size + 1) * 4 (non-zero value)
  682. s_lshl_b32 s_restore_buf_rsrc2, s_restore_alloc_size, 8 //NUM_RECORDS in bytes (64 threads*4)
  683. if (SWIZZLE_EN)
  684. s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  685. else
  686. s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  687. end
  688. if G8SR_VGPR_SR_IN_DWX4
  689. get_vgpr_size_bytes(s_restore_mem_offset)
  690. s_sub_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4
  691. // the const stride for DWx4 is 4*4 bytes
  692. s_and_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, 0x0000FFFF // reset const stride to 0
  693. s_or_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, G8SR_RESTORE_BUF_RSRC_WORD1_STRIDE_DWx4 // const stride to 4*4 bytes
  694. s_mov_b32 m0, s_restore_alloc_size
  695. s_set_gpr_idx_on m0, 0x8 // Note.. This will change m0
  696. L_RESTORE_VGPR_LOOP:
  697. buffer_load_dwordx4 v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1
  698. s_waitcnt vmcnt(0)
  699. s_sub_u32 m0, m0, 4
  700. v_mov_b32 v0, v0 // v[0+m0] = v0
  701. v_mov_b32 v1, v1
  702. v_mov_b32 v2, v2
  703. v_mov_b32 v3, v3
  704. s_sub_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4
  705. s_cmp_eq_u32 m0, 0x8000
  706. s_cbranch_scc0 L_RESTORE_VGPR_LOOP
  707. s_set_gpr_idx_off
  708. s_and_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, 0x0000FFFF // reset const stride to 0
  709. s_or_b32 s_restore_buf_rsrc1, s_restore_buf_rsrc1, S_RESTORE_BUF_RSRC_WORD1_STRIDE // const stride to 4*4 bytes
  710. else
  711. // VGPR load using dw burst
  712. s_mov_b32 s_restore_mem_offset_save, s_restore_mem_offset // restore start with v1, v0 will be the last
  713. s_add_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4
  714. s_mov_b32 m0, 4 //VGPR initial index value = 1
  715. s_set_gpr_idx_on m0, 0x8 //M0[7:0] = M0[7:0] and M0[15:12] = 0x8
  716. s_add_u32 s_restore_alloc_size, s_restore_alloc_size, 0x8000 //add 0x8000 since we compare m0 against it later
  717. L_RESTORE_VGPR_LOOP:
  718. if(USE_MTBUF_INSTEAD_OF_MUBUF)
  719. tbuffer_load_format_x v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset format:BUF_NUM_FORMAT_FLOAT format: BUF_DATA_FORMAT_32 slc:1 glc:1
  720. else
  721. buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1
  722. buffer_load_dword v1, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1 offset:256
  723. buffer_load_dword v2, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1 offset:256*2
  724. buffer_load_dword v3, v0, s_restore_buf_rsrc0, s_restore_mem_offset slc:1 glc:1 offset:256*3
  725. end
  726. s_waitcnt vmcnt(0) //ensure data ready
  727. v_mov_b32 v0, v0 //v[0+m0] = v0
  728. v_mov_b32 v1, v1
  729. v_mov_b32 v2, v2
  730. v_mov_b32 v3, v3
  731. s_add_u32 m0, m0, 4 //next vgpr index
  732. s_add_u32 s_restore_mem_offset, s_restore_mem_offset, 256*4 //every buffer_load_dword does 256 bytes
  733. s_cmp_lt_u32 m0, s_restore_alloc_size //scc = (m0 < s_restore_alloc_size) ? 1 : 0
  734. s_cbranch_scc1 L_RESTORE_VGPR_LOOP //VGPR restore (except v0) is complete?
  735. s_set_gpr_idx_off
  736. /* VGPR restore on v0 */
  737. if(USE_MTBUF_INSTEAD_OF_MUBUF)
  738. tbuffer_load_format_x v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save format:BUF_NUM_FORMAT_FLOAT format: BUF_DATA_FORMAT_32 slc:1 glc:1
  739. else
  740. buffer_load_dword v0, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1
  741. buffer_load_dword v1, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256
  742. buffer_load_dword v2, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256*2
  743. buffer_load_dword v3, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256*3
  744. end
  745. end
  746. /* restore SGPRs */
  747. //////////////////////////////
  748. // SGPR SR memory offset : size(VGPR)
  749. get_vgpr_size_bytes(s_restore_mem_offset)
  750. get_sgpr_size_bytes(s_restore_tmp)
  751. s_add_u32 s_restore_mem_offset, s_restore_mem_offset, s_restore_tmp
  752. s_sub_u32 s_restore_mem_offset, s_restore_mem_offset, 16*4 // restore SGPR from S[n] to S[0], by 16 sgprs group
  753. // TODO, change RSRC word to rearrange memory layout for SGPRS
  754. s_getreg_b32 s_restore_alloc_size, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE) //spgr_size
  755. s_add_u32 s_restore_alloc_size, s_restore_alloc_size, 1
  756. s_lshl_b32 s_restore_alloc_size, s_restore_alloc_size, 4 //Number of SGPRs = (sgpr_size + 1) * 16 (non-zero value)
  757. if (SGPR_SAVE_USE_SQC)
  758. s_lshl_b32 s_restore_buf_rsrc2, s_restore_alloc_size, 2 //NUM_RECORDS in bytes
  759. else
  760. s_lshl_b32 s_restore_buf_rsrc2, s_restore_alloc_size, 8 //NUM_RECORDS in bytes (64 threads)
  761. end
  762. if (SWIZZLE_EN)
  763. s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  764. else
  765. s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  766. end
  767. /* If 112 SGPRs ar allocated, 4 sgprs are not used TBA(108,109),TMA(110,111),
  768. However, we are safe to restore these 4 SGPRs anyway, since TBA,TMA will later be restored by HWREG
  769. */
  770. s_mov_b32 m0, s_restore_alloc_size
  771. L_RESTORE_SGPR_LOOP:
  772. read_16sgpr_from_mem(s0, s_restore_buf_rsrc0, s_restore_mem_offset) //PV: further performance improvement can be made
  773. s_waitcnt lgkmcnt(0) //ensure data ready
  774. s_sub_u32 m0, m0, 16 // Restore from S[n] to S[0]
  775. s_movreld_b64 s0, s0 //s[0+m0] = s0
  776. s_movreld_b64 s2, s2
  777. s_movreld_b64 s4, s4
  778. s_movreld_b64 s6, s6
  779. s_movreld_b64 s8, s8
  780. s_movreld_b64 s10, s10
  781. s_movreld_b64 s12, s12
  782. s_movreld_b64 s14, s14
  783. s_cmp_eq_u32 m0, 0 //scc = (m0 < s_restore_alloc_size) ? 1 : 0
  784. s_cbranch_scc0 L_RESTORE_SGPR_LOOP //SGPR restore (except s0) is complete?
  785. /* restore HW registers */
  786. //////////////////////////////
  787. L_RESTORE_HWREG:
  788. if G8SR_DEBUG_TIMESTAMP
  789. s_mov_b32 s_g8sr_ts_restore_s[0], s_restore_pc_lo
  790. s_mov_b32 s_g8sr_ts_restore_s[1], s_restore_pc_hi
  791. end
  792. // HWREG SR memory offset : size(VGPR)+size(SGPR)
  793. get_vgpr_size_bytes(s_restore_mem_offset)
  794. get_sgpr_size_bytes(s_restore_tmp)
  795. s_add_u32 s_restore_mem_offset, s_restore_mem_offset, s_restore_tmp
  796. s_mov_b32 s_restore_buf_rsrc2, 0x4 //NUM_RECORDS in bytes
  797. if (SWIZZLE_EN)
  798. s_add_u32 s_restore_buf_rsrc2, s_restore_buf_rsrc2, 0x0 //FIXME need to use swizzle to enable bounds checking?
  799. else
  800. s_mov_b32 s_restore_buf_rsrc2, 0x1000000 //NUM_RECORDS in bytes
  801. end
  802. read_hwreg_from_mem(s_restore_m0, s_restore_buf_rsrc0, s_restore_mem_offset) //M0
  803. read_hwreg_from_mem(s_restore_pc_lo, s_restore_buf_rsrc0, s_restore_mem_offset) //PC
  804. read_hwreg_from_mem(s_restore_pc_hi, s_restore_buf_rsrc0, s_restore_mem_offset)
  805. read_hwreg_from_mem(s_restore_exec_lo, s_restore_buf_rsrc0, s_restore_mem_offset) //EXEC
  806. read_hwreg_from_mem(s_restore_exec_hi, s_restore_buf_rsrc0, s_restore_mem_offset)
  807. read_hwreg_from_mem(s_restore_status, s_restore_buf_rsrc0, s_restore_mem_offset) //STATUS
  808. read_hwreg_from_mem(s_restore_trapsts, s_restore_buf_rsrc0, s_restore_mem_offset) //TRAPSTS
  809. read_hwreg_from_mem(xnack_mask_lo, s_restore_buf_rsrc0, s_restore_mem_offset) //XNACK_MASK_LO
  810. read_hwreg_from_mem(xnack_mask_hi, s_restore_buf_rsrc0, s_restore_mem_offset) //XNACK_MASK_HI
  811. read_hwreg_from_mem(s_restore_mode, s_restore_buf_rsrc0, s_restore_mem_offset) //MODE
  812. read_hwreg_from_mem(tba_lo, s_restore_buf_rsrc0, s_restore_mem_offset) //TBA_LO
  813. read_hwreg_from_mem(tba_hi, s_restore_buf_rsrc0, s_restore_mem_offset) //TBA_HI
  814. s_waitcnt lgkmcnt(0) //from now on, it is safe to restore STATUS and IB_STS
  815. s_and_b32 s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff //pc[47:32] //Do it here in order not to affect STATUS
  816. //for normal save & restore, the saved PC points to the next inst to execute, no adjustment needs to be made, otherwise:
  817. if ((EMU_RUN_HACK) && (!EMU_RUN_HACK_RESTORE_NORMAL))
  818. s_add_u32 s_restore_pc_lo, s_restore_pc_lo, 8 //pc[31:0]+8 //two back-to-back s_trap are used (first for save and second for restore)
  819. s_addc_u32 s_restore_pc_hi, s_restore_pc_hi, 0x0 //carry bit over
  820. end
  821. if ((EMU_RUN_HACK) && (EMU_RUN_HACK_RESTORE_NORMAL))
  822. s_add_u32 s_restore_pc_lo, s_restore_pc_lo, 4 //pc[31:0]+4 // save is hack through s_trap but restore is normal
  823. s_addc_u32 s_restore_pc_hi, s_restore_pc_hi, 0x0 //carry bit over
  824. end
  825. s_mov_b32 m0, s_restore_m0
  826. s_mov_b32 exec_lo, s_restore_exec_lo
  827. s_mov_b32 exec_hi, s_restore_exec_hi
  828. s_and_b32 s_restore_m0, SQ_WAVE_TRAPSTS_PRE_SAVECTX_MASK, s_restore_trapsts
  829. s_setreg_b32 hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_PRE_SAVECTX_SHIFT, SQ_WAVE_TRAPSTS_PRE_SAVECTX_SIZE), s_restore_m0
  830. s_and_b32 s_restore_m0, SQ_WAVE_TRAPSTS_POST_SAVECTX_MASK, s_restore_trapsts
  831. s_lshr_b32 s_restore_m0, s_restore_m0, SQ_WAVE_TRAPSTS_POST_SAVECTX_SHIFT
  832. s_setreg_b32 hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_POST_SAVECTX_SHIFT, SQ_WAVE_TRAPSTS_POST_SAVECTX_SIZE), s_restore_m0
  833. //s_setreg_b32 hwreg(HW_REG_TRAPSTS), s_restore_trapsts //don't overwrite SAVECTX bit as it may be set through external SAVECTX during restore
  834. s_setreg_b32 hwreg(HW_REG_MODE), s_restore_mode
  835. //reuse s_restore_m0 as a temp register
  836. s_and_b32 s_restore_m0, s_restore_pc_hi, S_SAVE_PC_HI_RCNT_MASK
  837. s_lshr_b32 s_restore_m0, s_restore_m0, S_SAVE_PC_HI_RCNT_SHIFT
  838. s_lshl_b32 s_restore_m0, s_restore_m0, SQ_WAVE_IB_STS_RCNT_SHIFT
  839. s_mov_b32 s_restore_tmp, 0x0 //IB_STS is zero
  840. s_or_b32 s_restore_tmp, s_restore_tmp, s_restore_m0
  841. s_and_b32 s_restore_m0, s_restore_pc_hi, S_SAVE_PC_HI_FIRST_REPLAY_MASK
  842. s_lshr_b32 s_restore_m0, s_restore_m0, S_SAVE_PC_HI_FIRST_REPLAY_SHIFT
  843. s_lshl_b32 s_restore_m0, s_restore_m0, SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT
  844. s_or_b32 s_restore_tmp, s_restore_tmp, s_restore_m0
  845. s_and_b32 s_restore_m0, s_restore_status, SQ_WAVE_STATUS_INST_ATC_MASK
  846. s_lshr_b32 s_restore_m0, s_restore_m0, SQ_WAVE_STATUS_INST_ATC_SHIFT
  847. s_setreg_b32 hwreg(HW_REG_IB_STS), s_restore_tmp
  848. s_and_b64 exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32
  849. s_and_b64 vcc, vcc, vcc // Restore STATUS.VCCZ, not writable by s_setreg_b32
  850. s_setreg_b32 hwreg(HW_REG_STATUS), s_restore_status // SCC is included, which is changed by previous salu
  851. s_barrier //barrier to ensure the readiness of LDS before access attempts from any other wave in the same TG //FIXME not performance-optimal at this time
  852. if G8SR_DEBUG_TIMESTAMP
  853. s_memrealtime s_g8sr_ts_restore_d
  854. s_waitcnt lgkmcnt(0)
  855. end
  856. // s_rfe_b64 s_restore_pc_lo //Return to the main shader program and resume execution
  857. s_rfe_restore_b64 s_restore_pc_lo, s_restore_m0 // s_restore_m0[0] is used to set STATUS.inst_atc
  858. /**************************************************************************/
  859. /* the END */
  860. /**************************************************************************/
  861. L_END_PGM:
  862. s_endpgm
  863. end
  864. /**************************************************************************/
  865. /* the helper functions */
  866. /**************************************************************************/
  867. //Only for save hwreg to mem
  868. function write_hwreg_to_mem(s, s_rsrc, s_mem_offset)
  869. s_mov_b32 exec_lo, m0 //assuming exec_lo is not needed anymore from this point on
  870. s_mov_b32 m0, s_mem_offset
  871. s_buffer_store_dword s, s_rsrc, m0 glc:1
  872. s_add_u32 s_mem_offset, s_mem_offset, 4
  873. s_mov_b32 m0, exec_lo
  874. end
  875. // HWREG are saved before SGPRs, so all HWREG could be use.
  876. function write_16sgpr_to_mem(s, s_rsrc, s_mem_offset)
  877. s_buffer_store_dwordx4 s[0], s_rsrc, 0 glc:1
  878. s_buffer_store_dwordx4 s[4], s_rsrc, 16 glc:1
  879. s_buffer_store_dwordx4 s[8], s_rsrc, 32 glc:1
  880. s_buffer_store_dwordx4 s[12], s_rsrc, 48 glc:1
  881. s_add_u32 s_rsrc[0], s_rsrc[0], 4*16
  882. s_addc_u32 s_rsrc[1], s_rsrc[1], 0x0 // +scc
  883. end
  884. function read_hwreg_from_mem(s, s_rsrc, s_mem_offset)
  885. s_buffer_load_dword s, s_rsrc, s_mem_offset glc:1
  886. s_add_u32 s_mem_offset, s_mem_offset, 4
  887. end
  888. function read_16sgpr_from_mem(s, s_rsrc, s_mem_offset)
  889. s_buffer_load_dwordx16 s, s_rsrc, s_mem_offset glc:1
  890. s_sub_u32 s_mem_offset, s_mem_offset, 4*16
  891. end
  892. function get_lds_size_bytes(s_lds_size_byte)
  893. // SQ LDS granularity is 64DW, while PGM_RSRC2.lds_size is in granularity 128DW
  894. s_getreg_b32 s_lds_size_byte, hwreg(HW_REG_LDS_ALLOC, SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT, SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE) // lds_size
  895. s_lshl_b32 s_lds_size_byte, s_lds_size_byte, 8 //LDS size in dwords = lds_size * 64 *4Bytes // granularity 64DW
  896. end
  897. function get_vgpr_size_bytes(s_vgpr_size_byte)
  898. s_getreg_b32 s_vgpr_size_byte, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_VGPR_SIZE_SIZE) //vpgr_size
  899. s_add_u32 s_vgpr_size_byte, s_vgpr_size_byte, 1
  900. s_lshl_b32 s_vgpr_size_byte, s_vgpr_size_byte, (2+8) //Number of VGPRs = (vgpr_size + 1) * 4 * 64 * 4 (non-zero value) //FIXME for GFX, zero is possible
  901. end
  902. function get_sgpr_size_bytes(s_sgpr_size_byte)
  903. s_getreg_b32 s_sgpr_size_byte, hwreg(HW_REG_GPR_ALLOC,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SHIFT,SQ_WAVE_GPR_ALLOC_SGPR_SIZE_SIZE) //spgr_size
  904. s_add_u32 s_sgpr_size_byte, s_sgpr_size_byte, 1
  905. s_lshl_b32 s_sgpr_size_byte, s_sgpr_size_byte, 6 //Number of SGPRs = (sgpr_size + 1) * 16 *4 (non-zero value)
  906. end
  907. function get_hwreg_size_bytes
  908. return 128 //HWREG size 128 bytes
  909. end
  910. #endif
  911. static const uint32_t cwsr_trap_gfx8_hex[] = {
  912. 0xbf820001, 0xbf820123,
  913. 0xb8f4f802, 0x89748674,
  914. 0xb8f5f803, 0x8675ff75,
  915. 0x00000400, 0xbf850011,
  916. 0xc00a1e37, 0x00000000,
  917. 0xbf8c007f, 0x87777978,
  918. 0xbf840002, 0xb974f802,
  919. 0xbe801d78, 0xb8f5f803,
  920. 0x8675ff75, 0x000001ff,
  921. 0xbf850002, 0x80708470,
  922. 0x82718071, 0x8671ff71,
  923. 0x0000ffff, 0xb974f802,
  924. 0xbe801f70, 0xb8f5f803,
  925. 0x8675ff75, 0x00000100,
  926. 0xbf840006, 0xbefa0080,
  927. 0xb97a0203, 0x8671ff71,
  928. 0x0000ffff, 0x80f08870,
  929. 0x82f18071, 0xbefa0080,
  930. 0xb97a0283, 0xbef60068,
  931. 0xbef70069, 0xb8fa1c07,
  932. 0x8e7a9c7a, 0x87717a71,
  933. 0xb8fa03c7, 0x8e7a9b7a,
  934. 0x87717a71, 0xb8faf807,
  935. 0x867aff7a, 0x00007fff,
  936. 0xb97af807, 0xbef2007e,
  937. 0xbef3007f, 0xbefe0180,
  938. 0xbf900004, 0xbf8e0002,
  939. 0xbf88fffe, 0xbef8007e,
  940. 0x8679ff7f, 0x0000ffff,
  941. 0x8779ff79, 0x00040000,
  942. 0xbefa0080, 0xbefb00ff,
  943. 0x00807fac, 0x867aff7f,
  944. 0x08000000, 0x8f7a837a,
  945. 0x877b7a7b, 0x867aff7f,
  946. 0x70000000, 0x8f7a817a,
  947. 0x877b7a7b, 0xbeef007c,
  948. 0xbeee0080, 0xb8ee2a05,
  949. 0x806e816e, 0x8e6e8a6e,
  950. 0xb8fa1605, 0x807a817a,
  951. 0x8e7a867a, 0x806e7a6e,
  952. 0xbefa0084, 0xbefa00ff,
  953. 0x01000000, 0xbefe007c,
  954. 0xbefc006e, 0xc0611bfc,
  955. 0x0000007c, 0x806e846e,
  956. 0xbefc007e, 0xbefe007c,
  957. 0xbefc006e, 0xc0611c3c,
  958. 0x0000007c, 0x806e846e,
  959. 0xbefc007e, 0xbefe007c,
  960. 0xbefc006e, 0xc0611c7c,
  961. 0x0000007c, 0x806e846e,
  962. 0xbefc007e, 0xbefe007c,
  963. 0xbefc006e, 0xc0611cbc,
  964. 0x0000007c, 0x806e846e,
  965. 0xbefc007e, 0xbefe007c,
  966. 0xbefc006e, 0xc0611cfc,
  967. 0x0000007c, 0x806e846e,
  968. 0xbefc007e, 0xbefe007c,
  969. 0xbefc006e, 0xc0611d3c,
  970. 0x0000007c, 0x806e846e,
  971. 0xbefc007e, 0xb8f5f803,
  972. 0xbefe007c, 0xbefc006e,
  973. 0xc0611d7c, 0x0000007c,
  974. 0x806e846e, 0xbefc007e,
  975. 0xbefe007c, 0xbefc006e,
  976. 0xc0611dbc, 0x0000007c,
  977. 0x806e846e, 0xbefc007e,
  978. 0xbefe007c, 0xbefc006e,
  979. 0xc0611dfc, 0x0000007c,
  980. 0x806e846e, 0xbefc007e,
  981. 0xb8eff801, 0xbefe007c,
  982. 0xbefc006e, 0xc0611bfc,
  983. 0x0000007c, 0x806e846e,
  984. 0xbefc007e, 0xbefe007c,
  985. 0xbefc006e, 0xc0611b3c,
  986. 0x0000007c, 0x806e846e,
  987. 0xbefc007e, 0xbefe007c,
  988. 0xbefc006e, 0xc0611b7c,
  989. 0x0000007c, 0x806e846e,
  990. 0xbefc007e, 0x867aff7f,
  991. 0x04000000, 0xbef30080,
  992. 0x8773737a, 0xb8ee2a05,
  993. 0x806e816e, 0x8e6e8a6e,
  994. 0xb8f51605, 0x80758175,
  995. 0x8e758475, 0x8e7a8275,
  996. 0xbefa00ff, 0x01000000,
  997. 0xbef60178, 0x80786e78,
  998. 0x82798079, 0xbefc0080,
  999. 0xbe802b00, 0xbe822b02,
  1000. 0xbe842b04, 0xbe862b06,
  1001. 0xbe882b08, 0xbe8a2b0a,
  1002. 0xbe8c2b0c, 0xbe8e2b0e,
  1003. 0xc06b003c, 0x00000000,
  1004. 0xc06b013c, 0x00000010,
  1005. 0xc06b023c, 0x00000020,
  1006. 0xc06b033c, 0x00000030,
  1007. 0x8078c078, 0x82798079,
  1008. 0x807c907c, 0xbf0a757c,
  1009. 0xbf85ffeb, 0xbef80176,
  1010. 0xbeee0080, 0xbefe00c1,
  1011. 0xbeff00c1, 0xbefa00ff,
  1012. 0x01000000, 0xe0724000,
  1013. 0x6e1e0000, 0xe0724100,
  1014. 0x6e1e0100, 0xe0724200,
  1015. 0x6e1e0200, 0xe0724300,
  1016. 0x6e1e0300, 0xbefe00c1,
  1017. 0xbeff00c1, 0xb8f54306,
  1018. 0x8675c175, 0xbf84002c,
  1019. 0xbf8a0000, 0x867aff73,
  1020. 0x04000000, 0xbf840028,
  1021. 0x8e758675, 0x8e758275,
  1022. 0xbefa0075, 0xb8ee2a05,
  1023. 0x806e816e, 0x8e6e8a6e,
  1024. 0xb8fa1605, 0x807a817a,
  1025. 0x8e7a867a, 0x806e7a6e,
  1026. 0x806eff6e, 0x00000080,
  1027. 0xbefa00ff, 0x01000000,
  1028. 0xbefc0080, 0xd28c0002,
  1029. 0x000100c1, 0xd28d0003,
  1030. 0x000204c1, 0xd1060002,
  1031. 0x00011103, 0x7e0602ff,
  1032. 0x00000200, 0xbefc00ff,
  1033. 0x00010000, 0xbe80007b,
  1034. 0x867bff7b, 0xff7fffff,
  1035. 0x877bff7b, 0x00058000,
  1036. 0xd8ec0000, 0x00000002,
  1037. 0xbf8c007f, 0xe0765000,
  1038. 0x6e1e0002, 0x32040702,
  1039. 0xd0c9006a, 0x0000eb02,
  1040. 0xbf87fff7, 0xbefb0000,
  1041. 0xbeee00ff, 0x00000400,
  1042. 0xbefe00c1, 0xbeff00c1,
  1043. 0xb8f52a05, 0x80758175,
  1044. 0x8e758275, 0x8e7a8875,
  1045. 0xbefa00ff, 0x01000000,
  1046. 0xbefc0084, 0xbf0a757c,
  1047. 0xbf840015, 0xbf11017c,
  1048. 0x8075ff75, 0x00001000,
  1049. 0x7e000300, 0x7e020301,
  1050. 0x7e040302, 0x7e060303,
  1051. 0xe0724000, 0x6e1e0000,
  1052. 0xe0724100, 0x6e1e0100,
  1053. 0xe0724200, 0x6e1e0200,
  1054. 0xe0724300, 0x6e1e0300,
  1055. 0x807c847c, 0x806eff6e,
  1056. 0x00000400, 0xbf0a757c,
  1057. 0xbf85ffef, 0xbf9c0000,
  1058. 0xbf8200ca, 0xbef8007e,
  1059. 0x8679ff7f, 0x0000ffff,
  1060. 0x8779ff79, 0x00040000,
  1061. 0xbefa0080, 0xbefb00ff,
  1062. 0x00807fac, 0x8676ff7f,
  1063. 0x08000000, 0x8f768376,
  1064. 0x877b767b, 0x8676ff7f,
  1065. 0x70000000, 0x8f768176,
  1066. 0x877b767b, 0x8676ff7f,
  1067. 0x04000000, 0xbf84001e,
  1068. 0xbefe00c1, 0xbeff00c1,
  1069. 0xb8f34306, 0x8673c173,
  1070. 0xbf840019, 0x8e738673,
  1071. 0x8e738273, 0xbefa0073,
  1072. 0xb8f22a05, 0x80728172,
  1073. 0x8e728a72, 0xb8f61605,
  1074. 0x80768176, 0x8e768676,
  1075. 0x80727672, 0x8072ff72,
  1076. 0x00000080, 0xbefa00ff,
  1077. 0x01000000, 0xbefc0080,
  1078. 0xe0510000, 0x721e0000,
  1079. 0xe0510100, 0x721e0000,
  1080. 0x807cff7c, 0x00000200,
  1081. 0x8072ff72, 0x00000200,
  1082. 0xbf0a737c, 0xbf85fff6,
  1083. 0xbef20080, 0xbefe00c1,
  1084. 0xbeff00c1, 0xb8f32a05,
  1085. 0x80738173, 0x8e738273,
  1086. 0x8e7a8873, 0xbefa00ff,
  1087. 0x01000000, 0xbef60072,
  1088. 0x8072ff72, 0x00000400,
  1089. 0xbefc0084, 0xbf11087c,
  1090. 0x8073ff73, 0x00008000,
  1091. 0xe0524000, 0x721e0000,
  1092. 0xe0524100, 0x721e0100,
  1093. 0xe0524200, 0x721e0200,
  1094. 0xe0524300, 0x721e0300,
  1095. 0xbf8c0f70, 0x7e000300,
  1096. 0x7e020301, 0x7e040302,
  1097. 0x7e060303, 0x807c847c,
  1098. 0x8072ff72, 0x00000400,
  1099. 0xbf0a737c, 0xbf85ffee,
  1100. 0xbf9c0000, 0xe0524000,
  1101. 0x761e0000, 0xe0524100,
  1102. 0x761e0100, 0xe0524200,
  1103. 0x761e0200, 0xe0524300,
  1104. 0x761e0300, 0xb8f22a05,
  1105. 0x80728172, 0x8e728a72,
  1106. 0xb8f61605, 0x80768176,
  1107. 0x8e768676, 0x80727672,
  1108. 0x80f2c072, 0xb8f31605,
  1109. 0x80738173, 0x8e738473,
  1110. 0x8e7a8273, 0xbefa00ff,
  1111. 0x01000000, 0xbefc0073,
  1112. 0xc031003c, 0x00000072,
  1113. 0x80f2c072, 0xbf8c007f,
  1114. 0x80fc907c, 0xbe802d00,
  1115. 0xbe822d02, 0xbe842d04,
  1116. 0xbe862d06, 0xbe882d08,
  1117. 0xbe8a2d0a, 0xbe8c2d0c,
  1118. 0xbe8e2d0e, 0xbf06807c,
  1119. 0xbf84fff1, 0xb8f22a05,
  1120. 0x80728172, 0x8e728a72,
  1121. 0xb8f61605, 0x80768176,
  1122. 0x8e768676, 0x80727672,
  1123. 0xbefa0084, 0xbefa00ff,
  1124. 0x01000000, 0xc0211cfc,
  1125. 0x00000072, 0x80728472,
  1126. 0xc0211c3c, 0x00000072,
  1127. 0x80728472, 0xc0211c7c,
  1128. 0x00000072, 0x80728472,
  1129. 0xc0211bbc, 0x00000072,
  1130. 0x80728472, 0xc0211bfc,
  1131. 0x00000072, 0x80728472,
  1132. 0xc0211d3c, 0x00000072,
  1133. 0x80728472, 0xc0211d7c,
  1134. 0x00000072, 0x80728472,
  1135. 0xc0211a3c, 0x00000072,
  1136. 0x80728472, 0xc0211a7c,
  1137. 0x00000072, 0x80728472,
  1138. 0xc0211dfc, 0x00000072,
  1139. 0x80728472, 0xc0211b3c,
  1140. 0x00000072, 0x80728472,
  1141. 0xc0211b7c, 0x00000072,
  1142. 0x80728472, 0xbf8c007f,
  1143. 0x8671ff71, 0x0000ffff,
  1144. 0xbefc0073, 0xbefe006e,
  1145. 0xbeff006f, 0x867375ff,
  1146. 0x000003ff, 0xb9734803,
  1147. 0x867375ff, 0xfffff800,
  1148. 0x8f738b73, 0xb973a2c3,
  1149. 0xb977f801, 0x8673ff71,
  1150. 0xf0000000, 0x8f739c73,
  1151. 0x8e739073, 0xbef60080,
  1152. 0x87767376, 0x8673ff71,
  1153. 0x08000000, 0x8f739b73,
  1154. 0x8e738f73, 0x87767376,
  1155. 0x8673ff74, 0x00800000,
  1156. 0x8f739773, 0xb976f807,
  1157. 0x86fe7e7e, 0x86ea6a6a,
  1158. 0xb974f802, 0xbf8a0000,
  1159. 0x95807370, 0xbf810000,
  1160. };