NM_Macros.S 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. ;------------------------------
  2. ; Macros I: Faux Instructions
  3. ;
  4. ; The following "faux instructions" are
  5. ; implemented here as macros:
  6. ;
  7. ; MOVIP register,constant MOVI with optional PFX & MOVHI, or BGEN
  8. ; ADDIP register,constant PFX and ADDI with optional PFX
  9. ; SUBIP register,constant PFX and SUBI with optional PFX
  10. ; CMPIP register,constant PFX and CMPI with optional PFX
  11. ;
  12. ; MOVI16 register,constant PFX and MOVI
  13. ; MOVI32 register,constant PFX, MOVI, PFX, and MOVHI
  14. ; MOVIA register,constant PFX and MOVHI on Nios32, and PFX and MOVI
  15. ;
  16. ; ANDIP register,constant PFX and ANDI
  17. ; ANDNIP register,constant PFX and ANDN
  18. ; ORIP register,constant PFX and ORI
  19. ; XORIP register,constant PFX and XORI
  20. ;
  21. ; _BSR address MOVIP address to %g7, and CALL
  22. ; _BR address MOVIP address to %g7, and JMP
  23. ;
  24. ; BEQ address SKPS cc_nz and BR, has delay slot
  25. ; BNE address SKPS cc_z and BR, has delay slot
  26. ; BLE address SKPS cc_gt and BR, has delay slot
  27. ; BLT address SKPS cc_ge and BR, has delay slot
  28. ; RESTRET RESTORE and JMP %i7
  29. ;
  30. ;-------------------------------
  31. ; Macros II: Printing
  32. ;
  33. ; These macros are guaranteed *not*
  34. ; to have branch delay slot after them.
  35. ;
  36. ; NM_PrintChar char
  37. ; NM_Print "string"
  38. ; NM_PrintLn "string" Follows it with a carriage return
  39. ; NM_PrintRegister reg For debugging, prints register name & value
  40. ;
  41. ;-------------------------------
  42. ; Macros III: Inline Debugging
  43. ;
  44. ; These macros print various information
  45. ; using large sections of expanded inline code.
  46. ; They each use either few or no registers.
  47. ; Thus, they may be safely used in interrupt handlers.
  48. ;
  49. ; NM_D_TxChar char print char to UART, affects no registers
  50. ; NM_D_TxRegister char,char,register prints the two characters, and the hex register value
  51. ; --------------------------------------
  52. .macro _pfx_op OP,reg,val,pForce=0
  53. .if (\pForce) || ((\val) > (31)) || ((\val) < (0))
  54. PFX %hi(\val)
  55. .endif
  56. \OP \reg,%lo(\val)
  57. .endm
  58. .macro _bgen reg,val,bit
  59. .if ((\val)==(1<<\bit))
  60. BGEN \reg,\bit
  61. .equ _bgenBit,1
  62. .endif
  63. .endm
  64. ;------------------------
  65. ; MOVIP %reg,32-bit-value
  66. .macro MOVIP reg,val
  67. ; Methodically test every BGEN possibility...
  68. .equ _bgenBit,0
  69. .if 1
  70. _bgen \reg,\val,0
  71. _bgen \reg,\val,1
  72. _bgen \reg,\val,2
  73. _bgen \reg,\val,3
  74. _bgen \reg,\val,4
  75. _bgen \reg,\val,5
  76. _bgen \reg,\val,6
  77. _bgen \reg,\val,7
  78. _bgen \reg,\val,8
  79. _bgen \reg,\val,9
  80. _bgen \reg,\val,10
  81. _bgen \reg,\val,11
  82. _bgen \reg,\val,12
  83. _bgen \reg,\val,13
  84. _bgen \reg,\val,14
  85. _bgen \reg,\val,15
  86. _bgen \reg,\val,16
  87. _bgen \reg,\val,17
  88. _bgen \reg,\val,18
  89. _bgen \reg,\val,19
  90. _bgen \reg,\val,20
  91. _bgen \reg,\val,21
  92. _bgen \reg,\val,22
  93. _bgen \reg,\val,23
  94. _bgen \reg,\val,24
  95. _bgen \reg,\val,25
  96. _bgen \reg,\val,26
  97. _bgen \reg,\val,27
  98. _bgen \reg,\val,28
  99. _bgen \reg,\val,29
  100. _bgen \reg,\val,30
  101. _bgen \reg,\val,31
  102. ; If no bgen fit...
  103. .endif
  104. .if !_bgenBit
  105. .if ((\val) & 0xFFE0)
  106. PFX %hi(\val)
  107. .endif
  108. MOVI \reg,%lo(\val)
  109. .if __nios32__
  110. .if ((\val) & 0xffff0000)
  111. .if ((\val) & 0xFFE00000)
  112. PFX %xhi(\val)
  113. .endif
  114. MOVHI \reg,%xlo(\val)
  115. .endif
  116. .endif
  117. .endif
  118. .endm
  119. ; ADDIP %reg,16-bit-value
  120. .macro ADDIP reg,val
  121. _pfx_op ADDI,\reg,\val
  122. .endm
  123. ; SUBIP %reg,16-bit-value
  124. .macro SUBIP reg,val
  125. _pfx_op SUBI,\reg,\val
  126. .endm
  127. ; CMPIP %reg,16-bit-value
  128. .macro CMPIP reg,val
  129. _pfx_op CMPI,\reg,\val
  130. .endm
  131. ; ANDIP %reg,16-bit-value
  132. .macro ANDIP reg,val
  133. PFX %hi(\val)
  134. AND \reg,%lo(\val)
  135. .endm
  136. ; ANDNIP %reg,16-bit-value
  137. .macro ANDNIP reg,val
  138. PFX %hi(\val)
  139. ANDN \reg,%lo(\val)
  140. .endm
  141. ; ORIP %reg,16-bit-value
  142. .macro ORIP reg,val
  143. PFX %hi(\val)
  144. OR \reg,%lo(\val)
  145. .endm
  146. ; XORIP %reg,16-bit-value
  147. .macro XORIP reg,val
  148. PFX %hi(\val)
  149. XOR \reg,%lo(\val)
  150. .endm
  151. ; BEQ addr
  152. .macro BEQ addr
  153. IFS cc_eq
  154. BR \addr
  155. .endm
  156. ; BNE addr
  157. .macro BNE addr
  158. IFS cc_ne
  159. BR \addr
  160. .endm
  161. ; BLE addr
  162. .macro BLE addr
  163. SKPS cc_gt
  164. BR \addr
  165. .endm
  166. ; BLT addr
  167. .macro BLT addr
  168. SKPS cc_ge
  169. BR \addr
  170. .endm
  171. .macro digitToChar reg
  172. ANDIP \reg,0x000f
  173. CMPI \reg,10
  174. SKPS cc_lt
  175. ADDI \reg,'A'-'0'-10
  176. PFX %hi('0')
  177. ADDI \reg,%lo('0')
  178. .endm
  179. ; PUSHRET == dec sp, and stash return addr
  180. .macro PUSHRET
  181. SUBI %sp,2
  182. ST [%sp],%o7
  183. .endm
  184. ; POPRET == pop and jump
  185. .macro POPRET
  186. LD %o7,[%sp]
  187. JMP %o7
  188. ADDI %sp,2 ; branch delay slot
  189. .endm
  190. ; RESTRET = restore & return
  191. .macro RESTRET
  192. JMP %i7
  193. RESTORE
  194. .endm
  195. ;--------------------
  196. ; MOVI16 %reg,Address
  197. ;
  198. .macro MOVI16 reg,val
  199. PFX %hi(\val)
  200. MOVI \reg,%lo(\val)
  201. .endm
  202. ;--------------------
  203. ; MOVI32 %reg,Address
  204. ;
  205. .macro MOVI32 reg,val
  206. PFX %hi(\val)
  207. MOVI \reg,%lo(\val)
  208. PFX %xhi(\val)
  209. MOVHI \reg,%xlo(\val)
  210. .endm
  211. ;--------------------
  212. ; MOVIA %reg,Address
  213. ;
  214. .macro MOVIA reg,val
  215. .if __nios32__
  216. MOVI32 \reg,\val
  217. .else
  218. MOVI16 \reg,\val
  219. .endif
  220. .endm
  221. ;--------------------
  222. ; _BR
  223. .macro _BR target,viaRegister=%g7
  224. MOVIA \viaRegister,\target@h
  225. JMP \viaRegister
  226. .endm
  227. ;--------------------
  228. ; _BSR
  229. .macro _BSR target,viaRegister=%g7
  230. MOVIA \viaRegister,\target@h
  231. CALL \viaRegister
  232. .endm
  233. ;---------------------
  234. ; NM_Print "Your String Here"
  235. ;
  236. .macro NM_Print string
  237. BR pastStringData\@
  238. NOP
  239. stringData\@:
  240. .asciz "\string"
  241. .align 1 ; aligns by 2^n
  242. pastStringData\@:
  243. MOVIA %o0,stringData\@
  244. _BSR NR_TxString
  245. NOP
  246. .endm
  247. .macro NM_PrintLn string
  248. NM_Print "\string"
  249. _BSR NR_TxCR
  250. NOP
  251. .endm
  252. .macro NM_PrintRegister reg ; affects %g0 & %g1 & %g7, but thrashes the CWP a bit
  253. SAVE %sp,-16
  254. NM_Print "\reg = "
  255. RESTORE
  256. MOV %g0,\reg
  257. SAVE %sp,-16
  258. MOV %o0,%g0
  259. _BSR NR_TxHex
  260. NOP
  261. _BSR NR_TxCR
  262. NOP
  263. RESTORE
  264. .endm
  265. .macro NM_PrintChar char
  266. MOVIP %o0,\char
  267. _BSR NR_TxChar
  268. NOP
  269. .endm
  270. .macro NM_Print2Chars char1,char2
  271. MOVIP %o0,(\char2<<8)+\char1
  272. _BSR NR_TxChar
  273. NOP
  274. _BSR NR_TxChar
  275. LSRI %o0,8
  276. .endm
  277. ; ---------------------------
  278. ; Completely inline UART sends
  279. ; Send the char, or %g7 if not there.
  280. ; Trashes %g5 and %g6 and %g7...
  281. .macro NM_TxChar char=0
  282. ;NM_D_Delay 1000
  283. MOVIA %g6,NA_UARTBase
  284. txCharLoop\@:
  285. PFX 2
  286. .if \char
  287. LD %g7,[%g6]
  288. SKP1 %g7,6
  289. .else
  290. LD %g5,[%g6]
  291. SKP1 %g5,6
  292. .endif
  293. BR txCharLoop\@
  294. NOP
  295. .if \char
  296. MOVIP %g7,\char
  297. .endif
  298. PFX 1
  299. ST [%g6],%g7
  300. ;NM_D_Delay 4
  301. .endm
  302. .macro NM_TxCR
  303. NM_TxChar 13
  304. NM_TxChar 10
  305. .endm
  306. .macro NM_TxHexDigit,reg,shift
  307. MOV %g7,\reg
  308. LSRI %g7,\shift
  309. ANDIP %g7,0x000f
  310. CMPI %g7,10
  311. SKPS cc_lt
  312. ADDIP %g7,'A'-'0'-10
  313. ADDIP %g7,'0'
  314. NM_TxChar
  315. .endm
  316. .macro NM_TxHex
  317. .if __nios32__
  318. NM_TxHexDigit %g0,28
  319. NM_TxHexDigit %g0,24
  320. NM_TxHexDigit %g0,20
  321. NM_TxHexDigit %g0,16
  322. .endif
  323. NM_TxHexDigit %g0,12
  324. NM_TxHexDigit %g0,8
  325. NM_TxHexDigit %g0,4
  326. NM_TxHexDigit %g0,0
  327. .endm
  328. ; ----------------------
  329. ; The following macros are
  330. ; rather mighty. They expand
  331. ; to large inline code for
  332. ; printing various things to
  333. ; the serial port. They are
  334. ; useful for debugging
  335. ; trap handlers, where you
  336. ; can't just go and call
  337. ; NR_TxChar and such, because,
  338. ; well, the CWP might be
  339. ; off limits!
  340. ;
  341. ; They do, however, presume
  342. ; that the stack is in good
  343. ; working order.
  344. .macro NM_D_PushGRegisters
  345. SUBIP %sp,16+69 ; oddball number so if we accidentally see it, it looks funny.
  346. STS [%sp,16+0],%g0
  347. STS [%sp,16+1],%g1
  348. STS [%sp,16+2],%g2
  349. STS [%sp,16+3],%g3
  350. STS [%sp,16+4],%g4
  351. STS [%sp,16+5],%g5
  352. STS [%sp,16+6],%g6
  353. STS [%sp,16+7],%g7
  354. .endm
  355. .macro NM_D_PopGRegisters
  356. LDS %g0,[%sp,16+0]
  357. LDS %g1,[%sp,16+1]
  358. LDS %g2,[%sp,16+2]
  359. LDS %g3,[%sp,16+3]
  360. LDS %g4,[%sp,16+4]
  361. LDS %g5,[%sp,16+5]
  362. LDS %g6,[%sp,16+6]
  363. LDS %g7,[%sp,16+7]
  364. ADDIP %sp,16+69 ; must match the push
  365. .endm
  366. .macro NM_D_TxChar c
  367. SUBI %sp,16+8 ; 32 or 16 bit, that's enough space
  368. STS [%sp,16+0],%g6
  369. STS [%sp,16+0],%g7
  370. NM_TxChar \c
  371. LDS %g6,[%sp,16+0]
  372. LDS %g7,[%sp,16+1]
  373. ADDI %sp,16+8
  374. .endm
  375. .macro NM_D_TxChar3 c1,c2,c3
  376. NM_D_TxChar '<'
  377. NM_D_TxChar \c1
  378. NM_D_TxChar \c2
  379. NM_D_TxChar \c3
  380. NM_D_TxChar '>'
  381. .endm
  382. .macro NM_D_TxRegister r,n,reg
  383. NM_D_PushGRegisters
  384. NM_TxChar '('
  385. NM_TxChar \r
  386. NM_TxChar \n
  387. NM_TxChar ':'
  388. MOV %g0,\reg
  389. NM_TxHex
  390. NM_TxChar ')'
  391. NM_D_PopGRegisters
  392. .endm
  393. .macro NM_D_TxReg r,n,reg
  394. NM_D_TxRegister \r,\n,\reg
  395. .endm
  396. ; Do a delay loop, affects no registers.
  397. .macro NM_D_Delay d
  398. SUBI %sp,16+4
  399. STS [%sp,16+0],%g0
  400. MOVIP %g0,\d
  401. NM_D_DelayLoop\@:
  402. IFRnz %g0
  403. BR NM_D_DelayLoop\@
  404. SUBI %g0,1
  405. LDS %g0,[%sp,16+0]
  406. ADDI %sp,16+4
  407. .endm