summaryrefslogtreecommitdiffstats
path: root/arch/unicore32/include/asm/assembler.h
blob: 3de843d92850c9937f9599c5691a61e3ac097813 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * linux/arch/unicore32/include/asm/assembler.h
 *
 * Code specific to PKUnity SoC and UniCore ISA
 *
 * Copyright (C) 2001-2010 GUAN Xue-tao
 *
 *  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