1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle 7 * Copyright (C) 1999 by Silicon Graphics, Inc. 8 * Copyright (C) 2001 MIPS Technologies, Inc. 9 * Copyright (C) 2002 Maciej W. Rozycki 10 * 11 * Some useful macros for MIPS assembler code 12 * 13 * Some of the routines below contain useless nops that will be optimized 14 * away by gas in -O mode. These nops are however required to fill delay 15 * slots in noreorder mode. 16 */ 17#ifndef __ASM_ASM_H 18#define __ASM_ASM_H 19 20#include <asm/sgidefs.h> 21 22/* 23 * PIC specific declarations 24 * Not used for the kernel but here seems to be the right place. 25 */ 26#ifdef __PIC__ 27#define CPRESTORE(register) \ 28 .cprestore register 29#define CPADD(register) \ 30 .cpadd register 31#define CPLOAD(register) \ 32 .cpload register 33#else 34#define CPRESTORE(register) 35#define CPADD(register) 36#define CPLOAD(register) 37#endif 38 39/* 40 * LEAF - declare leaf routine 41 */ 42#define LEAF(symbol) \ 43 .globl symbol; \ 44 .align 2; \ 45 .type symbol,@function; \ 46 .ent symbol,0; \ 47symbol: .frame sp,0,ra 48 49/* 50 * NESTED - declare nested routine entry point 51 */ 52#define NESTED(symbol, framesize, rpc) \ 53 .globl symbol; \ 54 .align 2; \ 55 .type symbol,@function; \ 56 .ent symbol,0; \ 57symbol: .frame sp, framesize, rpc 58 59/* 60 * END - mark end of function 61 */ 62#define END(function) \ 63 .end function; \ 64 .size function,.-function 65 66/* 67 * EXPORT - export definition of symbol 68 */ 69#define EXPORT(symbol) \ 70 .globl symbol; \ 71symbol: 72 73/* 74 * FEXPORT - export definition of a function symbol 75 */ 76#define FEXPORT(symbol) \ 77 .globl symbol; \ 78 .type symbol,@function; \ 79symbol: 80 81/* 82 * ABS - export absolute symbol 83 */ 84#define ABS(symbol,value) \ 85 .globl symbol; \ 86symbol = value 87 88#define PANIC(msg) \ 89 .set push; \ 90 .set reorder; \ 91 PTR_LA a0,8f; \ 92 jal panic; \ 939: b 9b; \ 94 .set pop; \ 95 TEXT(msg) 96 97/* 98 * Print formatted string 99 */ 100#define PRINT(string) \ 101 .set push; \ 102 .set reorder; \ 103 PTR_LA a0,8f; \ 104 jal printk; \ 105 .set pop; \ 106 TEXT(string) 107 108#define TEXT(msg) \ 109 .pushsection .data; \ 1108: .asciiz msg; \ 111 .popsection; 112 113/* 114 * Build text tables 115 */ 116#define TTABLE(string) \ 117 .pushsection .text; \ 118 .word 1f; \ 119 .popsection \ 120 .pushsection .data; \ 1211: .asciiz string; \ 122 .popsection 123 124/* 125 * MIPS IV pref instruction. 126 * Use with .set noreorder only! 127 * 128 * MIPS IV implementations are free to treat this as a nop. The R5000 129 * is one of them. So we should have an option not to use this instruction. 130 */ 131#ifdef CONFIG_CPU_HAS_PREFETCH 132 133#define PREF(hint,addr) \ 134 .set push; \ 135 .set mips4; \ 136 pref hint,addr; \ 137 .set pop 138 139#define PREFX(hint,addr) \ 140 .set push; \ 141 .set mips4; \ 142 prefx hint,addr; \ 143 .set pop 144 145#else /* !CONFIG_CPU_HAS_PREFETCH */ 146 147#define PREF(hint,addr) 148#define PREFX(hint,addr) 149 150#endif /* !CONFIG_CPU_HAS_PREFETCH */ 151 152/* 153 * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. 154 */ 155#if _MIPS_ISA == _MIPS_ISA_MIPS1 156#define MOVN(rd,rs,rt) \ 157 .set push; \ 158 .set reorder; \ 159 beqz rt,9f; \ 160 move rd,rs; \ 161 .set pop; \ 1629: 163#define MOVZ(rd,rs,rt) \ 164 .set push; \ 165 .set reorder; \ 166 bnez rt,9f; \ 167 move rd,rs; \ 168 .set pop; \ 1699: 170#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ 171#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) 172#define MOVN(rd,rs,rt) \ 173 .set push; \ 174 .set noreorder; \ 175 bnezl rt,9f; \ 176 move rd,rs; \ 177 .set pop; \ 1789: 179#define MOVZ(rd,rs,rt) \ 180 .set push; \ 181 .set noreorder; \ 182 beqzl rt,9f; \ 183 move rd,rs; \ 184 .set pop; \ 1859: 186#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ 187#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ 188 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 189#define MOVN(rd,rs,rt) \ 190 movn rd,rs,rt 191#define MOVZ(rd,rs,rt) \ 192 movz rd,rs,rt 193#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ 194 195/* 196 * Stack alignment 197 */ 198#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ 199 (_MIPS_ISA == _MIPS_ISA_MIPS32) 200#define ALSZ 7 201#define ALMASK ~7 202#endif 203#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ 204 (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 205#define ALSZ 15 206#define ALMASK ~15 207#endif 208 209/* 210 * Macros to handle different pointer/register sizes for 32/64-bit code 211 */ 212 213/* 214 * Size of a register 215 */ 216#ifdef __mips64 217#define SZREG 8 218#else 219#define SZREG 4 220#endif 221 222/* 223 * Use the following macros in assemblercode to load/store registers, 224 * pointers etc. 225 */ 226#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ 227 (_MIPS_ISA == _MIPS_ISA_MIPS32) 228#define REG_S sw 229#define REG_L lw 230#define REG_SUBU subu 231#define REG_ADDU addu 232#endif 233#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ 234 (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 235#define REG_S sd 236#define REG_L ld 237#define REG_SUBU dsubu 238#define REG_ADDU daddu 239#endif 240 241/* 242 * How to add/sub/load/store/shift C int variables. 243 */ 244#if _MIPS_SZINT == 32 245#define INT_ADD add 246#define INT_ADDU addu 247#define INT_ADDI addi 248#define INT_ADDIU addiu 249#define INT_SUB sub 250#define INT_SUBU subu 251#define INT_L lw 252#define INT_S sw 253#define INT_SLL sll 254#define INT_SLLV sllv 255#define INT_SRL srl 256#define INT_SRLV srlv 257#define INT_SRA sra 258#define INT_SRAV srav 259#endif 260 261#if _MIPS_SZINT == 64 262#define INT_ADD dadd 263#define INT_ADDU daddu 264#define INT_ADDI daddi 265#define INT_ADDIU daddiu 266#define INT_SUB dsub 267#define INT_SUBU dsubu 268#define INT_L ld 269#define INT_S sd 270#define INT_SLL dsll 271#define INT_SLLV dsllv 272#define INT_SRL dsrl 273#define INT_SRLV dsrlv 274#define INT_SRA dsra 275#define INT_SRAV dsrav 276#endif 277 278/* 279 * How to add/sub/load/store/shift C long variables. 280 */ 281#if _MIPS_SZLONG == 32 282#define LONG_ADD add 283#define LONG_ADDU addu 284#define LONG_ADDI addi 285#define LONG_ADDIU addiu 286#define LONG_SUB sub 287#define LONG_SUBU subu 288#define LONG_L lw 289#define LONG_S sw 290#define LONG_SLL sll 291#define LONG_SLLV sllv 292#define LONG_SRL srl 293#define LONG_SRLV srlv 294#define LONG_SRA sra 295#define LONG_SRAV srav 296#endif 297 298#if _MIPS_SZLONG == 64 299#define LONG_ADD dadd 300#define LONG_ADDU daddu 301#define LONG_ADDI daddi 302#define LONG_ADDIU daddiu 303#define LONG_SUB dsub 304#define LONG_SUBU dsubu 305#define LONG_L ld 306#define LONG_S sd 307#define LONG_SLL dsll 308#define LONG_SLLV dsllv 309#define LONG_SRL dsrl 310#define LONG_SRLV dsrlv 311#define LONG_SRA dsra 312#define LONG_SRAV dsrav 313#endif 314 315/* 316 * How to add/sub/load/store/shift pointers. 317 */ 318#if _MIPS_SZPTR == 32 319#define PTR_ADD add 320#define PTR_ADDU addu 321#define PTR_ADDI addi 322#define PTR_ADDIU addiu 323#define PTR_SUB sub 324#define PTR_SUBU subu 325#define PTR_L lw 326#define PTR_S sw 327#define PTR_LA la 328#define PTR_SLL sll 329#define PTR_SLLV sllv 330#define PTR_SRL srl 331#define PTR_SRLV srlv 332#define PTR_SRA sra 333#define PTR_SRAV srav 334 335#define PTR_SCALESHIFT 2 336 337#define PTR .word 338#define PTRSIZE 4 339#define PTRLOG 2 340#endif 341 342#if _MIPS_SZPTR == 64 343#define PTR_ADD dadd 344#define PTR_ADDU daddu 345#define PTR_ADDI daddi 346#define PTR_ADDIU daddiu 347#define PTR_SUB dsub 348#define PTR_SUBU dsubu 349#define PTR_L ld 350#define PTR_S sd 351#define PTR_LA dla 352#define PTR_SLL dsll 353#define PTR_SLLV dsllv 354#define PTR_SRL dsrl 355#define PTR_SRLV dsrlv 356#define PTR_SRA dsra 357#define PTR_SRAV dsrav 358 359#define PTR_SCALESHIFT 3 360 361#define PTR .dword 362#define PTRSIZE 8 363#define PTRLOG 3 364#endif 365 366/* 367 * Some cp0 registers were extended to 64bit for MIPS III. 368 */ 369#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ 370 (_MIPS_ISA == _MIPS_ISA_MIPS32) 371#define MFC0 mfc0 372#define MTC0 mtc0 373#endif 374#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ 375 (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 376#define MFC0 dmfc0 377#define MTC0 dmtc0 378#endif 379 380#define SSNOP sll zero,zero,1 381 382#endif /* __ASM_ASM_H */ 383