132 строки
2.7 KiB
C
132 строки
2.7 KiB
C
/*
|
|
* linux/arch/unicore32/include/asm/assembler.h
|
|
*
|
|
* Code specific to PKUnity SoC and UniCore ISA
|
|
*
|
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* Do not include any C declarations in this file - it is included by
|
|
* assembler source.
|
|
*/
|
|
#ifndef __ASSEMBLY__
|
|
#error "Only include this from assembly code"
|
|
#endif
|
|
|
|
#include <asm/ptrace.h>
|
|
|
|
/*
|
|
* Little Endian independent macros for shifting bytes within registers.
|
|
*/
|
|
#define pull >>
|
|
#define push <<
|
|
#define get_byte_0 << #0
|
|
#define get_byte_1 >> #8
|
|
#define get_byte_2 >> #16
|
|
#define get_byte_3 >> #24
|
|
#define put_byte_0 << #0
|
|
#define put_byte_1 << #8
|
|
#define put_byte_2 << #16
|
|
#define put_byte_3 << #24
|
|
|
|
#define cadd cmpadd
|
|
#define cand cmpand
|
|
#define csub cmpsub
|
|
#define cxor cmpxor
|
|
|
|
/*
|
|
* Enable and disable interrupts
|
|
*/
|
|
.macro disable_irq, temp
|
|
mov \temp, asr
|
|
andn \temp, \temp, #0xFF
|
|
or \temp, \temp, #PSR_I_BIT | PRIV_MODE
|
|
mov.a asr, \temp
|
|
.endm
|
|
|
|
.macro enable_irq, temp
|
|
mov \temp, asr
|
|
andn \temp, \temp, #0xFF
|
|
or \temp, \temp, #PRIV_MODE
|
|
mov.a asr, \temp
|
|
.endm
|
|
|
|
#define USER(x...) \
|
|
9999: x; \
|
|
.pushsection __ex_table, "a"; \
|
|
.align 3; \
|
|
.long 9999b, 9001f; \
|
|
.popsection
|
|
|
|
.macro notcond, cond, nexti = .+8
|
|
.ifc \cond, eq
|
|
bne \nexti
|
|
.else; .ifc \cond, ne
|
|
beq \nexti
|
|
.else; .ifc \cond, ea
|
|
bub \nexti
|
|
.else; .ifc \cond, ub
|
|
bea \nexti
|
|
.else; .ifc \cond, fs
|
|
bns \nexti
|
|
.else; .ifc \cond, ns
|
|
bfs \nexti
|
|
.else; .ifc \cond, fv
|
|
bnv \nexti
|
|
.else; .ifc \cond, nv
|
|
bfv \nexti
|
|
.else; .ifc \cond, ua
|
|
beb \nexti
|
|
.else; .ifc \cond, eb
|
|
bua \nexti
|
|
.else; .ifc \cond, eg
|
|
bsl \nexti
|
|
.else; .ifc \cond, sl
|
|
beg \nexti
|
|
.else; .ifc \cond, sg
|
|
bel \nexti
|
|
.else; .ifc \cond, el
|
|
bsg \nexti
|
|
.else; .ifnc \cond, al
|
|
.error "Unknown cond in notcond macro argument"
|
|
.endif; .endif; .endif; .endif; .endif; .endif; .endif
|
|
.endif; .endif; .endif; .endif; .endif; .endif; .endif
|
|
.endif
|
|
.endm
|
|
|
|
.macro usracc, instr, reg, ptr, inc, cond, rept, abort
|
|
.rept \rept
|
|
notcond \cond, .+8
|
|
9999 :
|
|
.if \inc == 1
|
|
\instr\()b.u \reg, [\ptr], #\inc
|
|
.elseif \inc == 4
|
|
\instr\()w.u \reg, [\ptr], #\inc
|
|
.else
|
|
.error "Unsupported inc macro argument"
|
|
.endif
|
|
|
|
.pushsection __ex_table, "a"
|
|
.align 3
|
|
.long 9999b, \abort
|
|
.popsection
|
|
.endr
|
|
.endm
|
|
|
|
.macro strusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f
|
|
usracc st, \reg, \ptr, \inc, \cond, \rept, \abort
|
|
.endm
|
|
|
|
.macro ldrusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f
|
|
usracc ld, \reg, \ptr, \inc, \cond, \rept, \abort
|
|
.endm
|
|
|
|
.macro nop8
|
|
.rept 8
|
|
nop
|
|
.endr
|
|
.endm
|