1 /*
2  * Copyright (C) 2017 Hangzhou C-SKY Microsystems co.,ltd.
3  *
4  * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB
5  * in this tarball.
6  */
7 
8 #ifndef _LINUX_CSKY_SYSDEP_H
9 #define _LINUX_CSKY_SYSDEP_H 1
10 
11 #include <common/sysdep.h>
12 #include <sys/syscall.h>
13 
14 #undef	SYS_ify
15 #define	SYS_ify(name) (__NR_##name)
16 
17 #ifdef __ASSEMBLER__
18 
19 /* ELF uses byte-counts for .align, most others use log2 of count of bytes.  */
20 #define ALIGNARG(log2) log2
21 /* For ELF we need the `.type' directive to make shared libs work right.  */
22 #define ASM_TYPE_DIRECTIVE(name,typearg) .type name,%##typearg;
23 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
24 
25 #define	ENTRY(name) \
26   .globl C_SYMBOL_NAME(name); \
27   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),function) \
28   .align ALIGNARG(4); \
29   C_LABEL(name)
30 
31 #undef END
32 #define END(name) ASM_SIZE_DIRECTIVE(name)
33 
34 #undef	ret_ERRVAL
35 #define	ret_ERRVAL rts
36 
37 #undef	PSEUDO_END
38 #define	PSEUDO_END(name) END(name)
39 
40 #ifdef __PIC__
41 #define __GET_GB \
42   bsr 1f; \
43   1: lrw gb, 1b@GOTPC; \
44   addu gb, lr;
45 
46 /*
47  * __JSR must be used with __GET_GB and SAVE_ARGS
48  */
49 #define __JSR(symbol) \
50   lrw a2, symbol@PLT; \
51   add a2, gb; \
52   ld.w a2, (a2); \
53   jsr a2;
54 
55 #define PSEUDO_ERRJMP \
56   subi sp, 8; \
57   st.w lr, (sp); \
58   st.w gb, (sp, 4); \
59   __GET_GB \
60   lrw a2, __syscall_error@PLT; \
61   addu a2, gb; \
62   ld.w a2, (a2); \
63   jsr a2; \
64   ld.w lr, (sp); \
65   ld.w gb, (sp, 4); \
66   addi sp, 8; \
67   rts;
68 
69 #else /* __PIC__ */
70 
71 #define __GET_GB
72 #define __JSR(symbol) jsri symbol;
73 #define PSEUDO_ERRJMP \
74   subi	sp, 4; \
75   stw	lr, (sp, 0); \
76   jsri	__syscall_error; \
77   ldw	lr, (sp, 0); \
78   addi	sp, 4; \
79   rts;
80 
81 #endif /* __PIC__ */
82 
83 #define PSEUDO_ERRVAL(name, syscall_name, args) \
84   .text; \
85   99: PSEUDO_ERRJMP; \
86   ENTRY(name); \
87   DO_CALL(syscall_name, args); \
88   btsti	a0, 31; \
89   bt 99b;
90 
91 #undef PSEUDO_END_ERRVAL
92 #define PSEUDO_END_ERRVAL(name) \
93   rts; \
94   END(name)
95 
96 /* DO_CALL */
97 #undef	DO_CALL
98 #ifdef	__CSKYABIV2__
99 
100 #define	DO_CALL(syscall_name, args) \
101   DOARGS_##args \
102   mov	t0, r7; \
103   lrw	r7, SYS_ify (syscall_name); \
104   trap	0; \
105   mov	r7, t0; \
106   UNDOARGS_##args
107 
108 #define DOARGS_0
109 #define DOARGS_1
110 #define DOARGS_2
111 #define DOARGS_3
112 #define DOARGS_4
113 #define DOARGS_5 subi sp, 4; st.w r4, (sp, 0); ld.w r4, (sp, 4);
114 #define DOARGS_6 subi sp, 8; stm r4-r5, (sp); ld.w r4, (sp, 8); ld.w r5, (sp, 12);
115 
116 #define UNDOARGS_0
117 #define UNDOARGS_1
118 #define UNDOARGS_2
119 #define UNDOARGS_3
120 #define UNDOARGS_4
121 #define UNDOARGS_5 ld.w r4, (sp, 0); addi sp, 4;
122 #define UNDOARGS_6 ldm r4-r5, (sp); addi sp, 8;
123 
124 #else /* __CSKYABIV2__ */
125 
126 #define DO_CALL(syscall_name, args) \
127   lrw  r1, SYS_ify (syscall_name); \
128   trap 0;
129 
130 #define DOARGS_0
131 #define DOARGS_1
132 #define DOARGS_2
133 #define DOARGS_3
134 #define DOARGS_4
135 #define DOARGS_5
136 #define DOARGS_6
137 
138 #define UNDOARGS_0
139 #define UNDOARGS_1
140 #define UNDOARGS_2
141 #define UNDOARGS_3
142 #define UNDOARGS_4
143 #define UNDOARGS_5
144 #define UNDOARGS_6
145 
146 #endif /* __CSKYABIV2__ */
147 
148 /*
149  * define DO_CALL_2, only ABIV2 need DO_CALL_2
150  * to be quite different with DO_CALL, DO_CALL_2 need not save r7.
151  */
152 #ifdef __CSKYABIV2__
153 #undef  DO_CALL_2
154 #define DO_CALL_2(syscall_name, args) \
155   DOARGS2_##args; \
156   lrw	r7, SYS_ify(syscall_name); \
157   trap	0; \
158   UNDOARGS2_##args
159 #undef  DOARGS2_0
160 #define DOARGS2_0
161 
162 #undef  DOARGS2_1
163 #define DOARGS2_1 DOARGS2_0
164 #undef  DOARGS2_2
165 #define DOARGS2_2 DOARGS2_0
166 #undef  DOARGS2_3
167 #define DOARGS2_3 DOARGS2_0
168 #undef  DOARGS2_4
169 #define DOARGS2_4 DOARGS2_0
170 #undef  DOARGS2_5
171 #define DOARGS2_5 \
172   subi sp, 8; \
173   cfi_adjust_cfa_offset (8); \
174   stw  r4, (sp, 0); \
175   ldw  r4, (sp, 24)
176 #undef  DOARGS2_6
177 #define DOARGS2_6 \
178   subi sp, 8; \
179   cfi_adjust_cfa_offset (8); \
180   stw  r4, (sp, 0); \
181   stw  r5, (sp, 4); \
182   ldw  r4, (sp, 24); \
183   ldw  r5, (sp, 28)
184 
185 #undef  UNDOARGS2_0
186 #define UNDOARGS2_0
187 
188 #undef  UNDOARGS2_1
189 #define UNDOARGS2_1 UNDOARGS2_0
190 #undef  UNDOARGS2_2
191 #define UNDOARGS2_2 UNDOARGS2_0
192 #undef  UNDOARGS2_3
193 #define UNDOARGS2_3 UNDOARGS2_0
194 #undef  UNDOARGS2_4
195 #define UNDOARGS2_4 UNDOARGS2_0
196 #undef  UNDOARGS2_5
197 #define UNDOARGS2_5 \
198   ldw  r4, (sp, 0); \
199   addi sp, 8
200 
201 #undef  UNDOARGS2_6
202 #define UNDOARGS2_6 \
203   ldw  r4, (sp, 0); \
204   ldw  r5, (sp, 4); \
205   addi sp, 8
206 
207 #endif  /* __CSKYABIV2__ */
208 
209 #endif /* __ASSEMBLER__ */
210 #endif /* _LINUX_CSKY_SYSDEP_H */
211 
212