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