or1k-asm-test.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /* Testsuite architecture macros for OpenRISC.
  2. Copyright (C) 2017-2022 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #ifndef OR1K_ASM_TEST_H
  14. #define OR1K_ASM_TEST_H
  15. #include "spr-defs.h"
  16. /* Register definitions */
  17. /* The "jump and link" instructions store the return address in R9. */
  18. #define LINK_REGISTER_R9 r9
  19. /* These register definitions match the ABI. */
  20. #define ZERO_R0 r0
  21. #define STACK_POINTER_R1 r1
  22. #define FRAME_POINTER_R2 r2
  23. #define RETURN_VALUE_R11 r11
  24. /* Load/move/clear helpers */
  25. .macro LOAD_IMMEDIATE reg, val
  26. l.movhi \reg, hi ( \val )
  27. l.ori \reg, \reg, lo ( \val )
  28. .endm
  29. .macro MOVE_REG dest_reg, src_reg
  30. .ifnes "\dest_reg","\src_reg"
  31. l.ori \dest_reg, \src_reg, 0
  32. .endif
  33. .endm
  34. .macro CLEAR_REG reg
  35. l.movhi \reg, 0
  36. .endm
  37. .macro MOVE_FROM_SPR reg, spr_reg
  38. l.mfspr \reg, ZERO_R0, \spr_reg
  39. .endm
  40. .macro MOVE_TO_SPR spr_reg, reg
  41. l.mtspr ZERO_R0, \reg, \spr_reg
  42. .endm
  43. .macro SET_SPR_SR_FLAGS flag_mask, scratch_reg_1, scratch_reg_2
  44. /* We cannot use PUSH and POP here because some flags like Carry
  45. would get overwritten. */
  46. /* We could optimise this routine, as instruction l.mtspr already
  47. does a logical OR. */
  48. MOVE_FROM_SPR \scratch_reg_2, SPR_SR
  49. LOAD_IMMEDIATE \scratch_reg_1, \flag_mask
  50. l.or \scratch_reg_2, \scratch_reg_2, \scratch_reg_1
  51. MOVE_TO_SPR SPR_SR, \scratch_reg_2
  52. .endm
  53. .macro CLEAR_SPR_SR_FLAGS flag_mask, scratch_reg_1, scratch_reg_2
  54. /* We cannot use PUSH and POP here because some flags like Carry
  55. would get overwritten. */
  56. MOVE_FROM_SPR \scratch_reg_2, SPR_SR
  57. LOAD_IMMEDIATE \scratch_reg_1, ~\flag_mask
  58. l.and \scratch_reg_2, \scratch_reg_2, \scratch_reg_1
  59. MOVE_TO_SPR SPR_SR, \scratch_reg_2
  60. .endm
  61. /* Stack helpers */
  62. /* This value is defined in the OpenRISC 1000 specification. */
  63. #define EXCEPTION_STACK_SKIP_SIZE 128
  64. /* WARNING: Functions without prolog cannot use these PUSH or POP
  65. macros.
  66. PERFORMANCE WARNING: These PUSH/POP macros are convenient, but
  67. can lead to slow code. If you need to PUSH or POP several
  68. registers, it's faster to use non-zero offsets when
  69. loading/storing and then increment/decrement the stack pointer
  70. just once. */
  71. .macro PUSH reg
  72. l.addi STACK_POINTER_R1, STACK_POINTER_R1, -4
  73. l.sw 0(STACK_POINTER_R1), \reg
  74. .endm
  75. /* WARNING: see the warnings for PUSH. */
  76. .macro POP reg
  77. l.lwz \reg, 0(STACK_POINTER_R1)
  78. l.addi STACK_POINTER_R1, STACK_POINTER_R1, 4
  79. .endm
  80. /* l.nop definitions for simulation control and console output. */
  81. /* Register definitions for the simulation l.nop codes. */
  82. #define NOP_REPORT_R3 r3
  83. #define NOP_EXIT_R3 r3
  84. /* SEC = Simulation Exit Code */
  85. #define SEC_SUCCESS 0
  86. #define SEC_RETURNED_FROM_MAIN 1
  87. #define SEC_GENERIC_ERROR 2
  88. /* When running under the simulator, this l.nop code terminates the
  89. simulation. */
  90. .macro EXIT_SIMULATION_WITH_IMMEDIATE_EXIT_CODE immediate_value
  91. LOAD_IMMEDIATE NOP_EXIT_R3, \immediate_value
  92. l.nop 1
  93. .endm
  94. .macro EXIT_SIMULATION_WITH_REG_EXIT_CODE reg
  95. MOVE_REG NOP_EXIT_R3, \reg
  96. l.nop 1
  97. .endm
  98. /* When running under the simulator, this l.nop code prints the
  99. value of R3 to the console. */
  100. .macro REPORT_TO_CONSOLE
  101. l.nop 2
  102. .endm
  103. /* NOTE: The stack must be set up, as this macro uses PUSH and POP. */
  104. .macro REPORT_REG_TO_CONSOLE reg
  105. .ifeqs "\reg","r3"
  106. /* Nothing more to do here, R3 is the register that gets printed. */
  107. REPORT_TO_CONSOLE
  108. .else
  109. PUSH NOP_REPORT_R3
  110. MOVE_REG NOP_REPORT_R3, \reg
  111. REPORT_TO_CONSOLE
  112. POP NOP_REPORT_R3
  113. .endif
  114. .endm
  115. /* NOTE: The stack must be set up, as this macro uses PUSH and POP. */
  116. .macro REPORT_IMMEDIATE_TO_CONSOLE val
  117. PUSH NOP_REPORT_R3
  118. LOAD_IMMEDIATE NOP_REPORT_R3, \val
  119. REPORT_TO_CONSOLE
  120. POP NOP_REPORT_R3
  121. .endm
  122. .macro PRINT_NEWLINE_TO_CONSOLE
  123. PUSH r3
  124. LOAD_IMMEDIATE r3, 0x0A
  125. l.nop 4
  126. POP r3
  127. .endm
  128. /* If SR[F] is set, writes 0x00000001 to the console, otherwise it
  129. writes 0x00000000. */
  130. .macro REPORT_SRF_TO_CONSOLE
  131. OR1K_DELAYED_NOP (l.bnf \@1$)
  132. REPORT_IMMEDIATE_TO_CONSOLE 0x00000001
  133. OR1K_DELAYED_NOP (l.j \@2$)
  134. \@1$:
  135. REPORT_IMMEDIATE_TO_CONSOLE 0x00000000
  136. \@2$:
  137. .endm
  138. /* If the given register is 0, writes 0x00000000 to the console,
  139. otherwise it writes 0x00000001. */
  140. .macro REPORT_BOOL_TO_CONSOLE reg
  141. l.sfne \reg, ZERO_R0
  142. REPORT_SRF_TO_CONSOLE
  143. .endm
  144. /* Writes to the console the value of the given register bit. */
  145. .macro REPORT_BIT_TO_CONSOLE reg, single_bit_mask
  146. PUSH r2
  147. PUSH r3
  148. PUSH r4
  149. MOVE_REG r2, \reg
  150. LOAD_IMMEDIATE r4, \single_bit_mask
  151. l.and r3, r2, r4
  152. REPORT_BOOL_TO_CONSOLE r3
  153. POP r4
  154. POP r3
  155. POP r2
  156. .endm
  157. /* Jump helpers */
  158. .macro CALL overwritten_reg, subroutine_name
  159. LOAD_IMMEDIATE \overwritten_reg, \subroutine_name
  160. OR1K_DELAYED_NOP (l.jalr \overwritten_reg)
  161. .endm
  162. .macro RETURN_TO_LINK_REGISTER_R9
  163. OR1K_DELAYED_NOP (l.jr LINK_REGISTER_R9)
  164. .endm
  165. /* Clear the BSS section on start-up */
  166. .macro CLEAR_BSS overwritten_reg1, overwritten_reg2
  167. LOAD_IMMEDIATE \overwritten_reg1, _bss_begin
  168. LOAD_IMMEDIATE \overwritten_reg2, _bss_end
  169. l.sfgeu \overwritten_reg1, \overwritten_reg2
  170. OR1K_DELAYED_NOP (l.bf bss_is_empty)
  171. bss_clear_loop:
  172. /* Possible optimisation to investigate:
  173. move "l.sw 0(\overwritten_reg1), r0" to the jump delay slot as
  174. "l.sw -4(\overwritten_reg1), r0" or similar. But keep in mind that
  175. there are plans to remove the jump delay slot. */
  176. l.sw 0(\overwritten_reg1), r0
  177. l.addi \overwritten_reg1, \overwritten_reg1, 4
  178. l.sfgtu \overwritten_reg2, \overwritten_reg1
  179. OR1K_DELAYED_NOP (l.bf bss_clear_loop)
  180. bss_is_empty:
  181. .endm
  182. #endif /* OR1K_ASM_TEST_H */