Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1436 lines
38 KiB

  1. // TITLE("Capture and Restore Context")
  2. //++
  3. //
  4. // Module Name:
  5. //
  6. // capture.s
  7. //
  8. // Abstract:
  9. //
  10. // This module implements the code necessary to capture and restore
  11. // the context of the caller.
  12. //
  13. // Author:
  14. //
  15. // William K. Cheung (wcheung) 08-Jan-1996
  16. //
  17. // Environment:
  18. //
  19. // Any mode.
  20. //
  21. // Revision History:
  22. //
  23. //--
  24. #include "ksia64.h"
  25. .global ZwContinue
  26. .type ZwContinue, @function
  27. //++
  28. //
  29. // VOID
  30. // RtlCaptureContext (
  31. // OUT PCONTEXT ContextRecord
  32. // )
  33. //
  34. // Routine Description:
  35. //
  36. // This function captures the context of the caller in the specified
  37. // context record.
  38. //
  39. // N.B. The context record is not guaranteed to be quadword aligned
  40. // and, therefore, no double floating store instructions can be
  41. // used.
  42. //
  43. // Arguments:
  44. //
  45. // ContextRecord (a0) - Supplies the address of a context record.
  46. //
  47. // Return Value:
  48. //
  49. // None.
  50. //
  51. //--
  52. LEAF_ENTRY(RtlCaptureContext)
  53. //
  54. // Save all integer registers and flush the RSE
  55. //
  56. .prologue
  57. .regstk 1, 10, 0, 0
  58. rbsp = loc9
  59. rpfs = loc8
  60. rbrp = loc7
  61. rpr = loc6
  62. runat = loc4
  63. flag = t16
  64. tmpbsp = t20
  65. rpsr = t22
  66. alloc rpfs = ar.pfs, 1, 10, 0, 0
  67. add loc0 = CxIntGp, a0
  68. add loc1 = CxIntT8, a0
  69. ;;
  70. flushrs
  71. .save ar.unat, loc4
  72. mov runat = ar.unat
  73. mov rpr = pr
  74. PROLOGUE_END
  75. .mem.offset 0,0
  76. st8.spill.nta [loc0] = gp, CxIntT0 - CxIntGp
  77. .mem.offset 8,0
  78. st8.spill.nta [loc1] = t8, CxIntT9 - CxIntT8
  79. add loc2 = CxIntGp, a0
  80. ;;
  81. .mem.offset 0,0
  82. st8.spill.nta [loc0] = t0, CxIntT1 - CxIntT0
  83. .mem.offset 8,0
  84. st8.spill.nta [loc1] = t9, CxIntT10 - CxIntT9
  85. shr loc2 = loc2, 3
  86. ;;
  87. .mem.offset 0,0
  88. st8.spill.nta [loc0] = t1, CxIntS0 - CxIntT1
  89. .mem.offset 8,0
  90. st8.spill.nta [loc1] = t10, CxIntT11 - CxIntT10
  91. and t0 = 0x3f, loc2
  92. ;;
  93. .mem.offset 0,0
  94. st8.spill.nta [loc0] = s0, CxIntS1 - CxIntS0
  95. .mem.offset 8,0
  96. st8.spill.nta [loc1] = t11, CxIntT12 - CxIntT11
  97. cmp4.ge pt1, pt0 = 1, t0
  98. ;;
  99. .mem.offset 0,0
  100. st8.spill.nta [loc0] = s1, CxIntS2 - CxIntS1
  101. .mem.offset 8,0
  102. st8.spill.nta [loc1] = t12, CxIntT13 - CxIntT12
  103. (pt1) sub t1 = 1, t0
  104. ;;
  105. .mem.offset 0,0
  106. st8.spill.nta [loc0] = s2, CxIntS3 - CxIntS2
  107. .mem.offset 8,0
  108. st8.spill.nta [loc1] = t13, CxIntT14 - CxIntT13
  109. (pt0) add t1 = -1, t0
  110. ;;
  111. .mem.offset 0,0
  112. st8.spill.nta [loc0] = s3, CxIntV0 - CxIntS3
  113. .mem.offset 8,0
  114. st8.spill.nta [loc1] = t14, CxIntT15 - CxIntT14
  115. (pt0) sub t8 = 65, t0
  116. ;;
  117. .mem.offset 0,0
  118. st8.spill.nta [loc0] = v0, CxIntTeb - CxIntV0
  119. .mem.offset 8,0
  120. st8.spill.nta [loc1] = t15, CxIntT16 - CxIntT15
  121. nop.i 0
  122. ;;
  123. .mem.offset 0,0
  124. st8.spill.nta [loc0] = teb, CxIntT2 - CxIntTeb
  125. .mem.offset 8,0
  126. st8.spill.nta [loc1] = t16, CxIntT17 - CxIntT16
  127. mov rbrp = brp
  128. ;;
  129. .mem.offset 0,0
  130. st8.spill.nta [loc0] = t2, CxIntT3 - CxIntT2
  131. .mem.offset 8,0
  132. st8.spill.nta [loc1] = t17, CxIntT18 - CxIntT17
  133. mov t11 = bs0
  134. ;;
  135. .mem.offset 0,0
  136. st8.spill.nta [loc0] = t3, CxIntSp - CxIntT3
  137. .mem.offset 8,0
  138. st8.spill.nta [loc1] = t18, CxIntT19 - CxIntT18
  139. mov t12 = bs1
  140. ;;
  141. .mem.offset 0,0
  142. st8.spill.nta [loc0] = sp, CxIntT4 - CxIntSp
  143. .mem.offset 8,0
  144. st8.spill.nta [loc1] = t19, CxIntT20 - CxIntT19
  145. mov t13 = bs2
  146. ;;
  147. .mem.offset 0,0
  148. st8.spill.nta [loc0] = t4, CxIntT5 - CxIntT4
  149. .mem.offset 8,0
  150. st8.spill.nta [loc1] = t20, CxIntT21 - CxIntT20
  151. mov t14 = bs3
  152. ;;
  153. .mem.offset 0,0
  154. st8.spill.nta [loc0] = t5, CxIntT6 - CxIntT5
  155. .mem.offset 8,0
  156. st8.spill.nta [loc1] = t21, CxIntT22 - CxIntT21
  157. mov t15 = bs4
  158. ;;
  159. .mem.offset 0,0
  160. st8.spill.nta [loc0] = t6, CxIntT7 - CxIntT6
  161. .mem.offset 8,0
  162. st8.spill.nta [loc1] = t22, CxPreds - CxIntT22
  163. mov t16 = bt0
  164. ;;
  165. st8.spill.nta [loc0] = t7
  166. st8.nta [loc1] = rpr, CxIntNats - CxPreds // save predicates
  167. mov t17 = bt1
  168. ;;
  169. mov t9 = ar.unat
  170. mov t4 = ar.fpsr
  171. add loc2 = CxBrRp, a0
  172. ;;
  173. add loc3 = CxBrS3, a0
  174. (pt1) shl t9 = t9, t1
  175. (pt0) shr.u t2 = t9, t1
  176. ;;
  177. //
  178. // Save branch registers.
  179. //
  180. st8.nta [loc2] = rbrp, CxBrS0 - CxBrRp // save brp
  181. st8.nta [loc3] = t14, CxBrS4 - CxBrS3 // save bs3
  182. (pt0) shl t3 = t9, t8
  183. ;;
  184. st8.nta [loc2] = t11, CxBrS1 - CxBrS0 // save bs0
  185. st8.nta [loc3] = t15, CxBrT0 - CxBrS4 // save bs4
  186. (pt0) or t9 = t2, t3
  187. ;;
  188. st8.nta [loc2] = t12, CxBrS2 - CxBrS1 // save bs1
  189. st8.nta [loc3] = t16, CxBrT1 - CxBrT0 // save bt0
  190. add loc0 = CxStFPSR, a0
  191. ;;
  192. st8.nta [loc2] = t13 // save bs2
  193. st8.nta [loc3] = t17 // save bt1
  194. nop.i 0
  195. ;;
  196. st8.nta [loc0] = t4 // save fpsr
  197. st8.nta [loc1] = t9 // save nat bits
  198. ;;
  199. #if !defined(NTOS_KERNEL_RUNTIME)
  200. mov t0 = ar21
  201. mov t1 = ar24
  202. add loc0 = CxStFCR, a0
  203. add loc1 = CxEflag, a0
  204. ;;
  205. mov t2 = ar25
  206. mov t3 = ar26
  207. st8.nta [loc0] = t0, 16
  208. st8.nta [loc1] = t1, 16
  209. ;;
  210. mov t0 = ar27
  211. mov t1 = ar28
  212. st8.nta [loc0] = t2, 16
  213. st8.nta [loc1] = t3, 16
  214. ;;
  215. mov t2 = ar29
  216. mov t3 = ar30
  217. st8.nta [loc0] = t0, 16
  218. st8.nta [loc1] = t1, 16
  219. ;;
  220. st8.nta [loc0] = t2, 16
  221. st8.nta [loc1] = t3, 16
  222. #endif // !defined(NTOS_KERNEL_RUNTIME)
  223. mov rbsp = ar.bsp
  224. add loc2 = CxFltS0, a0
  225. add loc3 = CxFltS1, a0
  226. ;;
  227. //
  228. // Save floating status and floating registers f0 - f127.
  229. //
  230. stf.spill.nta [loc2] = fs0, CxFltS2 - CxFltS0
  231. stf.spill.nta [loc3] = fs1, CxFltS3 - CxFltS1
  232. shr t0 = rpfs, 7
  233. ;;
  234. stf.spill.nta [loc2] = fs2, CxFltT0 - CxFltS2
  235. stf.spill.nta [loc3] = fs3, CxFltT1 - CxFltS3
  236. and t0 = 0x7f, t0
  237. ;;
  238. stf.spill.nta [loc2] = ft0, CxFltT2 - CxFltT0
  239. stf.spill.nta [loc3] = ft1, CxFltT3 - CxFltT1
  240. shr t1 = rbsp, 3
  241. ;;
  242. stf.spill.nta [loc2] = ft2, CxFltT4 - CxFltT2
  243. stf.spill.nta [loc3] = ft3, CxFltT5 - CxFltT3
  244. and t1 = 0x3f, t1
  245. ;;
  246. stf.spill.nta [loc2] = ft4, CxFltT6 - CxFltT4
  247. stf.spill.nta [loc3] = ft5, CxFltT7 - CxFltT5
  248. sub t2 = t0, t1
  249. ;;
  250. stf.spill.nta [loc2] = ft6, CxFltT8 - CxFltT6
  251. stf.spill.nta [loc3] = ft7, CxFltT9 - CxFltT7
  252. cmp4.le pt1, pt0 = t2, zero
  253. ;;
  254. stf.spill.nta [loc2] = ft8, CxFltS4 - CxFltT8
  255. stf.spill.nta [loc3] = ft9, CxFltS5 - CxFltT9
  256. (pt0) add t2 = -1, t2
  257. ;;
  258. stf.spill.nta [loc2] = fs4, CxFltS6 - CxFltS4
  259. stf.spill.nta [loc3] = fs5, CxFltS7 - CxFltS5
  260. (pt0) add t0 = 1, t0
  261. ;;
  262. stf.spill.nta [loc2] = fs6, CxFltS8 - CxFltS6
  263. stf.spill.nta [loc3] = fs7, CxFltS9 - CxFltS7
  264. (pt0) add t2 = -63, t2
  265. ;;
  266. stf.spill.nta [loc2] = fs8, CxFltS10 - CxFltS8
  267. stf.spill.nta [loc3] = fs9, CxFltS11 - CxFltS9
  268. (pt0) cmp4.ge.unc pt2, pt3 = t2, zero
  269. ;;
  270. stf.spill.nta [loc2] = fs10, CxFltS12 - CxFltS10
  271. stf.spill.nta [loc3] = fs11, CxFltS13 - CxFltS11
  272. mov rpsr = psr.um
  273. add tmpbsp = -8, rbsp
  274. (pt1) br.cond.spnt Rcc20
  275. ;;
  276. Rcc10:
  277. (pt2) add t0 = 1, t0
  278. (pt2) add t2 = -63, t2
  279. (pt3) br.cond.sptk Rcc20
  280. ;;
  281. cmp4.ge pt2, pt3 = t2, zero
  282. nop.m 0
  283. br Rcc10
  284. ;;
  285. Rcc20:
  286. stf.spill.nta [loc2] = fs12, CxFltS14 - CxFltS12
  287. stf.spill.nta [loc3] = fs13, CxFltS15 - CxFltS13
  288. shl t0 = t0, 3
  289. ;;
  290. stf.spill.nta [loc2] = fs14, CxFltS16 - CxFltS14
  291. stf.spill.nta [loc3] = fs15, CxFltS17 - CxFltS15
  292. sub rbsp = rbsp, t0
  293. ;;
  294. stf.spill.nta [loc2] = fs16, CxFltS18 - CxFltS16
  295. stf.spill.nta [loc3] = fs17, CxFltS19 - CxFltS17
  296. tbit.z pt2, pt1 = rpsr, PSR_MFH
  297. ;;
  298. stf.spill.nta [loc2] = fs18, CxFltF32 - CxFltS18
  299. stf.spill.nta [loc3] = fs19, CxFltF33 - CxFltS19
  300. mov flag = CONTEXT_CONTROL | CONTEXT_LOWER_FLOATING_POINT | CONTEXT_INTEGER
  301. ;;
  302. #if !defined(NTOS_KERNEL_RUNTIME)
  303. //
  304. // there is no need to capture the high fp set if the privilege
  305. // mode is kernel or the psr.mfh bit is not set in user mode.
  306. //
  307. (pt1) mov flag = CONTEXT_FULL
  308. (pt2) br.cond.sptk Rcc30
  309. ;;
  310. stf.spill.nta [loc2] = f32, CxFltF34 - CxFltF32
  311. stf.spill.nta [loc3] = f33, CxFltF35 - CxFltF33
  312. nop.i 0
  313. ;;
  314. stf.spill.nta [loc2] = f34, CxFltF36 - CxFltF34
  315. stf.spill.nta [loc3] = f35, CxFltF37 - CxFltF35
  316. nop.i 0
  317. ;;
  318. stf.spill.nta [loc2] = f36, CxFltF38 - CxFltF36
  319. stf.spill.nta [loc3] = f37, CxFltF39 - CxFltF37
  320. nop.i 0
  321. ;;
  322. stf.spill.nta [loc2] = f38, CxFltF40 - CxFltF38
  323. stf.spill.nta [loc3] = f39, CxFltF41 - CxFltF39
  324. nop.i 0
  325. ;;
  326. stf.spill.nta [loc2] = f40, CxFltF42 - CxFltF40
  327. stf.spill.nta [loc3] = f41, CxFltF43 - CxFltF41
  328. nop.i 0
  329. ;;
  330. stf.spill.nta [loc2] = f42, CxFltF44 - CxFltF42
  331. stf.spill.nta [loc3] = f43, CxFltF45 - CxFltF43
  332. nop.i 0
  333. ;;
  334. stf.spill.nta [loc2] = f44, CxFltF46 - CxFltF44
  335. stf.spill.nta [loc3] = f45, CxFltF47 - CxFltF45
  336. nop.i 0
  337. ;;
  338. stf.spill.nta [loc2] = f46, CxFltF48 - CxFltF46
  339. stf.spill.nta [loc3] = f47, CxFltF49 - CxFltF47
  340. nop.i 0
  341. ;;
  342. stf.spill.nta [loc2] = f48, CxFltF50 - CxFltF48
  343. stf.spill.nta [loc3] = f49, CxFltF51 - CxFltF49
  344. nop.i 0
  345. ;;
  346. stf.spill.nta [loc2] = f50, CxFltF52 - CxFltF50
  347. stf.spill.nta [loc3] = f51, CxFltF53 - CxFltF51
  348. nop.i 0
  349. ;;
  350. stf.spill.nta [loc2] = f52, CxFltF54 - CxFltF52
  351. stf.spill.nta [loc3] = f53, CxFltF55 - CxFltF53
  352. nop.i 0
  353. ;;
  354. stf.spill.nta [loc2] = f54, CxFltF56 - CxFltF54
  355. stf.spill.nta [loc3] = f55, CxFltF57 - CxFltF55
  356. nop.i 0
  357. ;;
  358. stf.spill.nta [loc2] = f56, CxFltF58 - CxFltF56
  359. stf.spill.nta [loc3] = f57, CxFltF59 - CxFltF57
  360. nop.i 0
  361. ;;
  362. stf.spill.nta [loc2] = f58, CxFltF60 - CxFltF58
  363. stf.spill.nta [loc3] = f59, CxFltF61 - CxFltF59
  364. nop.i 0
  365. ;;
  366. stf.spill.nta [loc2] = f60, CxFltF62 - CxFltF60
  367. stf.spill.nta [loc3] = f61, CxFltF63 - CxFltF61
  368. nop.i 0
  369. ;;
  370. stf.spill.nta [loc2] = f62, CxFltF64 - CxFltF62
  371. stf.spill.nta [loc3] = f63, CxFltF65 - CxFltF63
  372. nop.i 0
  373. ;;
  374. stf.spill.nta [loc2] = f64, CxFltF66 - CxFltF64
  375. stf.spill.nta [loc3] = f65, CxFltF67 - CxFltF65
  376. nop.i 0
  377. ;;
  378. stf.spill.nta [loc2] = f66, CxFltF68 - CxFltF66
  379. stf.spill.nta [loc3] = f67, CxFltF69 - CxFltF67
  380. nop.i 0
  381. ;;
  382. stf.spill.nta [loc2] = f68, CxFltF70 - CxFltF68
  383. stf.spill.nta [loc3] = f69, CxFltF71 - CxFltF69
  384. nop.i 0
  385. ;;
  386. stf.spill.nta [loc2] = f70, CxFltF72 - CxFltF70
  387. stf.spill.nta [loc3] = f71, CxFltF73 - CxFltF71
  388. nop.i 0
  389. ;;
  390. stf.spill.nta [loc2] = f72, CxFltF74 - CxFltF72
  391. stf.spill.nta [loc3] = f73, CxFltF75 - CxFltF73
  392. nop.i 0
  393. ;;
  394. stf.spill.nta [loc2] = f74, CxFltF76 - CxFltF74
  395. stf.spill.nta [loc3] = f75, CxFltF77 - CxFltF75
  396. nop.i 0
  397. ;;
  398. stf.spill.nta [loc2] = f76, CxFltF78 - CxFltF76
  399. stf.spill.nta [loc3] = f77, CxFltF79 - CxFltF77
  400. nop.i 0
  401. ;;
  402. stf.spill.nta [loc2] = f78, CxFltF80 - CxFltF78
  403. stf.spill.nta [loc3] = f79, CxFltF81 - CxFltF79
  404. nop.i 0
  405. ;;
  406. stf.spill.nta [loc2] = f80, CxFltF82 - CxFltF80
  407. stf.spill.nta [loc3] = f81, CxFltF83 - CxFltF81
  408. nop.i 0
  409. ;;
  410. stf.spill.nta [loc2] = f82, CxFltF84 - CxFltF82
  411. stf.spill.nta [loc3] = f83, CxFltF85 - CxFltF83
  412. nop.i 0
  413. ;;
  414. stf.spill.nta [loc2] = f84, CxFltF86 - CxFltF84
  415. stf.spill.nta [loc3] = f85, CxFltF87 - CxFltF85
  416. nop.i 0
  417. ;;
  418. stf.spill.nta [loc2] = f86, CxFltF88 - CxFltF86
  419. stf.spill.nta [loc3] = f87, CxFltF89 - CxFltF87
  420. nop.i 0
  421. ;;
  422. stf.spill.nta [loc2] = f88, CxFltF90 - CxFltF88
  423. stf.spill.nta [loc3] = f89, CxFltF91 - CxFltF89
  424. nop.i 0
  425. ;;
  426. stf.spill.nta [loc2] = f90, CxFltF92 - CxFltF90
  427. stf.spill.nta [loc3] = f91, CxFltF93 - CxFltF91
  428. nop.i 0
  429. ;;
  430. stf.spill.nta [loc2] = f92, CxFltF94 - CxFltF92
  431. stf.spill.nta [loc3] = f93, CxFltF95 - CxFltF93
  432. nop.i 0
  433. ;;
  434. stf.spill.nta [loc2] = f94, CxFltF96 - CxFltF94
  435. stf.spill.nta [loc3] = f95, CxFltF97 - CxFltF95
  436. nop.i 0
  437. ;;
  438. stf.spill.nta [loc2] = f96, CxFltF98 - CxFltF96
  439. stf.spill.nta [loc3] = f97, CxFltF99 - CxFltF97
  440. nop.i 0
  441. ;;
  442. stf.spill.nta [loc2] = f98, CxFltF100 - CxFltF98
  443. stf.spill.nta [loc3] = f99, CxFltF101 - CxFltF99
  444. nop.i 0
  445. ;;
  446. stf.spill.nta [loc2] = f100, CxFltF102 - CxFltF100
  447. stf.spill.nta [loc3] = f101, CxFltF103 - CxFltF101
  448. nop.i 0
  449. ;;
  450. stf.spill.nta [loc2] = f102, CxFltF104 - CxFltF102
  451. stf.spill.nta [loc3] = f103, CxFltF105 - CxFltF103
  452. nop.i 0
  453. ;;
  454. stf.spill.nta [loc2] = f104, CxFltF106 - CxFltF104
  455. stf.spill.nta [loc3] = f105, CxFltF107 - CxFltF105
  456. nop.i 0
  457. ;;
  458. stf.spill.nta [loc2] = f106, CxFltF108 - CxFltF106
  459. stf.spill.nta [loc3] = f107, CxFltF109 - CxFltF107
  460. nop.i 0
  461. ;;
  462. stf.spill.nta [loc2] = f108, CxFltF110 - CxFltF108
  463. stf.spill.nta [loc3] = f109, CxFltF111 - CxFltF109
  464. nop.i 0
  465. ;;
  466. stf.spill.nta [loc2] = f110, CxFltF112 - CxFltF110
  467. stf.spill.nta [loc3] = f111, CxFltF113 - CxFltF111
  468. nop.i 0
  469. ;;
  470. stf.spill.nta [loc2] = f112, CxFltF114 - CxFltF112
  471. stf.spill.nta [loc3] = f113, CxFltF115 - CxFltF113
  472. nop.i 0
  473. ;;
  474. stf.spill.nta [loc2] = f114, CxFltF116 - CxFltF114
  475. stf.spill.nta [loc3] = f115, CxFltF117 - CxFltF115
  476. nop.i 0
  477. ;;
  478. stf.spill.nta [loc2] = f116, CxFltF118 - CxFltF116
  479. stf.spill.nta [loc3] = f117, CxFltF119 - CxFltF117
  480. nop.i 0
  481. ;;
  482. stf.spill.nta [loc2] = f118, CxFltF120 - CxFltF118
  483. stf.spill.nta [loc3] = f119, CxFltF121 - CxFltF119
  484. nop.i 0
  485. ;;
  486. stf.spill.nta [loc2] = f120, CxFltF122 - CxFltF120
  487. stf.spill.nta [loc3] = f121, CxFltF123 - CxFltF121
  488. nop.i 0
  489. ;;
  490. stf.spill.nta [loc2] = f122, CxFltF124 - CxFltF122
  491. stf.spill.nta [loc3] = f123, CxFltF125 - CxFltF123
  492. nop.i 0
  493. ;;
  494. stf.spill.nta [loc2] = f124, CxFltF126 - CxFltF124
  495. stf.spill.nta [loc3] = f125, CxFltF127 - CxFltF125
  496. nop.i 0
  497. ;;
  498. stf.spill.nta [loc2] = f126
  499. stf.spill.nta [loc3] = f127
  500. nop.i 0
  501. ;;
  502. Rcc30:
  503. #endif // !defined(NTOS_KERNEL_RUNTIME)
  504. //
  505. // Save application registers, control information and set context flags.
  506. //
  507. User=pt0
  508. Krnl=pt1
  509. rdcr=t1
  510. mask=t2
  511. sol=t4
  512. rpsr=t5
  513. is=t6
  514. rccv=t7
  515. rlc=t8
  516. rec=t9
  517. rrsc=t10
  518. rrnat=t11
  519. addr0=t17
  520. addr1=t18
  521. tmp=t19
  522. mov rrsc = ar.rsc
  523. tbit.nz Krnl, User = sp, 62 // bit 62 is 1 when
  524. mov rlc = ar.lc
  525. ;;
  526. mov ar.rsc = r0 // put RSE in lazy mode
  527. mov rccv = ar.ccv
  528. mov rec = ar.ec
  529. ;; // in kernel
  530. (Krnl) mov rpsr = psr
  531. (User) mov rpsr = psr.um
  532. add addr0 = CxApUNAT, a0
  533. mov rrnat = ar.rnat
  534. add addr1 = CxApLC, a0
  535. (Krnl) mov rdcr = cr.dcr
  536. (Krnl) movl tmp = 1 << PSR_BN
  537. ;;
  538. st8.nta [addr0] = runat, CxApEC - CxApUNAT
  539. st8.nta [addr1] = rlc, CxApCCV - CxApLC
  540. (Krnl) or rpsr = tmp, rpsr
  541. ;;
  542. st8.nta [addr0] = rec, CxApDCR - CxApEC
  543. st8.nta [addr1] = rccv, CxRsPFS - CxApCCV
  544. mov tmp = 1
  545. ;;
  546. st8.nta [addr0] = rdcr, CxRsBSP - CxApDCR
  547. st8.nta [addr1] = rpfs, CxRsBSPSTORE - CxRsPFS
  548. shl tmp = tmp, 63
  549. ;;
  550. st8.nta [addr0] = rbsp, CxRsRSC - CxRsBSP
  551. st8.nta [addr1] = rbsp, CxRsRNAT - CxRsBSPSTORE
  552. or rpfs = rpfs, tmp // validate IFS
  553. ;;
  554. st8.nta [addr0] = rrsc, CxStIIP - CxRsRSC
  555. st8.nta [addr1] = rrnat, CxStIFS - CxRsRNAT
  556. mov mask = RNAT_ALIGNMENT
  557. ;;
  558. st8.nta [addr0] = rbrp, CxStIPSR - CxStIIP
  559. add tmp = CxContextFlags, a0
  560. (User) dep rpsr = 1, rpsr, PSR_PP, 1 // BUGBUG; force psr.pp to 1
  561. ;;
  562. st8.nta [addr0] = rpsr // save psr
  563. st8.nta [addr1] = rpfs
  564. or tmpbsp = tmpbsp, mask
  565. ;;
  566. mov ar.rsc = rrsc // restore RSC
  567. st4.nta [tmp] = flag
  568. mov ar.unat = runat // restore ar.unat
  569. st8.nta [tmpbsp] = rrnat
  570. (p0) br.ret.sptk brp // return to caller.
  571. LEAF_EXIT(RtlCaptureContext)
  572. //++
  573. //
  574. // VOID
  575. // RtlRestoreContext (
  576. // IN PCONTEXT ContextRecord,
  577. // IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL
  578. // )
  579. //
  580. // Routine Description:
  581. //
  582. // This function restores the context of the caller to the specified
  583. // context.
  584. //
  585. // N.B. The context record is assumed to be 16-byte aligned.
  586. //
  587. // N.B. This is a special routine that is used by RtlUnwind2 to restore
  588. // context in the current mode.
  589. //
  590. // N.B. RFI is used to resume execution in kernel mode.
  591. //
  592. // Arguments:
  593. //
  594. // ContextRecord (a0) - Supplies the address of a context record.
  595. //
  596. // ExceptionRecord (a1) - Supplies an optional pointer to an exception
  597. // record.
  598. //
  599. // Return Value:
  600. //
  601. // None.
  602. //
  603. // N.B. There is no return from this routine.
  604. //
  605. //--
  606. NESTED_ENTRY(RtlRestoreContext)
  607. dest1=t8
  608. dest2=t9
  609. rlc=t10
  610. rpreds=t11
  611. rbrp=t12
  612. rbsp=t13
  613. rpfs=t14
  614. runat=t15
  615. rpreds=t16
  616. rsp=t17
  617. rfpsr=t18
  618. jb=t19
  619. tmp=t20
  620. src1=t21
  621. src2=t22
  622. NESTED_SETUP(2, 13, 2, 0)
  623. cmp.eq pt1, p0 = zero, a1
  624. PROLOGUE_END
  625. //
  626. // If an exception record is specified and the exception status is the unwind
  627. // consolidation code and there is at least one parameter, then consolidate
  628. // all the frames that have been unwound and call back to a language specified
  629. // routine.
  630. //
  631. add t1 = ErNumberParameters, a1
  632. (pt1) br.cond.sptk.few Rrc10
  633. ;;
  634. ld4 t0 = [t1], ErExceptionCode - ErNumberParameters
  635. movl t3 = STATUS_UNWIND_CONSOLIDATE
  636. ;;
  637. cmp4.ne pt1, p0 = 0, t0
  638. ld4 t2 = [t1], ErExceptionInformation - ErExceptionCode
  639. ;;
  640. cmp4.eq.and pt1, p0 = t3, t2 // if ne, not a long jump
  641. movl t4 = STATUS_LONGJUMP
  642. ;;
  643. ld8 jb = [t1] // get address of jump buffer
  644. add loc2 = -STACK_SCRATCH_AREA, r32 // Create a vframe for context record.
  645. (pt1) br.cond.dptk.many RtlRcConsolidateFrames
  646. //
  647. // If exception status is STATUS_LONGJUMP, then restore the
  648. // nonvolatile registers to their state at the call to setjmp
  649. // before restoring the context record.
  650. //
  651. cmp4.ne pt1, p0 = t4, t2 // if ne, not a long jump
  652. (pt1) br.cond.sptk.few Rrc10
  653. ;;
  654. //
  655. // restore unat, non-volatile general and branch registers from
  656. // jump buffer and then save them in the context buffer.
  657. //
  658. add src1 = JbIntS0, jb
  659. add src2 = JbIntS1, jb
  660. nop.i 0
  661. ;;
  662. ld8.nt1 s0 = [src1], JbIntS2 - JbIntS0
  663. ld8.nt1 s1 = [src2], JbIntS3 - JbIntS1
  664. nop.i 0
  665. ;;
  666. ld8.nt1 s2 = [src1], JbIntSp - JbIntS2
  667. ld8.nt1 s3 = [src2], JbIntNats - JbIntS3
  668. nop.i 0
  669. ;;
  670. ld8.nt1 rsp = [src1], JbPreds - JbIntSp
  671. ld8.nt1 t2 = [src2]
  672. add t1 = 0x10f0, r0
  673. ;;
  674. ld8.nt1 rpreds = [src1]
  675. add loc11 = CxIntNats, a0
  676. and t2 = t2, t1
  677. ;;
  678. ld8 runat = [loc11]
  679. add dest1 = CxIntS0, a0
  680. add dest2 = CxIntS1, a0
  681. ;;
  682. st8 [dest1] = s0, CxIntS2 - CxIntS0
  683. st8 [dest2] = s1, CxIntS3 - CxIntS1
  684. nop.b 0
  685. ;;
  686. st8 [dest1] = s2, CxIntSp - CxIntS2
  687. st8 [dest2] = s3, CxPreds - CxIntS3
  688. andcm runat = runat, t1
  689. ;;
  690. st8 [dest1] = rsp
  691. st8 [dest2] = rpreds
  692. or runat = runat, t2
  693. ;;
  694. st8 [loc11] = runat
  695. add src1 = JbFltS0, jb
  696. add src2 = JbFltS1, jb
  697. ;;
  698. ldf.fill.nt1 fs0 = [src1], JbFltS2 - JbFltS0
  699. ldf.fill.nt1 fs1 = [src2], JbFltS3 - JbFltS1
  700. nop.i 0
  701. ;;
  702. ldf.fill.nt1 fs2 = [src1], JbFltS4 - JbFltS2
  703. ldf.fill.nt1 fs3 = [src2], JbFltS5 - JbFltS3
  704. nop.i 0
  705. ;;
  706. ldf.fill.nt1 fs4 = [src1], JbFltS6 - JbFltS4
  707. ldf.fill.nt1 fs5 = [src2], JbFltS7 - JbFltS5
  708. nop.i 0
  709. ;;
  710. ldf.fill.nt1 fs6 = [src1], JbFltS8 - JbFltS6
  711. ldf.fill.nt1 fs7 = [src2], JbFltS9 - JbFltS7
  712. nop.i 0
  713. ;;
  714. ldf.fill.nt1 fs8 = [src1], JbFltS10 - JbFltS8
  715. ldf.fill.nt1 fs9 = [src2], JbFltS11 - JbFltS9
  716. nop.i 0
  717. ;;
  718. ldf.fill.nt1 fs10 = [src1], JbFltS12 - JbFltS10
  719. ldf.fill.nt1 fs11 = [src2], JbFltS13 - JbFltS11
  720. nop.i 0
  721. ;;
  722. ldf.fill.nt1 fs12 = [src1], JbFltS14 - JbFltS12
  723. ldf.fill.nt1 fs13 = [src2], JbFltS15 - JbFltS13
  724. nop.i 0
  725. ;;
  726. ldf.fill.nt1 fs14 = [src1], JbFltS16 - JbFltS14
  727. ldf.fill.nt1 fs15 = [src2], JbFltS17 - JbFltS15
  728. nop.i 0
  729. ;;
  730. ldf.fill.nt1 fs16 = [src1], JbFltS18 - JbFltS16
  731. ldf.fill.nt1 fs17 = [src2], JbFltS19 - JbFltS17
  732. nop.i 0
  733. ;;
  734. ldf.fill.nt1 fs18 = [src1], JbFPSR - JbFltS18
  735. ldf.fill.nt1 fs19 = [src2]
  736. nop.i 0
  737. ;;
  738. ld8.nt1 rfpsr = [src1]
  739. add dest1 = CxFltS0, a0
  740. add dest2 = CxFltS1, a0
  741. ;;
  742. stf.spill [dest1] = fs0, CxFltS2 - CxFltS0
  743. stf.spill [dest2] = fs1, CxFltS3 - CxFltS1
  744. nop.i 0
  745. ;;
  746. stf.spill [dest1] = fs2, CxFltS4 - CxFltS2
  747. stf.spill [dest2] = fs3, CxFltS5 - CxFltS3
  748. nop.i 0
  749. ;;
  750. stf.spill [dest1] = fs4, CxFltS6 - CxFltS4
  751. stf.spill [dest2] = fs5, CxFltS7 - CxFltS5
  752. nop.i 0
  753. ;;
  754. stf.spill [dest1] = fs6, CxFltS8 - CxFltS6
  755. stf.spill [dest2] = fs7, CxFltS9 - CxFltS7
  756. nop.i 0
  757. ;;
  758. stf.spill [dest1] = fs8, CxFltS10 - CxFltS8
  759. stf.spill [dest2] = fs9, CxFltS11 - CxFltS9
  760. nop.i 0
  761. ;;
  762. stf.spill [dest1] = fs10, CxFltS12 - CxFltS10
  763. stf.spill [dest2] = fs11, CxFltS13 - CxFltS11
  764. nop.i 0
  765. ;;
  766. stf.spill [dest1] = fs12, CxFltS14 - CxFltS12
  767. stf.spill [dest2] = fs13, CxFltS15 - CxFltS13
  768. nop.i 0
  769. ;;
  770. stf.spill [dest1] = fs14, CxFltS16 - CxFltS14
  771. stf.spill [dest2] = fs15, CxFltS17 - CxFltS15
  772. nop.i 0
  773. ;;
  774. stf.spill [dest1] = fs16, CxFltS18 - CxFltS16
  775. stf.spill [dest2] = fs17, CxFltS19 - CxFltS17
  776. nop.i 0
  777. ;;
  778. stf.spill [dest1] = fs18
  779. stf.spill [dest2] = fs19
  780. add dest1 = CxStFPSR, a0
  781. ;;
  782. st8 [dest1] = rfpsr
  783. add src1 = JbStIIP, jb
  784. add src2 = JbBrS0, jb
  785. ;;
  786. ld8.nt1 loc11 = [src1], JbBrS1 - JbStIIP
  787. ld8.nt1 loc12 = [src2], JbBrS2 - JbBrS0
  788. ;;
  789. ld8.nt1 loc2 = [src1], JbBrS3 - JbBrS1
  790. ld8.nt1 loc3 = [src2], JbBrS4 - JbBrS2
  791. ;;
  792. ld8.nt1 loc4 = [src1], JbRsBSP - JbBrS3
  793. ld8.nt1 loc5 = [src2], JbRsPFS - JbBrS4
  794. ;;
  795. ld8.nt1 rbsp = [src1], JbApUNAT - JbRsBSP
  796. ld8.nt1 rpfs = [src2], JbApLC - JbRsPFS
  797. ;;
  798. ld8.nt1 runat = [src1]
  799. add dest1 = CxStIIP, a0
  800. add dest2 = CxBrS0, a0
  801. ld8.nt1 rlc = [src2]
  802. movl t0 = 1 << IFS_V
  803. ;;
  804. st8 [dest1] = loc11, CxBrS1 - CxStIIP
  805. st8 [dest2] = loc12, CxBrS2 - CxBrS0
  806. or rpfs = t0, rpfs // validate the ifs
  807. ;;
  808. st8 [dest1] = loc2, CxBrS3 - CxBrS1
  809. st8 [dest2] = loc3, CxBrS4 - CxBrS2
  810. ;;
  811. st8 [dest1] = loc4, CxApUNAT - CxBrS3
  812. st8 [dest2] = loc5, CxStIFS - CxBrS4
  813. ;;
  814. st8 [dest1] = runat, CxRsBSP - CxApUNAT
  815. st8 [dest2] = rpfs, CxApLC - CxStIFS
  816. ;;
  817. st8 [dest2] = rlc
  818. st8 [dest1] = rbsp
  819. ;;
  820. //
  821. // If the call is from user mode, then use the continue system service to
  822. // continue execution. Otherwise, restore the context directly since the
  823. // current mode is kernel and threads can't be arbitrarily interrupted.
  824. //
  825. Rrc10:
  826. #ifndef NTOS_KERNEL_RUNTIME
  827. mov out0 = a0
  828. mov out1 = zero
  829. br.call.sptk.few brp = ZwContinue
  830. #else
  831. //
  832. // Kernel mode; simply restore the registers and rfi
  833. //
  834. add src1 = CxIntNats, a0
  835. add src2 = CxPreds, a0
  836. add tmp = CxIntGp, a0
  837. ;;
  838. ld8.nt1 t17 = [src1], CxBrRp - CxIntNats
  839. ld8.nt1 t16 = [src2], CxBrS0 - CxPreds
  840. shr tmp = tmp, 3
  841. ;;
  842. ld8.nt1 t0 = [src1], CxBrS1 - CxBrRp
  843. ld8.nt1 t1 = [src2], CxBrS2 - CxBrS0
  844. and tmp = 0x3f, tmp
  845. ;;
  846. ld8.nt1 t2 = [src1], CxBrS3 - CxBrS1
  847. ld8.nt1 t3 = [src2], CxBrS4 - CxBrS2
  848. cmp4.ge pt1, pt0 = 1, tmp
  849. ;;
  850. ld8.nt1 t4 = [src1], CxBrT0 - CxBrS3
  851. ld8.nt1 t5 = [src2], CxBrT1 - CxBrS4
  852. (pt1) sub loc5 = 1, tmp
  853. ;;
  854. ld8.nt1 t6 = [src1], CxApUNAT - CxBrT0
  855. ld8.nt1 t7 = [src2], CxApLC - CxBrT1
  856. (pt0) add loc5 = -1, tmp
  857. ;;
  858. ld8.nt1 loc11 = [src1], CxApEC - CxApUNAT
  859. ld8.nt1 t8 = [src2], CxApCCV - CxApLC
  860. (pt0) sub loc6 = 65, tmp
  861. ;;
  862. ld8.nt1 t9 = [src1], CxApDCR - CxApEC
  863. ld8.nt1 t10 = [src2], CxRsPFS - CxApCCV
  864. (pt1) shr.u t17 = t17, loc5
  865. ;;
  866. ld8.nt1 loc12 = [src1], CxRsBSP - CxApDCR
  867. ld8.nt1 t11 = [src2], CxRsRSC - CxRsPFS
  868. (pt0) shl loc7 = t17, loc5
  869. ;;
  870. ld8.nt1 loc2 = [src1], CxStIIP - CxRsBSP
  871. ld8.nt1 loc3 = [src2], CxStIFS - CxRsRSC
  872. (pt0) shr.u loc8 = t17, loc6
  873. ;;
  874. ld8.nt1 loc9 = [src1]
  875. ld8.nt1 loc10 = [src2]
  876. (pt0) or t17 = loc7, loc8
  877. ;;
  878. mov ar.unat = t17
  879. add src1 = CxFltS0, a0
  880. shr t12 = loc2, 3
  881. ;;
  882. add src2 = CxFltS1, a0
  883. and t12 = 0x3f, t12 // current rnat save index
  884. and t13 = 0x7f, loc10 // total frame size
  885. ;;
  886. mov ar.ccv = t10
  887. add t14 = t13, t12
  888. mov ar.pfs = t11
  889. ;;
  890. Rrc20:
  891. cmp4.gt pt1, pt0 = 63, t14
  892. ;;
  893. (pt0) add t14 = -63, t14
  894. (pt0) add t13 = 1, t13
  895. ;;
  896. nop.m 0
  897. (pt1) shl t13 = t13, 3
  898. (pt0) br.cond.spnt Rrc20
  899. ;;
  900. add loc2 = loc2, t13
  901. nop.f 0
  902. mov pr = t16, -1
  903. ldf.fill.nt1 fs0 = [src1], CxFltS2 - CxFltS0
  904. ldf.fill.nt1 fs1 = [src2], CxFltS3 - CxFltS1
  905. mov brp = t0
  906. ;;
  907. ldf.fill.nt1 fs2 = [src1], CxFltT0 - CxFltS2
  908. ldf.fill.nt1 fs3 = [src2], CxFltT1 - CxFltS3
  909. mov bs0 = t1
  910. ;;
  911. ldf.fill.nt1 ft0 = [src1], CxFltT2 - CxFltT0
  912. ldf.fill.nt1 ft1 = [src2], CxFltT3 - CxFltT1
  913. mov bs1 = t2
  914. ;;
  915. ldf.fill.nt1 ft2 = [src1], CxFltT4 - CxFltT2
  916. ldf.fill.nt1 ft3 = [src2], CxFltT5 - CxFltT3
  917. mov bs2 = t3
  918. ;;
  919. ldf.fill.nt1 ft4 = [src1], CxFltT6 - CxFltT4
  920. ldf.fill.nt1 ft5 = [src2], CxFltT7 - CxFltT5
  921. mov bs3 = t4
  922. ;;
  923. ldf.fill.nt1 ft6 = [src1], CxFltT8 - CxFltT6
  924. ldf.fill.nt1 ft7 = [src2], CxFltT9 - CxFltT7
  925. mov bs4 = t5
  926. ;;
  927. ldf.fill.nt1 ft8 = [src1], CxFltS4 - CxFltT8
  928. ldf.fill.nt1 ft9 = [src2], CxFltS5 - CxFltT9
  929. mov bt0 = t6
  930. ;;
  931. ldf.fill.nt1 fs4 = [src1], CxFltS6 - CxFltS4
  932. ldf.fill.nt1 fs5 = [src2], CxFltS7 - CxFltS5
  933. mov bt1 = t7
  934. ;;
  935. ldf.fill.nt1 fs6 = [src1], CxFltS8 - CxFltS6
  936. ldf.fill.nt1 fs7 = [src2], CxFltS9 - CxFltS7
  937. mov ar.lc = t8
  938. ;;
  939. ldf.fill.nt1 fs8 = [src1], CxFltS10 - CxFltS8
  940. ldf.fill.nt1 fs9 = [src2], CxFltS11 - CxFltS9
  941. mov ar.ec = t9
  942. ;;
  943. ldf.fill.nt1 fs10 = [src1], CxFltS12 - CxFltS10
  944. ldf.fill.nt1 fs11 = [src2], CxFltS13 - CxFltS11
  945. nop.i 0
  946. ;;
  947. ldf.fill.nt1 fs12 = [src1], CxFltS14 - CxFltS12
  948. ldf.fill.nt1 fs13 = [src2], CxFltS15 - CxFltS13
  949. add loc6 = CxIntGp, a0
  950. ;;
  951. ldf.fill.nt1 fs14 = [src1], CxFltS16 - CxFltS14
  952. ldf.fill.nt1 fs15 = [src2], CxFltS17 - CxFltS15
  953. add loc7 = CxIntT0, a0
  954. ;;
  955. ldf.fill.nt1 fs16 = [src1], CxFltS18 - CxFltS16
  956. ldf.fill.nt1 fs17 = [src2], CxFltS19 - CxFltS17
  957. add t19 = CxRsRNAT, a0
  958. ;;
  959. ldf.fill.nt1 fs18 = [src1]
  960. ldf.fill.nt1 fs19 = [src2]
  961. add t7 = CxStFPSR, a0
  962. ;;
  963. ld8.nt1 loc8 = [t7] // load fpsr from context
  964. ld8.nt1 loc5 = [t19] // load rnat from context
  965. nop.i 0
  966. ld8.fill.nt1 gp = [loc6], CxIntT1 - CxIntGp
  967. ld8.fill.nt1 t0 = [loc7], CxIntS0 - CxIntT0
  968. ;;
  969. ld8.fill.nt1 t1 = [loc6], CxIntS1 - CxIntT1
  970. ld8.fill.nt1 s0 = [loc7], CxIntS2 - CxIntS0
  971. ;;
  972. ld8.fill.nt1 s1 = [loc6], CxIntS3 - CxIntS1
  973. ld8.fill.nt1 s2 = [loc7], CxIntV0 - CxIntS2
  974. ;;
  975. ld8.fill.nt1 s3 = [loc6], CxIntTeb - CxIntS3
  976. ld8.fill.nt1 v0 = [loc7], CxIntT2 - CxIntV0
  977. ;;
  978. ld8.fill.nt1 teb = [loc6], CxIntT3 - CxIntTeb
  979. ld8.fill.nt1 t2 = [loc7], CxIntSp - CxIntT2
  980. ;;
  981. ld8.fill.nt1 t3 = [loc6], CxIntT4 - CxIntT3
  982. ld8.fill.nt1 loc4 = [loc7], CxIntT5 - CxIntSp
  983. ;;
  984. ld8.fill.nt1 t4 = [loc6], CxIntT6 - CxIntT4
  985. ld8.fill.nt1 t5 = [loc7], CxIntT7 - CxIntT5
  986. ;;
  987. ld8.fill.nt1 t6 = [loc6], CxIntT8 - CxIntT6
  988. ld8.fill.nt1 t7 = [loc7], CxIntT9 - CxIntT7
  989. ;;
  990. ld8.fill.nt1 t8 = [loc6], CxIntT10 - CxIntT8
  991. ld8.fill.nt1 t9 = [loc7], CxIntT11 - CxIntT9
  992. ;;
  993. ld8.fill.nt1 t10 = [loc6], CxIntT12 - CxIntT10
  994. ld8.fill.nt1 t11 = [loc7], CxIntT13 - CxIntT11
  995. ;;
  996. ld8.fill.nt1 t12 = [loc6], CxIntT14 - CxIntT12
  997. ld8.fill.nt1 t13 = [loc7], CxIntT15 - CxIntT13
  998. ;;
  999. ld8.fill.nt1 t14 = [loc6], CxIntT16 - CxIntT14
  1000. ld8.fill.nt1 t15 = [loc7], CxIntT17 - CxIntT15
  1001. ;;
  1002. ld8.fill.nt1 t16 = [loc6], CxIntT18 - CxIntT16
  1003. ld8.fill.nt1 t17 = [loc7], CxIntT19 - CxIntT17
  1004. ;;
  1005. ld8.fill.nt1 t18 = [loc6], CxIntT20 - CxIntT18
  1006. ld8.fill.nt1 t19 = [loc7], CxIntT21 - CxIntT19
  1007. ;;
  1008. ld8.fill.nt1 t20 = [loc6], CxIntT22 - CxIntT20
  1009. ld8.fill.nt1 t21 = [loc7]
  1010. ;;
  1011. rsm 1 << PSR_I
  1012. ld8.fill.nt1 t22 = [loc6]
  1013. ;;
  1014. bsw.0
  1015. ;;
  1016. add r20 = CxStIPSR, a0
  1017. ;;
  1018. ld8.nt1 r20 = [r20] // load IPSR
  1019. movl r23 = 1 << IFS_V
  1020. ;;
  1021. mov ar.fpsr = loc8 // set fpsr
  1022. mov ar.unat = loc11
  1023. ;;
  1024. or r21 = r23, loc10 // set ifs valid bit
  1025. ;;
  1026. mov cr.dcr = loc12
  1027. mov r17 = loc2 // put BSP in a shadow reg
  1028. or r16 = 0x3, loc3 // put RSE in eager mode
  1029. mov ar.rsc = r0 // put RSE in enforced lazy
  1030. mov r22 = loc9 // put iip in a shadow reg
  1031. dep r21 = 0, r21, IFS_MBZ0, IFS_V-IFS_MBZ0
  1032. ;;
  1033. mov r18 = loc4 // put SP in a shadow reg
  1034. mov r19 = loc5 // put RNaTs in a shadow reg
  1035. ;;
  1036. alloc r23 = 0, 0, 0, 0
  1037. mov sp = r18
  1038. ;;
  1039. loadrs
  1040. ;;
  1041. rsm 1 << PSR_IC
  1042. ;;
  1043. srlz.d
  1044. ;;
  1045. mov cr.iip = r22
  1046. mov cr.ifs = r21
  1047. ;;
  1048. mov ar.bspstore = r17
  1049. mov cr.ipsr = r20
  1050. nop.i 0
  1051. ;;
  1052. mov ar.rnat = r19 // set rnat register
  1053. mov ar.rsc = r16 // restore RSC
  1054. ;;
  1055. invala
  1056. nop.i 0
  1057. rfi
  1058. ;;
  1059. #endif // NTOS_KERNEL_RUNTIME
  1060. LEAF_EXIT(RtlRestoreContext)
  1061. //++
  1062. //
  1063. // VOID
  1064. // RtlpFlushRSE (
  1065. // OUT PULONGLONG Bsp,
  1066. // OUT PULONGLONG Rnat
  1067. // )
  1068. //
  1069. // Routine Description:
  1070. //
  1071. // This function flushes the RSE, then captures the values of bsp
  1072. // and rnat into the input buffers.
  1073. //
  1074. // Arguments:
  1075. //
  1076. // Return Value:
  1077. //
  1078. // None.
  1079. //
  1080. //--
  1081. LEAF_ENTRY(RtlpFlushRSE)
  1082. flushrs
  1083. mov t2 = ar.rsc
  1084. ;;
  1085. mov t0 = ar.bsp
  1086. mov ar.rsc = r0 // put RSE in lazy mode
  1087. ;;
  1088. st8 [a0] = t0
  1089. mov t1 = ar.rnat
  1090. nop.i 0
  1091. ;;
  1092. st8 [a1] = t1
  1093. mov ar.rsc = t2
  1094. ;;
  1095. br.ret.sptk brp
  1096. LEAF_EXIT(RtlpFlushRSE)
  1097. //++
  1098. //
  1099. // VOID
  1100. // RtlRcConsolidateFrames (
  1101. // IN PCONTEXT ContextRecord
  1102. // IN PEXCEPTION_RECORD ExceptionRecord
  1103. // )
  1104. //
  1105. // Routine Description:
  1106. //
  1107. // This routine is called at the end of a unwind operation to logically
  1108. // remove unwound frames from the stack. This is accomplished by specifing
  1109. // the variable frame pointer and a context ABI unwind.
  1110. //
  1111. // The following code calls the language call back function specified in the
  1112. // exception record. If the function returns, then the destination frame
  1113. // context is restored and control transfered to the address returned by the
  1114. // language call back function. If control does not return, then another
  1115. // exception must be raised.
  1116. //
  1117. // Arguments:
  1118. //
  1119. // ContextRecord - Supplies a pointer to the context record.
  1120. //
  1121. // ExceptionRecord - Supplies a pointer to an exception record.
  1122. //
  1123. // Implicit Arguments:
  1124. //
  1125. // Virtual frame pointer (r34) - Supplies a pointer to the context record minus the stack area.
  1126. //
  1127. // LanguageSpecificHandler (jb) - Supplies a pointer to the language specific handler
  1128. //
  1129. // Return Value:
  1130. //
  1131. // None.
  1132. //
  1133. //--
  1134. .global RtlRcConsolidateFrames;
  1135. .proc RtlRcConsolidateFrames;
  1136. RtlRcConsolidateFrames::
  1137. .prologue
  1138. .unwabi @nt, CONTEXT_FRAME
  1139. .regstk 2, 13, 2, 0
  1140. .vframe loc2 // Specify that r32 content the saved sp
  1141. PROLOGUE_END
  1142. ld8 t3 = [jb], 8
  1143. add loc3 = CxStIIP, a0
  1144. ;;
  1145. ld8 gp = [jb]
  1146. mov bt0 = t3
  1147. ;;
  1148. mov out0 = a1 // Pass exception record as argument.
  1149. br.call.sptk brp = bt0
  1150. ;;
  1151. //
  1152. // The language specific handler retuns the address where control
  1153. // should be returned using the passed context. Update the context
  1154. // record with the new address.
  1155. //
  1156. st8 [loc3] = r8
  1157. br.cond.sptk Rrc10
  1158. ;;
  1159. LEAF_EXIT(RtlRcConsolidateFrames)