xref: /nrf52832-nimble/rt-thread/libcpu/mips/common/mips_asm.h (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * File      : mips_asm.h
3  * This file is part of RT-Thread RTOS
4  * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License along
17  *  with this program; if not, write to the Free Software Foundation, Inc.,
18  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Change Logs:
21  * Date           Author       Notes
22  * 2016��9��7��     Urey         the first version
23  */
24 
25 #ifndef _MIPS_ASM_H_
26 #define _MIPS_ASM_H_
27 
28 
29 /* ********************************************************************* */
30 /* Interface macro & data definition */
31 
32 #ifdef __ASSEMBLY__
33 
34 /******** ASSEMBLER SPECIFIC DEFINITIONS ********/
35 
36 #ifdef  __ghs__
37 #define ALIGN(x) .##align (1 << (x))
38 #else
39 #define ALIGN(x) .##align (x)
40 #endif
41 
42 #ifdef __ghs__
43 #define SET_MIPS3()
44 #define SET_MIPS0()
45 #define SET_PUSH()
46 #define SET_POP()
47 #else
48 #define SET_MIPS3() .##set mips3
49 #define SET_MIPS0() .##set mips0
50 #define SET_PUSH()  .##set push
51 #define SET_POP()   .##set pop
52 #endif
53 
54 /*  Different assemblers have different requirements for how to
55  *  indicate that the next section is bss :
56  *
57  *  Some use :   .bss
58  *  Others use : .section bss
59  *
60  *  We select which to use based on _BSS_OLD_, which may be defined
61  *  in makefile.
62  */
63 #ifdef _BSS_OLD_
64 #define BSS	.##section bss
65 #else
66 #define BSS	.##bss
67 #endif
68 
69 #define LEAF(name)\
70   		.##text;\
71   		.##globl	name;\
72   		.##ent	name;\
73 name:
74 
75 
76 #define SLEAF(name)\
77   		.##text;\
78   		.##ent	name;\
79 name:
80 
81 
82 #ifdef __ghs__
83 #define END(name)\
84   		.##end	name
85 #else
86 #define END(name)\
87   		.##size name,.-name;\
88   		.##end	name
89 #endif
90 
91 
92 #define EXTERN(name)
93 
94 #else
95 
96 #define U64 unsigned long long
97 #define U32 unsigned int
98 #define U16 unsigned short
99 #define U8  unsigned char
100 #define S64 signed long long
101 #define S32 int
102 #define S16 short int
103 #define S8  signed char
104 //#define bool U8
105 
106 #ifndef _SIZE_T_
107 #define _SIZE_T_
108 #ifdef __ghs__
109    typedef unsigned int size_t;
110 #else
111    typedef unsigned long size_t;
112 #endif
113 #endif
114 
115 /* Sets the result on bPort */
116 #define BIT_SET(bPort,bBitMask)        (bPort |= bBitMask)
117 #define BIT_CLR(bPort,bBitMask)        (bPort &= ~bBitMask)
118 
119 /* Returns the result */
120 #define GET_BIT_SET(bPort,bBitMask)    (bPort | bBitMask)
121 #define GET_BIT_CLR(bPort,bBitMask)    (bPort & ~bBitMask)
122 
123 /* Returns 0 if the condition is False & a non-zero value if it is True */
124 #define TEST_BIT_SET(bPort,bBitMask)   (bPort & bBitMask)
125 #define TEST_BIT_CLR(bPort,bBitMask)   ((~bPort) & bBitMask)
126 
127 /* Split union definitions */
128 typedef union tunSU16
129 {
130         U16 hwHW;
131         struct tst2U8
132         {
133                 U8 bB0;
134                 U8 bB1;
135         }st2U8;
136 }tunSU16;
137 
138 typedef union tunSU32
139 {
140         U32 wW;
141         struct tst2U16
142         {
143                 U16 hwHW0;
144                 U16 hwHW1;
145         }st2U16;
146         struct tst4U8
147         {
148                 U8 bB0;
149                 U8 bB1;
150                 U8 bB2;
151                 U8 bB3;
152         }st4U8;
153 }tunSU32;
154 
155 #endif /* #ifdef __ASSEMBLY__ */
156 
157 
158 /******** DEFINITIONS FOR BOTH ASSEMBLER AND C ********/
159 
160 
161 #define  NO_ERR             0x00000000     /* operation completed successfully */
162 #define  ERR                0xffffffff     /* operation completed not successfully */
163 
164 #define False 0
165 #define True !False
166 
167 #ifndef NULL
168 #define NULL		      	((void *)0)
169 #endif//NULL
170 
171 #ifndef MIN
172 #define MIN(x,y)           ((x) < (y) ? (x) : (y))
173 #endif//MIN
174 
175 #ifndef MAX
176 #define MAX(x,y)      		((x) > (y) ? (x) : (y))
177 #endif//MAX
178 
179 #define MAXUINT(w)	(\
180 		((w) == sizeof(U8))  ? 0xFFU :\
181 		((w) == sizeof(U16)) ? 0xFFFFU :\
182 		((w) == sizeof(U32)) ? 0xFFFFFFFFU : 0\
183 		        )
184 
185 #define MAXINT(w)	(\
186 		((w) == sizeof(S8))  ? 0x7F :\
187 		((w) == sizeof(S16)) ? 0x7FFF :\
188 		((w) == sizeof(S32)) ? 0x7FFFFFFF : 0\
189 		        )
190 
191 #define MSK(n)			  ((1 << (n)) - 1)
192 
193 #define KUSEG_MSK		  0x80000000
194 #define KSEG_MSK		  0xE0000000
195 
196 #define KUSEGBASE		  0x00000000
197 #define KSEG0BASE		  0x80000000
198 #define KSEG1BASE		  0xA0000000
199 #define KSSEGBASE		  0xC0000000
200 #define KSEG3BASE		  0xE0000000
201 
202 /*  Below macros perform the following functions :
203  *
204  *  KSEG0    : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG0.
205  *  KSEG1    : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG1.
206  *  PHYS     : Converts KSEG0/1 or physical addr (below 0.5GB) to physical address.
207  *  KSSEG    : Not relevant for converting, but used for determining range.
208  *  KSEG3    : Not relevant for converting, but used for determining range.
209  *  KUSEG    : Not relevant for converting, but used for determining range.
210  *  KSEG0A   : Same as KSEG0 but operates on register rather than constant.
211  *  KSEG1A   : Same as KSEG1 but operates on register rather than constant.
212  *  PHYSA    : Same as PHYS  but operates on register rather than constant.
213  *  CACHED   : Alias for KSEG0 macro .
214  *	       (Note that KSEG0 cache attribute is determined by K0
215  *	       field of Config register, but this is typically cached).
216  *  UNCACHED : Alias for KSEG1 macro .
217  */
218 #ifdef __ASSEMBLY__
219 #define KSEG0(addr)     (((addr) & ~KSEG_MSK)  | KSEG0BASE)
220 #define KSEG1(addr)     (((addr) & ~KSEG_MSK)  | KSEG1BASE)
221 #define KSSEG(addr)     (((addr) & ~KSEG_MSK)  | KSSEGBASE)
222 #define KSEG3(addr)     (((addr) & ~KSEG_MSK)  | KSEG3BASE)
223 #define KUSEG(addr)     (((addr) & ~KUSEG_MSK) | KUSEGBASE)
224 #define PHYS(addr)      ( (addr) & ~KSEG_MSK)
225 #define KSEG0A(reg) 	and reg, ~KSEG_MSK; or reg, KSEG0BASE
226 #define KSEG1A(reg) 	and reg, ~KSEG_MSK; or reg, KSEG1BASE
227 #define PHYSA(reg)	and reg, ~KSEG_MSK
228 #else
229 #define KSEG0(addr)     (((U32)(addr) & ~KSEG_MSK)  | KSEG0BASE)
230 #define KSEG1(addr)     (((U32)(addr) & ~KSEG_MSK)  | KSEG1BASE)
231 #define KSSEG(addr)	(((U32)(addr) & ~KSEG_MSK)  | KSSEGBASE)
232 #define KSEG3(addr)	(((U32)(addr) & ~KSEG_MSK)  | KSEG3BASE)
233 #define KUSEG(addr)	(((U32)(addr) & ~KUSEG_MSK) | KUSEGBASE)
234 #define PHYS(addr) 	((U32)(addr)  & ~KSEG_MSK)
235 #endif
236 
237 #define CACHED(addr)	KSEG0(addr)
238 #define UNCACHED(addr)	KSEG1(addr)
239 
240 
241 #ifdef __ASSEMBLY__
242 /* Macroes to access variables at constant addresses
243  * Compensates for signed 16 bit displacement
244  * Typical use:	li	a0, HIKSEG1(ATLAS_ASCIIWORD)
245  *		sw	v1, LO_OFFS(ATLAS_ASCIIWORD)(a0)
246  */
247 #define HIKSEG0(addr)	((KSEG0(addr) + 0x8000) & 0xffff0000)
248 #define HIKSEG1(addr)	((KSEG1(addr) + 0x8000) & 0xffff0000)
249 #define HI_PART(addr)	(((addr) + 0x8000) & 0xffff0000)
250 #define LO_OFFS(addr)	((addr) & 0xffff)
251 #endif
252 
253 
254 /* Most/Least significant 32 bit from 64 bit double word */
255 #define HI32(data64)		  ((U32)(data64 >> 32))
256 #define LO32(data64)		  ((U32)(data64 & 0xFFFFFFFF))
257 
258 #if ((!defined(__ASSEMBLY__)) && (!defined(__LANGUAGE_ASSEMBLY)))
259 #define REG8( addr )		  (*(volatile U8 *) (addr))
260 #define REG16( addr )		  (*(volatile U16 *)(addr))
261 #define REG32( addr )		  (*(volatile U32 *)(addr))
262 #define REG64( addr )		  (*(volatile U64 *)(addr))
263 #endif
264 
265 /* Register field mapping */
266 #define REGFIELD(reg, rfld)	  (((reg) & rfld##_MSK) >> rfld##_SHF)
267 
268 /* absolute register address, access 					*/
269 #define	REGA(addr)		  REG32(addr)
270 
271 /* physical register address, access: base address + offsett		*/
272 #define	REGP(base,phys)	REG32( (U32)(base) + (phys) )
273 
274 /* relative register address, access: base address + offsett		*/
275 #define REG(base,offs)  REG32( (U32)(base) + offs##_##OFS )
276 
277 /* relative register address, access: base address + offsett		*/
278 #define REG_8(base,offs)  REG8( (U32)(base) + offs##_##OFS )
279 
280 /* relative register address, access: base address + offsett		*/
281 #define REG_16(base,offs)  REG16( (U32)(base) + offs##_##OFS )
282 
283 /* relative register address, access: base address + offsett		*/
284 #define REG_64(base,offs)  REG64( (U32)(base) + offs##_##OFS )
285 
286 /**************************************
287  * Macroes not used by YAMON any more
288  * (kept for backwards compatibility)
289  */
290 /* register read field							*/
291 #define	REGARD(addr,fld)	((REGA(addr) & addr##_##fld##_##MSK) 	\
292 			 >> addr##_##fld##_##SHF)
293 
294 /* register write numeric field value					*/
295 #define	REGAWRI(addr,fld,intval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
296 				 | ((intval) << addr##_##fld##_##SHF))
297 
298 /* register write enumerated field value				*/
299 #define	REGAWRE(addr,fld,enumval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
300 			| ((addr##_##fld##_##enumval) << addr##_##fld##_##SHF))
301 
302 
303 /* Examples:
304  *
305  *	exccode = REGARD(CPU_CAUSE,EXC);
306  *
307  *	REGA(SDR_CONTROL) = REGAWRI(OSG_CONTROL,TMO,17)
308  *			 | REGAWRE(OSG_CONTROL,DTYPE,PC1);
309  */
310 
311 
312 /* register read field							*/
313 #define	REGRD(base,offs,fld) ((REG(base,offs) & offs##_##fld##_##MSK) 	\
314 			 >> offs##_##fld##_##SHF)
315 
316 /* register write numeric field value					*/
317 #define	REGWRI(base,offs,fld,intval)((REG(base,offs)& ~(offs##_##fld##_##MSK))\
318                                  | (((intval) << offs##_##fld##_##SHF) & offs##_##fld##_##MSK))
319 
320 /* register write enumerated field value				*/
321 #define	REGWRE(base,offs,fld,enumval)((REG(base,offs) & ~(offs##_##fld##_##MSK))\
322 				| ((offs##_##fld##_##enumval) << offs##_##fld##_##SHF))
323 
324 
325 /* physical register read field							*/
326 #define	REGPRD(base,phys,fld) ((REGP(base,phys) & phys##_##fld##_##MSK) 	\
327 			 >> phys##_##fld##_##SHF)
328 
329 /* physical register write numeric field value					*/
330 #define	REGPWRI(base,phys,fld,intval)((REGP(base,phys)& ~(phys##_##fld##_##MSK))\
331 				 | ((intval) << phys##_##fld##_##SHF))
332 
333 /* physical register write enumerated field value				*/
334 #define	REGPWRE(base,phys,fld,enumval)((REGP(base,phys) & ~(phys##_##fld##_##MSK))\
335 				| ((phys##_##fld##_##enumval) << phys##_##fld##_##SHF))
336 /*
337  * End of macroes not used by YAMON any more
338  *********************************************/
339 
340 /* Endian related macros */
341 
342 #define SWAP_BYTEADDR32( addr )   ( (addr) ^ 0x3 )
343 #define SWAP_U16ADDR32( addr ) ( (addr) ^ 0x2 )
344 
345 /* Set byte address to little endian format */
346 #ifdef EL
347 #define SWAP_BYTEADDR_EL(addr) 	  addr
348 #else
349 #define SWAP_BYTEADDR_EL(addr)    SWAP_BYTEADDR32( addr )
350 #endif
351 
352 /* Set byte address to big endian format */
353 #ifdef EB
354 #define SWAP_BYTEADDR_EB(addr) 	  addr
355 #else
356 #define SWAP_BYTEADDR_EB(addr)    SWAP_BYTEADDR32( addr )
357 #endif
358 
359 /* Set U16 address to little endian format */
360 #ifdef EL
361 #define SWAP_U16ADDR_EL(addr)  addr
362 #else
363 #define SWAP_U16ADDR_EL(addr)  SWAP_U16ADDR32( addr )
364 #endif
365 
366 /* Set U16 address to big endian format */
367 #ifdef EB
368 #define SWAP_U16ADDR_EB(addr)  addr
369 #else
370 #define SWAP_U16ADDR_EB(addr)  SWAP_U16ADDR32( addr )
371 #endif
372 
373 #ifdef EL
374 #define REGW32LE(addr, data)      REG32(addr) = (data)
375 #define REGR32LE(addr, data)      (data)      = REG32(addr)
376 #else
377 #define REGW32LE(addr, data)      REG32(addr) = SWAPEND32(data)
378 #define REGR32LE(addr, data)      (data)      = REG32(addr), (data) = SWAPEND32(data)
379 #endif
380 
381 /* Set of 'LE'-macros, convert by BE: */
382 #ifdef EL
383 #define CPU_TO_LE32( value ) (value)
384 #define LE32_TO_CPU( value ) (value)
385 
386 #define CPU_TO_LE16( value ) (value)
387 #define LE16_TO_CPU( value ) (value)
388 #else
389 #define CPU_TO_LE32( value ) ( (                ((U32)value)  << 24) |   \
390                                ((0x0000FF00UL & ((U32)value)) <<  8) |   \
391                                ((0x00FF0000UL & ((U32)value)) >>  8) |   \
392                                (                ((U32)value)  >> 24)   )
393 #define LE32_TO_CPU( value ) CPU_TO_LE32( value )
394 
395 #define CPU_TO_LE16( value ) ( ((U16)(((U16)value)  << 8)) |   \
396                                ((U16)(((U16)value)  >> 8))   )
397 #define LE16_TO_CPU( value ) CPU_TO_LE16( value )
398 #endif
399 
400 /* Set of 'BE'-macros, convert by LE: */
401 #ifdef EB
402 #define CPU_TO_BE32( value ) (value)
403 #define BE32_TO_CPU( value ) (value)
404 
405 #define CPU_TO_BE16( value ) (value)
406 #define BE16_TO_CPU( value ) (value)
407 #else
408 #define CPU_TO_BE32( value ) ( (                ((U32)value)  << 24) |   \
409                                ((0x0000FF00UL & ((U32)value)) <<  8) |   \
410                                ((0x00FF0000UL & ((U32)value)) >>  8) |   \
411                                (                ((U32)value)  >> 24)   )
412 #define BE32_TO_CPU( value ) CPU_TO_BE32( value )
413 
414 #define CPU_TO_BE16( value ) ( ((U16)(((U16)value)  << 8)) |   \
415                                ((U16)(((U16)value)  >> 8))   )
416 #define BE16_TO_CPU( value ) CPU_TO_BE16( value )
417 #endif
418 
419 
420 /* Control characters */
421 #define CTRL_A          ('A'-0x40)
422 #define CTRL_B          ('B'-0x40)
423 #define CTRL_C          ('C'-0x40)
424 #define CTRL_D          ('D'-0x40)
425 #define CTRL_E          ('E'-0x40)
426 #define CTRL_F          ('F'-0x40)
427 #define CTRL_H          ('H'-0x40)
428 #define CTRL_K          ('K'-0x40)
429 #define CTRL_N          ('N'-0x40)
430 #define CTRL_P          ('P'-0x40)
431 #define CTRL_U          ('U'-0x40)
432 #define BACKSPACE       0x08
433 #define DEL             0x7F
434 #define TAB             0x09
435 #define CR              0x0D /* Enter Key */
436 #define LF              0x0A
437 #define ESC             0x1B
438 #define SP              0x20
439 #define CSI             0x9B
440 
441 
442 /* DEF2STR(x) converts #define symbol to string */
443 #define DEF2STR1(x) #x
444 #define DEF2STR(x)  DEF2STR1(x)
445 
446 
447 #endif /* _MIPS_ASM_H_ */
448