]>
Commit | Line | Data |
---|---|---|
d614a753 | 1 | /* Copyright (C) 1997-2020 Free Software Foundation, Inc. |
74de4bb5 | 2 | This file is part of the GNU C Library. |
74de4bb5 UD |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or | |
3214b89b AJ |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
74de4bb5 UD |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
3214b89b | 12 | Lesser General Public License for more details. |
74de4bb5 | 13 | |
3214b89b | 14 | You should have received a copy of the GNU Lesser General Public |
ab84e3ff | 15 | License along with the GNU C Library. If not, see |
5a82c748 | 16 | <https://www.gnu.org/licenses/>. */ |
74de4bb5 UD |
17 | |
18 | #ifndef _SYS_ASM_H | |
19 | #define _SYS_ASM_H | |
20 | ||
21 | #include <sgidefs.h> | |
22 | ||
23 | #ifndef CAT | |
2aee8949 | 24 | # define __CAT(str1,str2) str1##str2 |
b1a0b02e | 25 | # define CAT(str1,str2) __CAT(str1,str2) |
74de4bb5 UD |
26 | #endif |
27 | ||
aea7a9b9 JM |
28 | /* Redefined as nonempty in the internal header. */ |
29 | #define __mips_cfi_startproc /* Empty. */ | |
30 | #define __mips_cfi_endproc /* Empty. */ | |
31 | ||
74de4bb5 UD |
32 | /* |
33 | * Macros to handle different pointer/register sizes for 32/64-bit code | |
34 | * | |
35 | * 64 bit address space isn't used yet, so we may use the R3000 32 bit | |
36 | * defines for now. | |
37 | */ | |
73a227e2 | 38 | #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 |
b1a0b02e AO |
39 | # define PTR .word |
40 | # define PTRSIZE 4 | |
41 | # define PTRLOG 2 | |
73a227e2 | 42 | #elif _MIPS_SIM == _ABI64 |
b1a0b02e AO |
43 | # define PTR .dword |
44 | # define PTRSIZE 8 | |
45 | # define PTRLOG 3 | |
46 | #endif | |
74de4bb5 UD |
47 | |
48 | /* | |
49 | * PIC specific declarations | |
50 | */ | |
73a227e2 | 51 | #if _MIPS_SIM == _ABIO32 |
b1a0b02e AO |
52 | # ifdef __PIC__ |
53 | # define CPRESTORE(register) \ | |
74de4bb5 | 54 | .cprestore register |
b1a0b02e AO |
55 | # define CPLOAD(register) \ |
56 | .cpload register | |
57 | # else | |
58 | # define CPRESTORE(register) | |
59 | # define CPLOAD(register) | |
60 | # endif | |
61 | ||
62 | # define CPADD(register) \ | |
74de4bb5 | 63 | .cpadd register |
b1a0b02e AO |
64 | |
65 | /* | |
66 | * Set gp when at 1st instruction | |
67 | */ | |
68 | # define SETUP_GP \ | |
69 | .set noreorder; \ | |
70 | .cpload $25; \ | |
71 | .set reorder | |
72 | /* Set gp when not at 1st instruction */ | |
73 | # define SETUP_GPX(r) \ | |
74 | .set noreorder; \ | |
75 | move r, $31; /* Save old ra. */ \ | |
76 | bal 10f; /* Find addr of cpload. */ \ | |
77 | nop; \ | |
78 | 10: \ | |
79 | .cpload $31; \ | |
80 | move $31, r; \ | |
81 | .set reorder | |
82 | # define SETUP_GPX_L(r, l) \ | |
83 | .set noreorder; \ | |
84 | move r, $31; /* Save old ra. */ \ | |
85 | bal l; /* Find addr of cpload. */ \ | |
86 | nop; \ | |
87 | l: \ | |
88 | .cpload $31; \ | |
89 | move $31, r; \ | |
90 | .set reorder | |
91 | # define SAVE_GP(x) \ | |
92 | .cprestore x /* Save gp trigger t9/jalr conversion. */ | |
93 | # define SETUP_GP64(a, b) | |
94 | # define SETUP_GPX64(a, b) | |
95 | # define SETUP_GPX64_L(cp_reg, ra_save, l) | |
96 | # define RESTORE_GP64 | |
97 | # define USE_ALT_CP(a) | |
73a227e2 | 98 | #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */ |
b1a0b02e AO |
99 | /* |
100 | * For callee-saved gp calling convention: | |
101 | */ | |
102 | # define SETUP_GP | |
103 | # define SETUP_GPX(r) | |
104 | # define SETUP_GPX_L(r, l) | |
105 | # define SAVE_GP(x) | |
106 | ||
107 | # define SETUP_GP64(gpoffset, proc) \ | |
108 | .cpsetup $25, gpoffset, proc | |
109 | # define SETUP_GPX64(cp_reg, ra_save) \ | |
110 | move ra_save, $31; /* Save old ra. */ \ | |
111 | .set noreorder; \ | |
112 | bal 10f; /* Find addr of .cpsetup. */ \ | |
113 | nop; \ | |
114 | 10: \ | |
115 | .set reorder; \ | |
116 | .cpsetup $31, cp_reg, 10b; \ | |
117 | move $31, ra_save | |
118 | # define SETUP_GPX64_L(cp_reg, ra_save, l) \ | |
119 | move ra_save, $31; /* Save old ra. */ \ | |
120 | .set noreorder; \ | |
121 | bal l; /* Find addr of .cpsetup. */ \ | |
122 | nop; \ | |
123 | l: \ | |
124 | .set reorder; \ | |
125 | .cpsetup $31, cp_reg, l; \ | |
126 | move $31, ra_save | |
127 | # define RESTORE_GP64 \ | |
128 | .cpreturn | |
129 | /* Use alternate register for context pointer. */ | |
130 | # define USE_ALT_CP(reg) \ | |
131 | .cplocal reg | |
73a227e2 | 132 | #endif /* _MIPS_SIM != _ABIO32 */ |
b1a0b02e AO |
133 | |
134 | /* | |
135 | * Stack Frame Definitions | |
136 | */ | |
73a227e2 | 137 | #if _MIPS_SIM == _ABIO32 |
b1a0b02e | 138 | # define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */ |
74de4bb5 | 139 | #endif |
73a227e2 | 140 | #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 |
b1a0b02e AO |
141 | # define NARGSAVE 0 /* No caller responsibilities. */ |
142 | #endif | |
143 | ||
74de4bb5 UD |
144 | |
145 | /* | |
146 | * LEAF - declare leaf routine | |
147 | */ | |
148 | #define LEAF(symbol) \ | |
149 | .globl symbol; \ | |
150 | .align 2; \ | |
151 | .type symbol,@function; \ | |
152 | .ent symbol,0; \ | |
aea7a9b9 JM |
153 | symbol: .frame sp,0,ra; \ |
154 | __mips_cfi_startproc | |
74de4bb5 UD |
155 | |
156 | /* | |
157 | * NESTED - declare nested routine entry point | |
158 | */ | |
159 | #define NESTED(symbol, framesize, rpc) \ | |
160 | .globl symbol; \ | |
161 | .align 2; \ | |
162 | .type symbol,@function; \ | |
163 | .ent symbol,0; \ | |
aea7a9b9 JM |
164 | symbol: .frame sp, framesize, rpc; \ |
165 | __mips_cfi_startproc | |
74de4bb5 UD |
166 | |
167 | /* | |
168 | * END - mark end of function | |
169 | */ | |
b1a0b02e AO |
170 | #ifndef END |
171 | # define END(function) \ | |
aea7a9b9 | 172 | __mips_cfi_endproc; \ |
74de4bb5 UD |
173 | .end function; \ |
174 | .size function,.-function | |
b1a0b02e | 175 | #endif |
74de4bb5 UD |
176 | |
177 | /* | |
178 | * EXPORT - export definition of symbol | |
179 | */ | |
180 | #define EXPORT(symbol) \ | |
181 | .globl symbol; \ | |
aea7a9b9 | 182 | symbol: __mips_cfi_startproc |
74de4bb5 UD |
183 | |
184 | /* | |
185 | * ABS - export absolute symbol | |
186 | */ | |
187 | #define ABS(symbol,value) \ | |
188 | .globl symbol; \ | |
189 | symbol = value | |
190 | ||
191 | #define PANIC(msg) \ | |
192 | .set push; \ | |
193 | .set reorder; \ | |
194 | la a0,8f; \ | |
195 | jal panic; \ | |
196 | 9: b 9b; \ | |
197 | .set pop; \ | |
198 | TEXT(msg) | |
199 | ||
200 | /* | |
201 | * Print formated string | |
202 | */ | |
203 | #define PRINT(string) \ | |
204 | .set push; \ | |
205 | .set reorder; \ | |
206 | la a0,8f; \ | |
207 | jal printk; \ | |
208 | .set pop; \ | |
209 | TEXT(string) | |
210 | ||
211 | #define TEXT(msg) \ | |
212 | .data; \ | |
213 | 8: .asciiz msg; \ | |
214 | .previous; | |
215 | ||
216 | /* | |
217 | * Build text tables | |
218 | */ | |
219 | #define TTABLE(string) \ | |
220 | .text; \ | |
221 | .word 1f; \ | |
222 | .previous; \ | |
223 | .data; \ | |
224 | 1: .asciz string; \ | |
225 | .previous | |
226 | ||
227 | /* | |
228 | * MIPS IV pref instruction. | |
229 | * Use with .set noreorder only! | |
230 | * | |
231 | * MIPS IV implementations are free to treat this as a nop. The R5000 | |
232 | * is one of them. So we should have an option not to use this instruction. | |
233 | */ | |
a04549c1 JM |
234 | #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) \ |
235 | || (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) | |
b1a0b02e | 236 | # define PREF(hint,addr) \ |
74de4bb5 | 237 | pref hint,addr |
b1a0b02e | 238 | # define PREFX(hint,addr) \ |
74de4bb5 UD |
239 | prefx hint,addr |
240 | #else | |
b290216f SE |
241 | # define PREF(hint,addr) |
242 | # define PREFX(hint,addr) | |
74de4bb5 UD |
243 | #endif |
244 | ||
245 | /* | |
246 | * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. | |
247 | */ | |
248 | #if _MIPS_ISA == _MIPS_ISA_MIPS1 | |
b1a0b02e | 249 | # define MOVN(rd,rs,rt) \ |
74de4bb5 UD |
250 | .set push; \ |
251 | .set reorder; \ | |
b1a0b02e AO |
252 | beqz rt,9f; \ |
253 | move rd,rs; \ | |
74de4bb5 UD |
254 | .set pop; \ |
255 | 9: | |
b1a0b02e | 256 | # define MOVZ(rd,rs,rt) \ |
74de4bb5 UD |
257 | .set push; \ |
258 | .set reorder; \ | |
b1a0b02e AO |
259 | bnez rt,9f; \ |
260 | move rd,rt; \ | |
74de4bb5 UD |
261 | .set pop; \ |
262 | 9: | |
263 | #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ | |
264 | #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) | |
b1a0b02e | 265 | # define MOVN(rd,rs,rt) \ |
74de4bb5 UD |
266 | .set push; \ |
267 | .set noreorder; \ | |
b1a0b02e AO |
268 | bnezl rt,9f; \ |
269 | move rd,rs; \ | |
74de4bb5 UD |
270 | .set pop; \ |
271 | 9: | |
b1a0b02e | 272 | # define MOVZ(rd,rs,rt) \ |
74de4bb5 UD |
273 | .set push; \ |
274 | .set noreorder; \ | |
b1a0b02e AO |
275 | beqzl rt,9f; \ |
276 | movz rd,rs; \ | |
74de4bb5 UD |
277 | .set pop; \ |
278 | 9: | |
279 | #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ | |
a04549c1 JM |
280 | #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) \ |
281 | || (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) | |
b1a0b02e | 282 | # define MOVN(rd,rs,rt) \ |
74de4bb5 | 283 | movn rd,rs,rt |
b1a0b02e | 284 | # define MOVZ(rd,rs,rt) \ |
74de4bb5 UD |
285 | movz rd,rs,rt |
286 | #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */ | |
287 | ||
288 | /* | |
289 | * Stack alignment | |
290 | */ | |
73a227e2 | 291 | #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 |
b1a0b02e AO |
292 | # define ALSZ 15 |
293 | # define ALMASK ~15 | |
f4e9c08c AO |
294 | #else |
295 | # define ALSZ 7 | |
296 | # define ALMASK ~7 | |
74de4bb5 UD |
297 | #endif |
298 | ||
299 | /* | |
300 | * Size of a register | |
301 | */ | |
73a227e2 | 302 | #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 |
b1a0b02e | 303 | # define SZREG 8 |
74de4bb5 | 304 | #else |
b1a0b02e | 305 | # define SZREG 4 |
74de4bb5 UD |
306 | #endif |
307 | ||
308 | /* | |
309 | * Use the following macros in assemblercode to load/store registers, | |
310 | * pointers etc. | |
311 | */ | |
f4e9c08c | 312 | #if (SZREG == 4) |
b1a0b02e AO |
313 | # define REG_S sw |
314 | # define REG_L lw | |
315 | #else | |
316 | # define REG_S sd | |
317 | # define REG_L ld | |
74de4bb5 UD |
318 | #endif |
319 | ||
320 | /* | |
321 | * How to add/sub/load/store/shift C int variables. | |
322 | */ | |
323 | #if (_MIPS_SZINT == 32) | |
b1a0b02e AO |
324 | # define INT_ADD add |
325 | # define INT_ADDI addi | |
326 | # define INT_ADDU addu | |
327 | # define INT_ADDIU addiu | |
5057ad3b | 328 | # define INT_SUB sub |
b1a0b02e AO |
329 | # define INT_SUBI subi |
330 | # define INT_SUBU subu | |
331 | # define INT_SUBIU subu | |
332 | # define INT_L lw | |
333 | # define INT_S sw | |
74de4bb5 UD |
334 | #endif |
335 | ||
336 | #if (_MIPS_SZINT == 64) | |
b1a0b02e AO |
337 | # define INT_ADD dadd |
338 | # define INT_ADDI daddi | |
339 | # define INT_ADDU daddu | |
340 | # define INT_ADDIU daddiu | |
5057ad3b | 341 | # define INT_SUB dsub |
b1a0b02e AO |
342 | # define INT_SUBI dsubi |
343 | # define INT_SUBU dsubu | |
344 | # define INT_SUBIU dsubu | |
345 | # define INT_L ld | |
346 | # define INT_S sd | |
74de4bb5 UD |
347 | #endif |
348 | ||
349 | /* | |
350 | * How to add/sub/load/store/shift C long variables. | |
351 | */ | |
352 | #if (_MIPS_SZLONG == 32) | |
b1a0b02e AO |
353 | # define LONG_ADD add |
354 | # define LONG_ADDI addi | |
355 | # define LONG_ADDU addu | |
356 | # define LONG_ADDIU addiu | |
5057ad3b | 357 | # define LONG_SUB sub |
b1a0b02e AO |
358 | # define LONG_SUBI subi |
359 | # define LONG_SUBU subu | |
360 | # define LONG_SUBIU subu | |
361 | # define LONG_L lw | |
362 | # define LONG_S sw | |
363 | # define LONG_SLL sll | |
364 | # define LONG_SLLV sllv | |
365 | # define LONG_SRL srl | |
366 | # define LONG_SRLV srlv | |
367 | # define LONG_SRA sra | |
368 | # define LONG_SRAV srav | |
74de4bb5 UD |
369 | #endif |
370 | ||
371 | #if (_MIPS_SZLONG == 64) | |
b1a0b02e AO |
372 | # define LONG_ADD dadd |
373 | # define LONG_ADDI daddi | |
374 | # define LONG_ADDU daddu | |
375 | # define LONG_ADDIU daddiu | |
5057ad3b | 376 | # define LONG_SUB dsub |
b1a0b02e AO |
377 | # define LONG_SUBI dsubi |
378 | # define LONG_SUBU dsubu | |
379 | # define LONG_SUBIU dsubu | |
380 | # define LONG_L ld | |
381 | # define LONG_S sd | |
382 | # define LONG_SLL dsll | |
383 | # define LONG_SLLV dsllv | |
384 | # define LONG_SRL dsrl | |
385 | # define LONG_SRLV dsrlv | |
386 | # define LONG_SRA dsra | |
387 | # define LONG_SRAV dsrav | |
74de4bb5 UD |
388 | #endif |
389 | ||
390 | /* | |
391 | * How to add/sub/load/store/shift pointers. | |
392 | */ | |
73a227e2 | 393 | #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32) |
b1a0b02e AO |
394 | # define PTR_ADD add |
395 | # define PTR_ADDI addi | |
396 | # define PTR_ADDU addu | |
397 | # define PTR_ADDIU addiu | |
5057ad3b | 398 | # define PTR_SUB sub |
b1a0b02e AO |
399 | # define PTR_SUBI subi |
400 | # define PTR_SUBU subu | |
401 | # define PTR_SUBIU subu | |
402 | # define PTR_L lw | |
403 | # define PTR_LA la | |
404 | # define PTR_S sw | |
405 | # define PTR_SLL sll | |
406 | # define PTR_SLLV sllv | |
407 | # define PTR_SRL srl | |
408 | # define PTR_SRLV srlv | |
409 | # define PTR_SRA sra | |
410 | # define PTR_SRAV srav | |
411 | ||
412 | # define PTR_SCALESHIFT 2 | |
74de4bb5 UD |
413 | #endif |
414 | ||
73a227e2 | 415 | #if _MIPS_SIM == _ABIN32 |
b1a0b02e AO |
416 | # define PTR_ADD add |
417 | # define PTR_ADDI addi | |
5057ad3b | 418 | # define PTR_SUB sub |
b1a0b02e | 419 | # define PTR_SUBI subi |
86c56b16 | 420 | #if !defined __mips_isa_rev || __mips_isa_rev < 6 |
04d55561 SE |
421 | # define PTR_ADDU add /* no u */ |
422 | # define PTR_ADDIU addi /* no u */ | |
b1a0b02e AO |
423 | # define PTR_SUBU sub /* no u */ |
424 | # define PTR_SUBIU sub /* no u */ | |
04d55561 SE |
425 | #else |
426 | # define PTR_ADDU addu | |
427 | # define PTR_ADDIU addiu | |
428 | # define PTR_SUBU subu | |
429 | # define PTR_SUBIU subu | |
430 | #endif | |
b1a0b02e AO |
431 | # define PTR_L lw |
432 | # define PTR_LA la | |
433 | # define PTR_S sw | |
434 | # define PTR_SLL sll | |
435 | # define PTR_SLLV sllv | |
436 | # define PTR_SRL srl | |
437 | # define PTR_SRLV srlv | |
438 | # define PTR_SRA sra | |
439 | # define PTR_SRAV srav | |
440 | ||
441 | # define PTR_SCALESHIFT 2 | |
442 | #endif | |
443 | ||
73a227e2 AJ |
444 | #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \ |
445 | || _MIPS_SIM == _ABI64 | |
b1a0b02e AO |
446 | # define PTR_ADD dadd |
447 | # define PTR_ADDI daddi | |
448 | # define PTR_ADDU daddu | |
449 | # define PTR_ADDIU daddiu | |
5057ad3b | 450 | # define PTR_SUB dsub |
b1a0b02e AO |
451 | # define PTR_SUBI dsubi |
452 | # define PTR_SUBU dsubu | |
453 | # define PTR_SUBIU dsubu | |
454 | # define PTR_L ld | |
455 | # define PTR_LA dla | |
456 | # define PTR_S sd | |
457 | # define PTR_SLL dsll | |
458 | # define PTR_SLLV dsllv | |
459 | # define PTR_SRL dsrl | |
460 | # define PTR_SRLV dsrlv | |
461 | # define PTR_SRA dsra | |
462 | # define PTR_SRAV dsrav | |
463 | ||
464 | # define PTR_SCALESHIFT 3 | |
74de4bb5 UD |
465 | #endif |
466 | ||
467 | /* | |
468 | * Some cp0 registers were extended to 64bit for MIPS III. | |
469 | */ | |
a04549c1 JM |
470 | #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) \ |
471 | || (_MIPS_ISA == _MIPS_ISA_MIPS32) | |
b1a0b02e AO |
472 | # define MFC0 mfc0 |
473 | # define MTC0 mtc0 | |
74de4bb5 | 474 | #endif |
a04549c1 JM |
475 | #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) \ |
476 | || (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) | |
b1a0b02e AO |
477 | # define MFC0 dmfc0 |
478 | # define MTC0 dmtc0 | |
74de4bb5 UD |
479 | #endif |
480 | ||
6f65e668 | 481 | /* The MIPS architectures do not have a uniform memory model. Particular |
63841821 AJ |
482 | platforms may provide additional guarantees - for instance, the R4000 |
483 | LL and SC instructions implicitly perform a SYNC, and the 4K promises | |
484 | strong ordering. | |
485 | ||
486 | However, in the absence of those guarantees, we must assume weak ordering | |
487 | and SYNC explicitly where necessary. | |
488 | ||
489 | Some obsolete MIPS processors may not support the SYNC instruction. This | |
490 | applies to "true" MIPS I processors; most of the processors which compile | |
491 | using MIPS I implement parts of MIPS II. */ | |
492 | ||
493 | #ifndef MIPS_SYNC | |
494 | # define MIPS_SYNC sync | |
495 | #endif | |
496 | ||
74de4bb5 | 497 | #endif /* sys/asm.h */ |