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