123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- ;------------------------------
- ; Macros I: Faux Instructions
- ;
- ; The following "faux instructions" are
- ; implemented here as macros:
- ;
- ; MOVIP register,constant MOVI with optional PFX & MOVHI, or BGEN
- ; ADDIP register,constant PFX and ADDI with optional PFX
- ; SUBIP register,constant PFX and SUBI with optional PFX
- ; CMPIP register,constant PFX and CMPI with optional PFX
- ;
- ; MOVI16 register,constant PFX and MOVI
- ; MOVI32 register,constant PFX, MOVI, PFX, and MOVHI
- ; MOVIA register,constant PFX and MOVHI on Nios32, and PFX and MOVI
- ;
- ; ANDIP register,constant PFX and ANDI
- ; ANDNIP register,constant PFX and ANDN
- ; ORIP register,constant PFX and ORI
- ; XORIP register,constant PFX and XORI
- ;
- ; _BSR address MOVIP address to %g7, and CALL
- ; _BR address MOVIP address to %g7, and JMP
- ;
- ; BEQ address SKPS cc_nz and BR, has delay slot
- ; BNE address SKPS cc_z and BR, has delay slot
- ; BLE address SKPS cc_gt and BR, has delay slot
- ; BLT address SKPS cc_ge and BR, has delay slot
- ; RESTRET RESTORE and JMP %i7
- ;
- ;-------------------------------
- ; Macros II: Printing
- ;
- ; These macros are guaranteed *not*
- ; to have branch delay slot after them.
- ;
- ; NM_PrintChar char
- ; NM_Print "string"
- ; NM_PrintLn "string" Follows it with a carriage return
- ; NM_PrintRegister reg For debugging, prints register name & value
- ;
- ;-------------------------------
- ; Macros III: Inline Debugging
- ;
- ; These macros print various information
- ; using large sections of expanded inline code.
- ; They each use either few or no registers.
- ; Thus, they may be safely used in interrupt handlers.
- ;
- ; NM_D_TxChar char print char to UART, affects no registers
- ; NM_D_TxRegister char,char,register prints the two characters, and the hex register value
- ; --------------------------------------
- .macro _pfx_op OP,reg,val,pForce=0
- .if (\pForce) || ((\val) > (31)) || ((\val) < (0))
- PFX %hi(\val)
- .endif
- \OP \reg,%lo(\val)
- .endm
- .macro _bgen reg,val,bit
- .if ((\val)==(1<<\bit))
- BGEN \reg,\bit
- .equ _bgenBit,1
- .endif
- .endm
- ;------------------------
- ; MOVIP %reg,32-bit-value
- .macro MOVIP reg,val
- ; Methodically test every BGEN possibility...
- .equ _bgenBit,0
- .if 1
- _bgen \reg,\val,0
- _bgen \reg,\val,1
- _bgen \reg,\val,2
- _bgen \reg,\val,3
- _bgen \reg,\val,4
- _bgen \reg,\val,5
- _bgen \reg,\val,6
- _bgen \reg,\val,7
- _bgen \reg,\val,8
- _bgen \reg,\val,9
- _bgen \reg,\val,10
- _bgen \reg,\val,11
- _bgen \reg,\val,12
- _bgen \reg,\val,13
- _bgen \reg,\val,14
- _bgen \reg,\val,15
- _bgen \reg,\val,16
- _bgen \reg,\val,17
- _bgen \reg,\val,18
- _bgen \reg,\val,19
- _bgen \reg,\val,20
- _bgen \reg,\val,21
- _bgen \reg,\val,22
- _bgen \reg,\val,23
- _bgen \reg,\val,24
- _bgen \reg,\val,25
- _bgen \reg,\val,26
- _bgen \reg,\val,27
- _bgen \reg,\val,28
- _bgen \reg,\val,29
- _bgen \reg,\val,30
- _bgen \reg,\val,31
- ; If no bgen fit...
- .endif
- .if !_bgenBit
- .if ((\val) & 0xFFE0)
- PFX %hi(\val)
- .endif
- MOVI \reg,%lo(\val)
- .if __nios32__
- .if ((\val) & 0xffff0000)
- .if ((\val) & 0xFFE00000)
- PFX %xhi(\val)
- .endif
- MOVHI \reg,%xlo(\val)
- .endif
- .endif
- .endif
- .endm
- ; ADDIP %reg,16-bit-value
- .macro ADDIP reg,val
- _pfx_op ADDI,\reg,\val
- .endm
- ; SUBIP %reg,16-bit-value
- .macro SUBIP reg,val
- _pfx_op SUBI,\reg,\val
- .endm
- ; CMPIP %reg,16-bit-value
- .macro CMPIP reg,val
- _pfx_op CMPI,\reg,\val
- .endm
- ; ANDIP %reg,16-bit-value
- .macro ANDIP reg,val
- PFX %hi(\val)
- AND \reg,%lo(\val)
- .endm
- ; ANDNIP %reg,16-bit-value
- .macro ANDNIP reg,val
- PFX %hi(\val)
- ANDN \reg,%lo(\val)
- .endm
- ; ORIP %reg,16-bit-value
- .macro ORIP reg,val
- PFX %hi(\val)
- OR \reg,%lo(\val)
- .endm
- ; XORIP %reg,16-bit-value
- .macro XORIP reg,val
- PFX %hi(\val)
- XOR \reg,%lo(\val)
- .endm
- ; BEQ addr
- .macro BEQ addr
- IFS cc_eq
- BR \addr
- .endm
- ; BNE addr
- .macro BNE addr
- IFS cc_ne
- BR \addr
- .endm
- ; BLE addr
- .macro BLE addr
- SKPS cc_gt
- BR \addr
- .endm
- ; BLT addr
- .macro BLT addr
- SKPS cc_ge
- BR \addr
- .endm
- .macro digitToChar reg
- ANDIP \reg,0x000f
- CMPI \reg,10
- SKPS cc_lt
- ADDI \reg,'A'-'0'-10
- PFX %hi('0')
- ADDI \reg,%lo('0')
- .endm
- ; PUSHRET == dec sp, and stash return addr
- .macro PUSHRET
- SUBI %sp,2
- ST [%sp],%o7
- .endm
- ; POPRET == pop and jump
- .macro POPRET
- LD %o7,[%sp]
- JMP %o7
- ADDI %sp,2 ; branch delay slot
- .endm
- ; RESTRET = restore & return
- .macro RESTRET
- JMP %i7
- RESTORE
- .endm
- ;--------------------
- ; MOVI16 %reg,Address
- ;
- .macro MOVI16 reg,val
- PFX %hi(\val)
- MOVI \reg,%lo(\val)
- .endm
- ;--------------------
- ; MOVI32 %reg,Address
- ;
- .macro MOVI32 reg,val
- PFX %hi(\val)
- MOVI \reg,%lo(\val)
- PFX %xhi(\val)
- MOVHI \reg,%xlo(\val)
- .endm
- ;--------------------
- ; MOVIA %reg,Address
- ;
- .macro MOVIA reg,val
- .if __nios32__
- MOVI32 \reg,\val
- .else
- MOVI16 \reg,\val
- .endif
- .endm
- ;--------------------
- ; _BR
- .macro _BR target,viaRegister=%g7
- MOVIA \viaRegister,\target@h
- JMP \viaRegister
- .endm
- ;--------------------
- ; _BSR
- .macro _BSR target,viaRegister=%g7
- MOVIA \viaRegister,\target@h
- CALL \viaRegister
- .endm
- ;---------------------
- ; NM_Print "Your String Here"
- ;
- .macro NM_Print string
- BR pastStringData\@
- NOP
- stringData\@:
- .asciz "\string"
- .align 1 ; aligns by 2^n
- pastStringData\@:
- MOVIA %o0,stringData\@
- _BSR NR_TxString
- NOP
- .endm
- .macro NM_PrintLn string
- NM_Print "\string"
- _BSR NR_TxCR
- NOP
- .endm
- .macro NM_PrintRegister reg ; affects %g0 & %g1 & %g7, but thrashes the CWP a bit
- SAVE %sp,-16
- NM_Print "\reg = "
- RESTORE
- MOV %g0,\reg
- SAVE %sp,-16
- MOV %o0,%g0
- _BSR NR_TxHex
- NOP
- _BSR NR_TxCR
- NOP
- RESTORE
- .endm
- .macro NM_PrintChar char
- MOVIP %o0,\char
- _BSR NR_TxChar
- NOP
- .endm
- .macro NM_Print2Chars char1,char2
- MOVIP %o0,(\char2<<8)+\char1
- _BSR NR_TxChar
- NOP
- _BSR NR_TxChar
- LSRI %o0,8
- .endm
- ; ---------------------------
- ; Completely inline UART sends
- ; Send the char, or %g7 if not there.
- ; Trashes %g5 and %g6 and %g7...
- .macro NM_TxChar char=0
- ;NM_D_Delay 1000
- MOVIA %g6,NA_UARTBase
- txCharLoop\@:
- PFX 2
- .if \char
- LD %g7,[%g6]
- SKP1 %g7,6
- .else
- LD %g5,[%g6]
- SKP1 %g5,6
- .endif
- BR txCharLoop\@
- NOP
- .if \char
- MOVIP %g7,\char
- .endif
- PFX 1
- ST [%g6],%g7
- ;NM_D_Delay 4
- .endm
- .macro NM_TxCR
- NM_TxChar 13
- NM_TxChar 10
- .endm
- .macro NM_TxHexDigit,reg,shift
- MOV %g7,\reg
- LSRI %g7,\shift
- ANDIP %g7,0x000f
- CMPI %g7,10
- SKPS cc_lt
- ADDIP %g7,'A'-'0'-10
- ADDIP %g7,'0'
- NM_TxChar
- .endm
- .macro NM_TxHex
- .if __nios32__
- NM_TxHexDigit %g0,28
- NM_TxHexDigit %g0,24
- NM_TxHexDigit %g0,20
- NM_TxHexDigit %g0,16
- .endif
- NM_TxHexDigit %g0,12
- NM_TxHexDigit %g0,8
- NM_TxHexDigit %g0,4
- NM_TxHexDigit %g0,0
- .endm
- ; ----------------------
- ; The following macros are
- ; rather mighty. They expand
- ; to large inline code for
- ; printing various things to
- ; the serial port. They are
- ; useful for debugging
- ; trap handlers, where you
- ; can't just go and call
- ; NR_TxChar and such, because,
- ; well, the CWP might be
- ; off limits!
- ;
- ; They do, however, presume
- ; that the stack is in good
- ; working order.
- .macro NM_D_PushGRegisters
- SUBIP %sp,16+69 ; oddball number so if we accidentally see it, it looks funny.
- STS [%sp,16+0],%g0
- STS [%sp,16+1],%g1
- STS [%sp,16+2],%g2
- STS [%sp,16+3],%g3
- STS [%sp,16+4],%g4
- STS [%sp,16+5],%g5
- STS [%sp,16+6],%g6
- STS [%sp,16+7],%g7
- .endm
- .macro NM_D_PopGRegisters
- LDS %g0,[%sp,16+0]
- LDS %g1,[%sp,16+1]
- LDS %g2,[%sp,16+2]
- LDS %g3,[%sp,16+3]
- LDS %g4,[%sp,16+4]
- LDS %g5,[%sp,16+5]
- LDS %g6,[%sp,16+6]
- LDS %g7,[%sp,16+7]
- ADDIP %sp,16+69 ; must match the push
- .endm
- .macro NM_D_TxChar c
- SUBI %sp,16+8 ; 32 or 16 bit, that's enough space
- STS [%sp,16+0],%g6
- STS [%sp,16+0],%g7
- NM_TxChar \c
- LDS %g6,[%sp,16+0]
- LDS %g7,[%sp,16+1]
- ADDI %sp,16+8
- .endm
- .macro NM_D_TxChar3 c1,c2,c3
- NM_D_TxChar '<'
- NM_D_TxChar \c1
- NM_D_TxChar \c2
- NM_D_TxChar \c3
- NM_D_TxChar '>'
- .endm
- .macro NM_D_TxRegister r,n,reg
- NM_D_PushGRegisters
- NM_TxChar '('
- NM_TxChar \r
- NM_TxChar \n
- NM_TxChar ':'
- MOV %g0,\reg
- NM_TxHex
- NM_TxChar ')'
- NM_D_PopGRegisters
- .endm
- .macro NM_D_TxReg r,n,reg
- NM_D_TxRegister \r,\n,\reg
- .endm
- ; Do a delay loop, affects no registers.
- .macro NM_D_Delay d
- SUBI %sp,16+4
- STS [%sp,16+0],%g0
- MOVIP %g0,\d
- NM_D_DelayLoop\@:
- IFRnz %g0
- BR NM_D_DelayLoop\@
- SUBI %g0,1
- LDS %g0,[%sp,16+0]
- ADDI %sp,16+4
- .endm
|