162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 362306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 462306a36Sopenharmony_ci * for more details. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle 762306a36Sopenharmony_ci * Copyright (C) 1999 by Silicon Graphics, Inc. 862306a36Sopenharmony_ci * Copyright (C) 2001 MIPS Technologies, Inc. 962306a36Sopenharmony_ci * Copyright (C) 2002 Maciej W. Rozycki 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Some useful macros for MIPS assembler code 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * Some of the routines below contain useless nops that will be optimized 1462306a36Sopenharmony_ci * away by gas in -O mode. These nops are however required to fill delay 1562306a36Sopenharmony_ci * slots in noreorder mode. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci#ifndef __ASM_ASM_H 1862306a36Sopenharmony_ci#define __ASM_ASM_H 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <asm/sgidefs.h> 2162306a36Sopenharmony_ci#include <asm/asm-eva.h> 2262306a36Sopenharmony_ci#include <asm/isa-rev.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#ifndef __VDSO__ 2562306a36Sopenharmony_ci/* 2662306a36Sopenharmony_ci * Emit CFI data in .debug_frame sections, not .eh_frame sections. 2762306a36Sopenharmony_ci * We don't do DWARF unwinding at runtime, so only the offline DWARF 2862306a36Sopenharmony_ci * information is useful to anyone. Note we should change this if we 2962306a36Sopenharmony_ci * ever decide to enable DWARF unwinding at runtime. 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_ci#define CFI_SECTIONS .cfi_sections .debug_frame 3262306a36Sopenharmony_ci#else 3362306a36Sopenharmony_ci /* 3462306a36Sopenharmony_ci * For the vDSO, emit both runtime unwind information and debug 3562306a36Sopenharmony_ci * symbols for the .dbg file. 3662306a36Sopenharmony_ci */ 3762306a36Sopenharmony_ci#define CFI_SECTIONS 3862306a36Sopenharmony_ci#endif 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* 4162306a36Sopenharmony_ci * LEAF - declare leaf routine 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci#define LEAF(symbol) \ 4462306a36Sopenharmony_ci CFI_SECTIONS; \ 4562306a36Sopenharmony_ci .globl symbol; \ 4662306a36Sopenharmony_ci .align 2; \ 4762306a36Sopenharmony_ci .type symbol, @function; \ 4862306a36Sopenharmony_ci .ent symbol, 0; \ 4962306a36Sopenharmony_cisymbol: .frame sp, 0, ra; \ 5062306a36Sopenharmony_ci .cfi_startproc; \ 5162306a36Sopenharmony_ci .insn 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * NESTED - declare nested routine entry point 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_ci#define NESTED(symbol, framesize, rpc) \ 5762306a36Sopenharmony_ci CFI_SECTIONS; \ 5862306a36Sopenharmony_ci .globl symbol; \ 5962306a36Sopenharmony_ci .align 2; \ 6062306a36Sopenharmony_ci .type symbol, @function; \ 6162306a36Sopenharmony_ci .ent symbol, 0; \ 6262306a36Sopenharmony_cisymbol: .frame sp, framesize, rpc; \ 6362306a36Sopenharmony_ci .cfi_startproc; \ 6462306a36Sopenharmony_ci .insn 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* 6762306a36Sopenharmony_ci * END - mark end of function 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_ci#define END(function) \ 7062306a36Sopenharmony_ci .cfi_endproc; \ 7162306a36Sopenharmony_ci .end function; \ 7262306a36Sopenharmony_ci .size function, .-function 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/* 7562306a36Sopenharmony_ci * EXPORT - export definition of symbol 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci#define EXPORT(symbol) \ 7862306a36Sopenharmony_ci .globl symbol; \ 7962306a36Sopenharmony_cisymbol: 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci/* 8262306a36Sopenharmony_ci * FEXPORT - export definition of a function symbol 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_ci#define FEXPORT(symbol) \ 8562306a36Sopenharmony_ci .globl symbol; \ 8662306a36Sopenharmony_ci .type symbol, @function; \ 8762306a36Sopenharmony_cisymbol: .insn 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* 9062306a36Sopenharmony_ci * ABS - export absolute symbol 9162306a36Sopenharmony_ci */ 9262306a36Sopenharmony_ci#define ABS(symbol,value) \ 9362306a36Sopenharmony_ci .globl symbol; \ 9462306a36Sopenharmony_cisymbol = value 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#define TEXT(msg) \ 9762306a36Sopenharmony_ci .pushsection .data; \ 9862306a36Sopenharmony_ci8: .asciiz msg; \ 9962306a36Sopenharmony_ci .popsection; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#define ASM_PANIC(msg) \ 10262306a36Sopenharmony_ci .set push; \ 10362306a36Sopenharmony_ci .set reorder; \ 10462306a36Sopenharmony_ci PTR_LA a0, 8f; \ 10562306a36Sopenharmony_ci jal panic; \ 10662306a36Sopenharmony_ci9: b 9b; \ 10762306a36Sopenharmony_ci .set pop; \ 10862306a36Sopenharmony_ci TEXT(msg) 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* 11162306a36Sopenharmony_ci * Print formatted string 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_ci#ifdef CONFIG_PRINTK 11462306a36Sopenharmony_ci#define ASM_PRINT(string) \ 11562306a36Sopenharmony_ci .set push; \ 11662306a36Sopenharmony_ci .set reorder; \ 11762306a36Sopenharmony_ci PTR_LA a0, 8f; \ 11862306a36Sopenharmony_ci jal _printk; \ 11962306a36Sopenharmony_ci .set pop; \ 12062306a36Sopenharmony_ci TEXT(string) 12162306a36Sopenharmony_ci#else 12262306a36Sopenharmony_ci#define ASM_PRINT(string) 12362306a36Sopenharmony_ci#endif 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci/* 12662306a36Sopenharmony_ci * Stack alignment 12762306a36Sopenharmony_ci */ 12862306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32) 12962306a36Sopenharmony_ci#define ALSZ 7 13062306a36Sopenharmony_ci#define ALMASK ~7 13162306a36Sopenharmony_ci#endif 13262306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 13362306a36Sopenharmony_ci#define ALSZ 15 13462306a36Sopenharmony_ci#define ALMASK ~15 13562306a36Sopenharmony_ci#endif 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci/* 13862306a36Sopenharmony_ci * Macros to handle different pointer/register sizes for 32/64-bit code 13962306a36Sopenharmony_ci */ 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* 14262306a36Sopenharmony_ci * Size of a register 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ci#ifdef __mips64 14562306a36Sopenharmony_ci#define SZREG 8 14662306a36Sopenharmony_ci#else 14762306a36Sopenharmony_ci#define SZREG 4 14862306a36Sopenharmony_ci#endif 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci/* 15162306a36Sopenharmony_ci * Use the following macros in assemblercode to load/store registers, 15262306a36Sopenharmony_ci * pointers etc. 15362306a36Sopenharmony_ci */ 15462306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32) 15562306a36Sopenharmony_ci#define REG_S sw 15662306a36Sopenharmony_ci#define REG_L lw 15762306a36Sopenharmony_ci#define REG_SUBU subu 15862306a36Sopenharmony_ci#define REG_ADDU addu 15962306a36Sopenharmony_ci#endif 16062306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 16162306a36Sopenharmony_ci#define REG_S sd 16262306a36Sopenharmony_ci#define REG_L ld 16362306a36Sopenharmony_ci#define REG_SUBU dsubu 16462306a36Sopenharmony_ci#define REG_ADDU daddu 16562306a36Sopenharmony_ci#endif 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/* 16862306a36Sopenharmony_ci * How to add/sub/load/store/shift C int variables. 16962306a36Sopenharmony_ci */ 17062306a36Sopenharmony_ci#if (_MIPS_SZINT == 32) 17162306a36Sopenharmony_ci#define INT_ADD add 17262306a36Sopenharmony_ci#define INT_ADDU addu 17362306a36Sopenharmony_ci#define INT_ADDI addi 17462306a36Sopenharmony_ci#define INT_ADDIU addiu 17562306a36Sopenharmony_ci#define INT_SUB sub 17662306a36Sopenharmony_ci#define INT_SUBU subu 17762306a36Sopenharmony_ci#define INT_L lw 17862306a36Sopenharmony_ci#define INT_S sw 17962306a36Sopenharmony_ci#define INT_SLL sll 18062306a36Sopenharmony_ci#define INT_SLLV sllv 18162306a36Sopenharmony_ci#define INT_SRL srl 18262306a36Sopenharmony_ci#define INT_SRLV srlv 18362306a36Sopenharmony_ci#define INT_SRA sra 18462306a36Sopenharmony_ci#define INT_SRAV srav 18562306a36Sopenharmony_ci#endif 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci#if (_MIPS_SZINT == 64) 18862306a36Sopenharmony_ci#define INT_ADD dadd 18962306a36Sopenharmony_ci#define INT_ADDU daddu 19062306a36Sopenharmony_ci#define INT_ADDI daddi 19162306a36Sopenharmony_ci#define INT_ADDIU daddiu 19262306a36Sopenharmony_ci#define INT_SUB dsub 19362306a36Sopenharmony_ci#define INT_SUBU dsubu 19462306a36Sopenharmony_ci#define INT_L ld 19562306a36Sopenharmony_ci#define INT_S sd 19662306a36Sopenharmony_ci#define INT_SLL dsll 19762306a36Sopenharmony_ci#define INT_SLLV dsllv 19862306a36Sopenharmony_ci#define INT_SRL dsrl 19962306a36Sopenharmony_ci#define INT_SRLV dsrlv 20062306a36Sopenharmony_ci#define INT_SRA dsra 20162306a36Sopenharmony_ci#define INT_SRAV dsrav 20262306a36Sopenharmony_ci#endif 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/* 20562306a36Sopenharmony_ci * How to add/sub/load/store/shift C long variables. 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_ci#if (_MIPS_SZLONG == 32) 20862306a36Sopenharmony_ci#define LONG_ADD add 20962306a36Sopenharmony_ci#define LONG_ADDU addu 21062306a36Sopenharmony_ci#define LONG_ADDI addi 21162306a36Sopenharmony_ci#define LONG_ADDIU addiu 21262306a36Sopenharmony_ci#define LONG_SUB sub 21362306a36Sopenharmony_ci#define LONG_SUBU subu 21462306a36Sopenharmony_ci#define LONG_L lw 21562306a36Sopenharmony_ci#define LONG_LL ll 21662306a36Sopenharmony_ci#define LONG_SC sc 21762306a36Sopenharmony_ci#define LONG_S sw 21862306a36Sopenharmony_ci#define LONG_SP swp 21962306a36Sopenharmony_ci#define LONG_SLL sll 22062306a36Sopenharmony_ci#define LONG_SLLV sllv 22162306a36Sopenharmony_ci#define LONG_SRL srl 22262306a36Sopenharmony_ci#define LONG_SRLV srlv 22362306a36Sopenharmony_ci#define LONG_SRA sra 22462306a36Sopenharmony_ci#define LONG_SRAV srav 22562306a36Sopenharmony_ci#define LONG_INS ins 22662306a36Sopenharmony_ci#define LONG_EXT ext 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci#ifdef __ASSEMBLY__ 22962306a36Sopenharmony_ci#define LONG .word 23062306a36Sopenharmony_ci#endif 23162306a36Sopenharmony_ci#define LONGSIZE 4 23262306a36Sopenharmony_ci#define LONGMASK 3 23362306a36Sopenharmony_ci#define LONGLOG 2 23462306a36Sopenharmony_ci#endif 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci#if (_MIPS_SZLONG == 64) 23762306a36Sopenharmony_ci#define LONG_ADD dadd 23862306a36Sopenharmony_ci#define LONG_ADDU daddu 23962306a36Sopenharmony_ci#define LONG_ADDI daddi 24062306a36Sopenharmony_ci#define LONG_ADDIU daddiu 24162306a36Sopenharmony_ci#define LONG_SUB dsub 24262306a36Sopenharmony_ci#define LONG_SUBU dsubu 24362306a36Sopenharmony_ci#define LONG_L ld 24462306a36Sopenharmony_ci#define LONG_LL lld 24562306a36Sopenharmony_ci#define LONG_SC scd 24662306a36Sopenharmony_ci#define LONG_S sd 24762306a36Sopenharmony_ci#define LONG_SP sdp 24862306a36Sopenharmony_ci#define LONG_SLL dsll 24962306a36Sopenharmony_ci#define LONG_SLLV dsllv 25062306a36Sopenharmony_ci#define LONG_SRL dsrl 25162306a36Sopenharmony_ci#define LONG_SRLV dsrlv 25262306a36Sopenharmony_ci#define LONG_SRA dsra 25362306a36Sopenharmony_ci#define LONG_SRAV dsrav 25462306a36Sopenharmony_ci#define LONG_INS dins 25562306a36Sopenharmony_ci#define LONG_EXT dext 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci#ifdef __ASSEMBLY__ 25862306a36Sopenharmony_ci#define LONG .dword 25962306a36Sopenharmony_ci#endif 26062306a36Sopenharmony_ci#define LONGSIZE 8 26162306a36Sopenharmony_ci#define LONGMASK 7 26262306a36Sopenharmony_ci#define LONGLOG 3 26362306a36Sopenharmony_ci#endif 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci/* 26662306a36Sopenharmony_ci * How to add/sub/load/store/shift pointers. 26762306a36Sopenharmony_ci */ 26862306a36Sopenharmony_ci#if (_MIPS_SZPTR == 32) 26962306a36Sopenharmony_ci#define PTR_ADD add 27062306a36Sopenharmony_ci#define PTR_ADDU addu 27162306a36Sopenharmony_ci#define PTR_ADDI addi 27262306a36Sopenharmony_ci#define PTR_ADDIU addiu 27362306a36Sopenharmony_ci#define PTR_SUB sub 27462306a36Sopenharmony_ci#define PTR_SUBU subu 27562306a36Sopenharmony_ci#define PTR_L lw 27662306a36Sopenharmony_ci#define PTR_S sw 27762306a36Sopenharmony_ci#define PTR_LA la 27862306a36Sopenharmony_ci#define PTR_LI li 27962306a36Sopenharmony_ci#define PTR_SLL sll 28062306a36Sopenharmony_ci#define PTR_SLLV sllv 28162306a36Sopenharmony_ci#define PTR_SRL srl 28262306a36Sopenharmony_ci#define PTR_SRLV srlv 28362306a36Sopenharmony_ci#define PTR_SRA sra 28462306a36Sopenharmony_ci#define PTR_SRAV srav 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci#define PTR_SCALESHIFT 2 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci#define PTR_WD .word 28962306a36Sopenharmony_ci#define PTRSIZE 4 29062306a36Sopenharmony_ci#define PTRLOG 2 29162306a36Sopenharmony_ci#endif 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci#if (_MIPS_SZPTR == 64) 29462306a36Sopenharmony_ci#define PTR_ADD dadd 29562306a36Sopenharmony_ci#define PTR_ADDU daddu 29662306a36Sopenharmony_ci#define PTR_ADDI daddi 29762306a36Sopenharmony_ci#define PTR_ADDIU daddiu 29862306a36Sopenharmony_ci#define PTR_SUB dsub 29962306a36Sopenharmony_ci#define PTR_SUBU dsubu 30062306a36Sopenharmony_ci#define PTR_L ld 30162306a36Sopenharmony_ci#define PTR_S sd 30262306a36Sopenharmony_ci#define PTR_LA dla 30362306a36Sopenharmony_ci#define PTR_LI dli 30462306a36Sopenharmony_ci#define PTR_SLL dsll 30562306a36Sopenharmony_ci#define PTR_SLLV dsllv 30662306a36Sopenharmony_ci#define PTR_SRL dsrl 30762306a36Sopenharmony_ci#define PTR_SRLV dsrlv 30862306a36Sopenharmony_ci#define PTR_SRA dsra 30962306a36Sopenharmony_ci#define PTR_SRAV dsrav 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci#define PTR_SCALESHIFT 3 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci#define PTR_WD .dword 31462306a36Sopenharmony_ci#define PTRSIZE 8 31562306a36Sopenharmony_ci#define PTRLOG 3 31662306a36Sopenharmony_ci#endif 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci/* 31962306a36Sopenharmony_ci * Some cp0 registers were extended to 64bit for MIPS III. 32062306a36Sopenharmony_ci */ 32162306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32) 32262306a36Sopenharmony_ci#define MFC0 mfc0 32362306a36Sopenharmony_ci#define MTC0 mtc0 32462306a36Sopenharmony_ci#endif 32562306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 32662306a36Sopenharmony_ci#define MFC0 dmfc0 32762306a36Sopenharmony_ci#define MTC0 dmtc0 32862306a36Sopenharmony_ci#endif 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci#define SSNOP sll zero, zero, 1 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci/* 33362306a36Sopenharmony_ci * Using a branch-likely instruction to check the result of an sc instruction 33462306a36Sopenharmony_ci * works around a bug present in R10000 CPUs prior to revision 3.0 that could 33562306a36Sopenharmony_ci * cause ll-sc sequences to execute non-atomically. 33662306a36Sopenharmony_ci */ 33762306a36Sopenharmony_ci#ifdef CONFIG_WAR_R10000_LLSC 33862306a36Sopenharmony_ci# define SC_BEQZ beqzl 33962306a36Sopenharmony_ci#elif !defined(CONFIG_CC_HAS_BROKEN_INLINE_COMPAT_BRANCH) && MIPS_ISA_REV >= 6 34062306a36Sopenharmony_ci# define SC_BEQZ beqzc 34162306a36Sopenharmony_ci#else 34262306a36Sopenharmony_ci# define SC_BEQZ beqz 34362306a36Sopenharmony_ci#endif 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci#ifdef CONFIG_SGI_IP28 34662306a36Sopenharmony_ci/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 34762306a36Sopenharmony_ci#include <asm/cacheops.h> 34862306a36Sopenharmony_ci#define R10KCBARRIER(addr) cache Cache_Barrier, addr; 34962306a36Sopenharmony_ci#else 35062306a36Sopenharmony_ci#define R10KCBARRIER(addr) 35162306a36Sopenharmony_ci#endif 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci#endif /* __ASM_ASM_H */ 354