tbidefr.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * tbidefr.S
  3. *
  4. * Copyright (C) 2009, 2012 Imagination Technologies.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU General Public License version 2 as published by the
  8. * Free Software Foundation.
  9. *
  10. * Routing deferred exceptions
  11. */
  12. #include <asm/metag_regs.h>
  13. #include <asm/tbx.h>
  14. .text
  15. .balign 4
  16. .global ___TBIHandleDFR
  17. .type ___TBIHandleDFR,function
  18. /* D1Ar1:D0Ar2 -- State
  19. * D0Ar3 -- SigNum
  20. * D0Ar4 -- Triggers
  21. * D1Ar5 -- Inst
  22. * D0Ar6 -- pTBI (volatile)
  23. */
  24. ___TBIHandleDFR:
  25. #ifdef META_BUG_MBN100212
  26. MSETL [A0StP++], D0FrT, D0.5
  27. /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved
  28. * D0Ar4 -- The deferred exceptions
  29. * D1Ar3 -- As per D0Ar4 but just the trigger bits
  30. * D0.5 -- The bgnd deferred exceptions
  31. * D1.5 -- TXDEFR with bgnd re-added
  32. */
  33. /* - Collect the pending deferred exceptions using TXSTAT,
  34. * (ack's the bgnd exceptions as a side-effect)
  35. * - Manually collect remaining (interrupt) deferred exceptions
  36. * using TXDEFR
  37. * - Replace the triggers (from TXSTATI) with the int deferred
  38. * exceptions DEFR ..., TXSTATI would have returned if it was valid
  39. * from bgnd code
  40. * - Reconstruct TXDEFR by or'ing bgnd deferred exceptions (except
  41. * the DEFER bit) and the int deferred exceptions. This will be
  42. * restored later
  43. */
  44. DEFR D0.5, TXSTAT
  45. MOV D1.5, TXDEFR
  46. ANDT D0.5, D0.5, #HI(0xFFFF0000)
  47. MOV D1Ar3, D1.5
  48. ANDT D1Ar3, D1Ar3, #HI(0xFFFF0000)
  49. OR D0Ar4, D1Ar3, #TXSTAT_DEFER_BIT
  50. OR D1.5, D1.5, D0.5
  51. /* Mask off anything unrelated to the deferred exception triggers */
  52. ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS)
  53. /* Can assume that at least one exception happened since this
  54. * handler wouldnt have been called otherwise.
  55. *
  56. * Replace the signal number and at the same time, prepare
  57. * the mask to acknowledge the exception
  58. *
  59. * D1Re0 -- The bits to acknowledge
  60. * D1Ar3 -- The signal number
  61. * D1RtP -- Scratch to deal with non-conditional insns
  62. */
  63. MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT)
  64. MOV D1RtP, #TXSTAT_FPE_INVALID_S
  65. FFB D1Ar3, D1Ar3
  66. CMP D1Ar3, #TXSTAT_FPE_INVALID_S
  67. MOVLE D1Ar3, D1RtP /* Collapse FPE triggers to a single signal */
  68. MOV D1RtP, #1
  69. LSLGT D1Re0, D1RtP, D1Ar3
  70. /* Get the handler using the signal number
  71. *
  72. * D1Ar3 -- The signal number
  73. * D0Re0 -- Offset into TBI struct containing handler address
  74. * D1Re0 -- Mask of triggers to keep
  75. * D1RtP -- Address of handler
  76. */
  77. SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE)
  78. LSL D0Re0, D1Ar3, #2
  79. XOR D1Re0, D1Re0, #-1 /* Prepare mask for acknowledge (avoids stall) */
  80. ADD D0Re0,D0Re0,#TBI_fnSigs
  81. GETD D1RtP, [D0Ar6+D0Re0]
  82. /* Acknowledge triggers */
  83. AND D1.5, D1.5, D1Re0
  84. /* Restore remaining exceptions
  85. * Do this here in case the handler enables nested interrupts
  86. *
  87. * D1.5 -- TXDEFR with this exception ack'd
  88. */
  89. MOV TXDEFR, D1.5
  90. /* Call the handler */
  91. SWAP D1RtP, PC
  92. GETL D0.5, D1.5, [--A0StP]
  93. GETL D0FrT, D1RtP, [--A0StP]
  94. MOV PC,D1RtP
  95. #else /* META_BUG_MBN100212 */
  96. /* D1Ar1,D0Ar2,D1Ar5,D0Ar6 -- Arguments to handler, must be preserved
  97. * D0Ar4 -- The deferred exceptions
  98. * D1Ar3 -- As per D0Ar4 but just the trigger bits
  99. */
  100. /* - Collect the pending deferred exceptions using TXSTAT,
  101. * (ack's the interrupt exceptions as a side-effect)
  102. */
  103. DEFR D0Ar4, TXSTATI
  104. /* Mask off anything unrelated to the deferred exception triggers */
  105. MOV D1Ar3, D0Ar4
  106. ANDT D1Ar3, D1Ar3, #HI(TXSTAT_BUSERR_BIT | TXSTAT_FPE_BITS)
  107. /* Can assume that at least one exception happened since this
  108. * handler wouldnt have been called otherwise.
  109. *
  110. * Replace the signal number and at the same time, prepare
  111. * the mask to acknowledge the exception
  112. *
  113. * The unusual code for 1<<D1Ar3 may need explanation.
  114. * Normally this would be done using 'MOV rs,#1' and 'LSL rd,rs,D1Ar3'
  115. * but only D1Re0 is available in D1 and no crossunit insns are available
  116. * Even worse, there is no conditional 'MOV r,#uimm8'.
  117. * Since the CMP proves that D1Ar3 >= 20, we can reuse the bottom 12-bits
  118. * of D1Re0 (using 'ORGT r,#1') in the knowledge that the top 20-bits will
  119. * be discarded without affecting the result.
  120. *
  121. * D1Re0 -- The bits to acknowledge
  122. * D1Ar3 -- The signal number
  123. */
  124. MOVT D1Re0, #HI(TXSTAT_FPE_BITS & ~TXSTAT_FPE_DENORMAL_BIT)
  125. MOV D0Re0, #TXSTAT_FPE_INVALID_S
  126. FFB D1Ar3, D1Ar3
  127. CMP D1Ar3, #TXSTAT_FPE_INVALID_S
  128. MOVLE D1Ar3, D0Re0 /* Collapse FPE triggers to a single signal */
  129. ORGT D1Re0, D1Re0, #1
  130. LSLGT D1Re0, D1Re0, D1Ar3
  131. SUB D1Ar3, D1Ar3, #(TXSTAT_FPE_INVALID_S - TBID_SIGNUM_FPE)
  132. /* Acknowledge triggers and restore remaining exceptions
  133. * Do this here in case the handler enables nested interrupts
  134. *
  135. * (x | y) ^ y == x & ~y. It avoids the restrictive XOR ...,#-1 insn
  136. * and is the same length
  137. */
  138. MOV D0Re0, TXDEFR
  139. OR D0Re0, D0Re0, D1Re0
  140. XOR TXDEFR, D0Re0, D1Re0
  141. /* Get the handler using the signal number
  142. *
  143. * D1Ar3 -- The signal number
  144. * D0Re0 -- Address of handler
  145. */
  146. LSL D0Re0, D1Ar3, #2
  147. ADD D0Re0,D0Re0,#TBI_fnSigs
  148. GETD D0Re0, [D0Ar6+D0Re0]
  149. /* Tailcall the handler */
  150. MOV PC,D0Re0
  151. #endif /* META_BUG_MBN100212 */
  152. .size ___TBIHandleDFR,.-___TBIHandleDFR
  153. /*
  154. * End of tbidefr.S
  155. */