summaryrefslogtreecommitdiffstats
path: root/arch/unicore32/include/asm/assembler.h
blob: 8e87ed7faeba1027e7e7e0e59a5622c74b48ba9c (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
129
130
131
/*
 * 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