?? macros.s
字號:
;********************************************************************************************************
; NIOS Macros
;
; GNU ASSEMBLER nios-elf-as.exe
;
; File : macros.s
; By : Farid LEZIAR (fleziar@yahoo.fr)
; Version : 2.0
;
; This port is free. you can use it, redistribute it
; and/or modify it under the following terms:
;
; 1. You are not allowed to remove or modify this copyright notice
; and License paragraphs, even if parts of the software is used.
; 2. The improvements and/or extentions you make must be available
; for the community under THIS license, source code included.
; 4. You may NOT distribute this software under another license without
; explicit permission from farid LEZIAR (fleziar@yahoo.fr).
; 5. This software is free, and distributed in the hope that it will be
; useful, but WITHOUT ANY WARRANTY.
; 6. Tou have you inform me whenever you use this software.
;
;********************************************************************************************************
; Direct Load 32bits value
.macro MOVI32 reg,val
PFX %hi(\val)
MOVI \reg,%lo(\val)
PFX %xhi(\val)
MOVHI \reg,%xlo(\val)
.endm
; Direct Load 16bits value
.macro MOVI16 reg,val
PFX %hi(\val)
MOVI \reg,%lo(\val)
.endm
; ADDI16 %reg,16-bit-value
.macro ADDI16 reg,val
PFX %hi(\val)
ADDI \reg, %lo(\val)
.endm
; SUBI16 %reg,16-bit-value
.macro SUBI16 reg,val
PFX %hi(\val)
SUBI \reg, %lo(\val)
.endm
; =========================================================================================
; == MACROS
; =========================================================================================
; Disable Interrupt
.macro disable_interrupt
PFX 8
WRCTL %g0
.endm
; Enable Interrupt
.macro enable_interrupt
PFX 9
WRCTL %g0
.endm
; decrement 32bits word aligned variable (alters %g0 and %g1 )
.macro dec32 variable
PFX %hi(\variable)
MOVI %g0,%lo(\variable)
PFX %xhi(\variable)
MOVHI %g0,%xlo(\variable)
LD %g1, [%g0]
SUBI %g1, 1
ST [%g0], %g1
.endm
; decrement 16bits word aligned variable (alters %g0 and %g1 )
.macro dec16 variable
PFX %hi(\variable)
MOVI %g0,%lo(\variable)
LD %g1, [%g0]
SUBI %g1, 1
ST [%g0], %g1
.endm
; increment 32bits word aligned variable (alters %g0 and %g1 )
.macro inc32 variable
PFX %hi(\variable)
MOVI %g0,%lo(\variable)
PFX %xhi(\variable)
MOVHI %g0,%xlo(\variable)
LD %g1, [%g0]
ADDI %g1, 1
ST [%g0], %g1
.endm
; increment 16bits word aligned variable (alters %g0 and %g1 )
.macro inc16 variable
PFX %hi(\variable)
MOVI %g0,%lo(\variable)
LD %g1, [%g0]
ADDI %g1, 1
ST [%g0], %g1
.endm
; increment 8bit variable (alters %g0, %g1, %g2)
.macro inc8 variable
MOVI32 %g2, \variable ; %g2 = &variable
LD %g1, [%g2] ; %g1 = variable
EXT8D %g1, %g2 ; extract byte
ADDI %g1, 1 ; %g1 ++
FILL8 %r0, %g1 ; %g0 = %g1 %g1 %g1 %g1
ST8D [%g2], %r0 ; store %g1
.endm
; clear 32bits word aligned variable (alters %g0 and %g1 )
.macro clr32 variable
MOVI32 %g0, \variable
MOVI32 %g1, 0
ST [%g0], %g0
.endm
; clear 16bits word aligned variable (alters %g0 and %g1 )
.macro clr16 variable
MOVI16 %g0, \variable
MOVI16 %g1, 0
ST [%g0], %g0
.endm
; =========================================================================================
; == SAVING-LOADING REGISTERS MACROS
; =========================================================================================
; load GLOBAL registers from the stack
.macro LDS_GR index
LDS %g0, [%sp, \index+0]
LDS %g1, [%sp, \index+1]
LDS %g2, [%sp, \index+2]
LDS %g3, [%sp, \index+3]
LDS %g4, [%sp, \index+4]
LDS %g5, [%sp, \index+5]
LDS %g6, [%sp, \index+6]
LDS %g7, [%sp, \index+7]
.endm
; save GLOBAL registers on the stack
.macro STS_GR index
STS [%sp, \index+0], %g0
STS [%sp, \index+1], %g1
STS [%sp, \index+2], %g2
STS [%sp, \index+3], %g3
STS [%sp, \index+4], %g4
STS [%sp, \index+5], %g5
STS [%sp, \index+6], %g6
STS [%sp, \index+7], %g7
.endm
; save ISTATUS on the stack
.macro STS_IS index
PFX 1
RDCTL %g0
STS [%sp, \index], %g0
.endm
; save IN registers on the stack
.macro STS_IR index
STS [%sp, \index+0], %i0
STS [%sp, \index+1], %i1
STS [%sp, \index+2], %i2
STS [%sp, \index+3], %i3
STS [%sp, \index+4], %i4
STS [%sp, \index+5], %i5
STS [%sp, \index+6], %i6
STS [%sp, \index+7], %i7
.endm
; load IN registers from the stack
.macro LDS_IR index
LDS %i0, [%sp, \index+0]
LDS %i1, [%sp, \index+1]
LDS %i2, [%sp, \index+2]
LDS %i3, [%sp, \index+3]
LDS %i4, [%sp, \index+4]
LDS %i5, [%sp, \index+5]
LDS %i6, [%sp, \index+6]
LDS %i7, [%sp, \index+7]
.endm
; save LOCAL registers on the stack
.macro STS_LR index
STS [%sp, \index+0], %L0
STS [%sp, \index+1], %L1
STS [%sp, \index+2], %L2
STS [%sp, \index+3], %L3
STS [%sp, \index+4], %L4
STS [%sp, \index+5], %L5
STS [%sp, \index+6], %L6
STS [%sp, \index+7], %L7
.endm
; load LOCAL registers from the stack
.macro LDS_LR index
LDS %L0, [%sp, \index+0]
LDS %L1, [%sp, \index+1]
LDS %L2, [%sp, \index+2]
LDS %L3, [%sp, \index+3]
LDS %L4, [%sp, \index+4]
LDS %L5, [%sp, \index+5]
LDS %L6, [%sp, \index+6]
LDS %L7, [%sp, \index+7]
.endm
; Increment CWP (virtual RESTORE instruction)
; in = %g0 = current STATUS
.macro INCCWP
PFX %hi(0x0010)
ADDI %g0, %lo(0x0010) ; CWP++
WRCTL %g0
NOP
.endm
; Decrement CWP (virtual SAVE instruction)
; in = %g0 = current STATUS
.macro DECCWP
PFX %hi(0x0010)
SUBI %g0, %lo(0x0010) ; CWP--
WRCTL %g0
NOP
.endm
; LOAD ISTATUS from the stack
.macro LDS_IS index
LDS %g0, [%sp, \index]
PFX 1
WRCTL %g0
.endm
; =========================================================================================
; == CONTEXT MANAGEMENT MACRO
; =========================================================================================
; This macro saves to stack :
; global registers, ISTATUS, return address and
; all window registers above the current window.
; affects (%sp, CWP, %g0, %g1, %g2, %g6 and %g7)
.macro SAVE_CONTEXT
SUBI16 %fp, (24+10)*regwidth ; space for savind %g, STATUS(Task) and interrupt %o7
MOV %sp, %fp
ADDI16 %fp, (24+10)*regwidth
STS_GR 24+0 ; save global registers
STS_IS 24+8 ; save STATUS(Task) = ISTATUS
STS [%sp, 24+9], %o7 ; save interrupt return address
; read current window
RDCTL %g1 ; %g1 = STATUS(Interrupt) = XXXXXXX-CWP-XXXX
RDCTL %g0 ; %g0 = STATUS(Interrupt)
RDCTL %g7 ; %g7 = STATUS(Interrupt)
LSRI %g1, 4 ; %g1 = XXXXXXXXXXX-CWP-
PFX %hi(0x001F)
AND %g1, %lo(0x001F) ; %g1 = 00000000000-CWP-
; %g1 = cwp(interrupt)
;ADDI %g1, 1 ; %g1 = cwp(Task)
; read HI_LIMIT from %ctl2
PFX 2
RDCTL %g2 ; %g2 = XXXXXXHHHHHLLLLL
LSRI %g2, 5 ; %g2 = XXXXXXXXXXXHHHHH
PFX %hi(0x001F)
AND %g2, %lo(0x001F) ; %g2 = 00000000000HHHHH
; save all window registers
nextSW\@:
SUBI16 %sp, 16*regwidth ; space for saving next %o and %L
STS_IR 24+8 ; save IN registers
MOV %g6, %sp
INCCWP ; CWP++
ADDI %g1, 1 ; current cwp++
MOV %sp, %g6
STS_LR 24+0 ; save LOCAL registers
CMP %g1, %g2 ; current cwp == HI_LIMIT ?
SKPS cc_z
BR nextSW\@ ; no
NOP
SUBI16 %sp, 9*regwidth ; space for saving INreg(HILIMIT) and STATUS
STS_IR 24+1 ; save INreg(HILIMIT)
STS [%sp, 24+0], %g7 ; save STATUS(Interrupt)
; now we are in cwp = HILIMIT
.endm
; This macro loads from stack :
; global registers, ISTATUS, return address and
; all window registers above the current window.
; and place cwp to interrupt window in order to execute
; a TRAP %o7 instruction.
; affects (%sp, CWP, %g0, %g1, %g2, %g6 and %g7)
.macro LOAD_CONTEXT
; read last interrupt window from stack
LDS %g1, [%sp, 24+0] ; %g1 = STATUS = XXXXXXX-CWP-XXXX
;MOV %g0, %g1 ; %g0 = STATUS(interrupt)
MOV %g7, %g1 ; %g7 = STATUS(interrupt)
LSRI %g1, 4 ; %g1 = XXXXXXXXXXX-CWP-
PFX %hi(0x001F)
AND %g1, %lo(0x001F) ; %g1 = 00000000000-CWP-
; %g1 = cwp(interrupt)
;ADDI %g1, 1 ; %g1 = cwp(Task)
; read HI_LIMIT from %ctl2
PFX 2
RDCTL %g2 ; %g2 = XXXXXXHHHHHLLLLL
LSRI %g2, 5 ; %g2 = XXXXXXXXXXXHHHHH
PFX %hi(0x001F)
AND %g2, %lo(0x001F) ; %g2 = 00000000000HHHHH
; set current window to HI_LIMIT
; and preserves %sp
MOV %g6, %sp ; save %sp
MOV %g0, %g2 ; %g0 = 00000000000HHHHH
LSLI %g0, 4 ; %g0 = 0000000HHHHH0000
WRCTL %g0 ; change to HILIMIT (IPRI=0, IE=0, FLAG=0)
NOP
MOV %sp, %g6 ; restore %sp (delay slot)
ADDI %sp, 1*regwidth
; resore all window registers
nextLW\@: ; next Load Window
LDS_IR 24+0 ; load IN registers
LDS_LR 24+8 ; Load LOCAL registers
ADDI16 %sp, 16*regwidth
MOV %g6, %sp
DECCWP ; CWP-- (%g0 = current status)
SUBI %g2, 1 ; current cwp--
MOV %sp, %g6
LDS_IR 24+8 ; Load IN registers
CMP %g1, %g2 ; current cwp == cwp(interrupt) ?
SKPS cc_z
BR nextLW\@ ; no
NOP
LDS_IR 24+0 ; load IN registers (= OUT's Task)
LDS_IS 24+16 ; load STATUS(Task) = ISTATUS
LDS %o7, [%sp, 24+17] ; load interrupt return address
LDS_GR 24+8 ; load global registers
; restore valid %sp to the task
MOV %fp, %sp
ADDI16 %fp, (24+18)*regwidth
.endm
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -