Files
2026-07-30 11:19:44 +05:30

716 lines
25 KiB
C

/* asmMips.h - assembler definitions header file */
/*
* Copyright (c) 1991-1993, 1996-1997, 1999, 2001-2002, 2004, 2006-2011
* Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
* This file has been developed or significantly modified by the
* MIPS Center of Excellence Dedicated Engineering Staff.
* This notice is as per the MIPS Center of Excellence Master Partner
* Agreement, do not remove this notice without checking first with
* WR/Platforms MIPS Center of Excellence engineering management.
*/
/*
modification history
--------------------
02n,01sep11,slk add register size selectable subu and addu
02m,02mar11,d_c Add FUNC_EXPORT() macro.
02m,03mar11,slk add xlp variant support
02l,28sep10,d_c remove warning about .word values
02k,23jul10,rlg addition of some cavium specific defines part of SDK removal
02m,27may10,d_c Rename CAVIUM_CNMIPS_* to _WRS_CAVIUM_CNMIPS_* and define in
arch Makefile
02l,28apr10,d_c LPA and execute inhibit support
02k,31mar10,d_c Add cav_cn5xxx and cav_cn6xxx variants
02j,27jul09,pch CQ154839: add _WRS_MIPS_ERET24K_ERRATA
02i,08jul09,slk add FUNC_BEGIN and FUNC_END
02h,20apr09,pch Import PARAM_OFFSET from rtpALib.s
02g,26feb09,pgh Remove _WRS_MIPS_SDA_SUPPORTED #if
02f,08feb09,pch add HAZARD_NULL
02e,08aug08,slk add _WRS_MIPS_SDA_OFFSET macro for gnu and diab SDA
region accesses
02d,26sep07,d_c Add extended interrupts for RMI _xlr variant
02c,16aug07,agf Define empty hazard set for fully interlocked cores
02b,10aug07,rlg MIPS library restructure changes
02a,29jul07,pes Addition of more registers for Cavium save/restore
01z,15may07,sru N32 stack alignment set to 16-byte aligned
01y,28mar07,rlg updates to allow for full 64 bit register access on li
instructions
01y,29mar07,pes Adjust stack frame macros for n32 use.
01x,18jul06,pes Move SMP macros to private header.
01y,28aug06,pes Enclose macro definitions in #ifdef _ASMLANGUAGE/#endif
to prevent namespace collision if this file is included
in a "C" file. (WIND00035912)
01x,21jun06,rlg removal of SMP macros
01w,24may06,pes Remove macros dealing with _mipsSrImask and _mipsEsfTail.
01v,11may06,pes Add macros for SMP support.
01u,24apr06,pes Add SMP support.
01t,17jun04,pes Add definition of _RTypeSize.
01s,05may04,pes Correct build failures caused by 01r.
01r,28apr04,pes Adjusting hazard include file mechanism.
01q,23oct02,jmt Modified to handle Arch Specific hazards
01p,01aug01,mem Changes to support diab.
01o,16jul01,ros add CofE comment
01n,20apr01,roz Added SWC1/LWC1
01m,09apr01,mem Correct stack frame macros for MIPS64
01l,09feb01,tlc Introduce HAZARD macro definitions.
01k,03jan01,pes Added GTEXT and GDATA for declaring functions and data
01j,19jan99,dra added CW4000, CW4011, VR4100, VR5000 and VR5400 support.
fixed SETFRAME macro to keep stack 8-byte aligned.
01i,18apr97,kkk added C0_PRID for R3000. (SPR# 8321)
01h,22nov96,kkk add back C0_TLBHI for R3000.
01g,21nov96,kkk enabled SW/LW for R4650.
01g,14oct96,kkk added R4650 support.
01f,15oct93,cd added R4000 support; defined frame macros.
01e,22sep92,rrr added support for c++
01d,03jun92,ajm updated file name referenced to match real name
01c,26may92,rrr the tree shuffle
01b,04oct91,rrr passed through the ansification filter
-changed copyright notice
01a,21feb91,ajm written.
*/
#ifndef __INCasmMipsh
#define __INCasmMipsh
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
/*
* The LEADING_UNDERSCORE macro should be defined to TRUE for toolchains
* that do NOT prefix a leading underscore character, i.e. "_", to
* symbols. Define the macro to FALSE when using a toolchain that
* does add a leading underscore character to symbols.
*/
#define LEADING_UNDERSCORE FALSE
#if (LEADING_UNDERSCORE == TRUE)
#define FUNC_EXPORT(func) .globl _##func
#define FUNC(func) _##func
#define FUNC_LABEL(func) _##func:
#else
#define FUNC_EXPORT(func) .globl func
#define FUNC(func) func
#define FUNC_LABEL(func) func:
#endif
/* Introduced to abstract assembler idiosyncrasies */
#define FUNC_BEGIN(func) FUNC_LABEL(func)
#define FUNC_END(func) .size FUNC(func), . - FUNC(func)
#define FUNC_DECL(range,func)
#define VAR_DECL(var) var
#define VAR(var) var(r0)
/*
* These macros are used to declare assembly language symbols that need
* to be typed properly(func or data) to be visible to the OMF tool.
* So that the build tool could mark them as an entry point to be linked
* by another PD.
*/
#define GTEXT(sym) FUNC(sym) ; .type FUNC(sym),@function
#define GDATA(sym) FUNC(sym) ; .type FUNC(sym),@object
#define FUNCREF(func) func
/*
* MIPS register definitions
*/
#define zero $0 /* wired zero */
#define AT $at /* assembler temp */
#define v0 $2 /* return reg 0 */
#define v1 $3 /* return reg 1 */
#define a0 $4 /* arg reg 0 */
#define a1 $5 /* arg reg 1 */
#define a2 $6 /* arg reg 2 */
#define a3 $7 /* arg reg 3 */
#define t0 $8 /* caller saved 0 */
#define t1 $9 /* caller saved 1 */
#define t2 $10 /* caller saved 2 */
#define t3 $11 /* caller saved 3 */
#define t4 $12 /* caller saved 4 */
#define t5 $13 /* caller saved 5 */
#define t6 $14 /* caller saved 6 */
#define t7 $15 /* caller saved 7 */
#define s0 $16 /* callee saved 0 */
#define s1 $17 /* callee saved 1 */
#define s2 $18 /* callee saved 2 */
#define s3 $19 /* callee saved 3 */
#define s4 $20 /* callee saved 4 */
#define s5 $21 /* callee saved 5 */
#define s6 $22 /* callee saved 6 */
#define s7 $23 /* callee saved 7 */
#define t8 $24 /* caller saved 8 */
#define t9 $25 /* caller saved 9 */
#define k0 $26 /* kernel temp 0 */
#define k1 $27 /* kernel temp 1 */
#define gp $28 /* global pointer */
#define sp $29 /* stack pointer */
#define s8 $30 /* callee saved 8 */
#define ra $31 /* return address */
#ifdef _WRS_MIPS_N32_ABI
#define a4 $8 /* arg register 4 (== t0 in OABI) */
#define a5 $9 /* arg register 5 (== t1 in OABI)*/
#define a6 $10 /* arg register 6 (== t2 in OABI) */
#define a7 $11 /* arg register 7 (== t3 in OABI) */
#endif /* _wRS_MIPS_N32_ABI */
/*
* MIPS Coprocessor 0 regs
*/
#define C0_IBASE $0 /* R4650: instruction base xlate address */
#define C0_IBOUND $1 /* R4650: instruction xlate address bound */
#define C0_DBASE $2 /* R4650: data base xlate address */
#define C0_DBOUND $3 /* R4650: data xlate address bound */
#define C0_INX $0 /* tlb index */
#define C0_RAND $1 /* tlb random */
/* Begin CPUs: R3000, CW4000, CW4011 */
#define C0_TLBLO $2 /* tlb entry low */
/* End R3000, CW4000, CW4011 */
/* Begin CPUs: R4000, VR5000, VR5400, VR4100 */
#define C0_TLBLO0 $2 /* tlb entry low 0 */
#define C0_TLBLO1 $3 /* tlb entry low 1 */
/* End R4000, VR5000, VR5400, VR4100 */
#define C0_CTXT $4 /* tlb context */
/* Begin CPUs: R4000, VR5000, VR5400, VR4100 */
#define C0_PAGEMASK $5 /* page mask */
#define C0_WIRED $6 /* lb wired entries */
/* End R4000, VR5000, VR5400, VR4100 */
#if defined(_WRS_CAVIUM_CNMIPS_CORE) || defined(_WRS_CAVIUM_CNMIPS_II_CORE)
#define C0_HWRENA $7
#endif /* _WRS_CAVIUM_CNMIPS_CORE || _WRS_CAVIUM_CNMIPS_II_CORE */
#define C0_BADVADDR $8 /* bad virtual address */
/* Begin CPUs: R4000, R4650, VR5000, VR5400, CW4011, VR4100 */
#define C0_COUNT $9 /* count */
/* End R4000, R4650, VR5000, VR5400, CW4011, VR4100 */
#if defined(_WRS_CAVIUM_CNMIPS_CORE) || defined(_WRS_CAVIUM_CNMIPS_II_CORE)
#define C0_CAVCNTL $9,7
#define C0_PAGE_GRAIN $5,1
#endif /* _WRS_CAVIUM_CNMIPS_CORE || _WRS_CAVIUM_CNMIPS_II_CORE */
/* Begin CPUs: R4000, VR5000, VR5400, R3000, CW4000, CW4011, VR4100 */
#define C0_TLBHI $10 /* tlb entry hi */
/* End R4000, VR5000, VR5400, R3000, CW4000, CW4011, VR4100 */
/* Begin CPUs: R4000, VR5000, VR5400, R4650, CW4011, VR4100 */
#define C0_COMPARE $11 /* compare */
#if defined(_WRS_CAVIUM_CNMIPS_CORE) || defined(_WRS_CAVIUM_CNMIPS_II_CORE)
#define C0_CAV_MEMCTL $11,7
#endif /* _WRS_CAVIUM_CNMIPS_CORE || _WRS_CAVIUM_CNMIPS_II_CORE */
/* End R4000, VR5000, VR5400, R4650, CW4011, VR4100*/
#define C0_SR $12 /* status register */
#define C0_CAUSE $13 /* exception cause */
#define C0_EPC $14 /* exception pc */
#define C0_PRID $15
#if defined(_WRS_CAVIUM_CNMIPS_CORE) || defined(_WRS_CAVIUM_CNMIPS_II_CORE)
#define C0_EBASE $15,1
#endif /* _WRS_CAVIUM_CNMIPS_CORE || _WRS_CAVIUM_CNMIPS_II_CORE */
/* Begin CPUs: R4000, R4650, VR5000, VR5400, VR4100, CW4011 */
#define C0_CONFIG $16
#define C0_CALG $17 /* R4650: cache algorithm register */
#define C0_LLADDR $17
#define C0_IWATCH $18 /* R4650: instruction virt addr for watch */
#define C0_WATCHLO $18
#define C0_DWATCH $19 /* R4650: data virt addr for watch */
#define C0_WATCHHI $19
#define C0_ECC $26
#define C0_CACHEERR $27
#define C0_TAGLO $28
/* Begin CPUs: R4000, VR5000, VR5400, VR4100 */
#define C0_TAGHI $29
/* End R4000, VR5000, VR5400, VR4100 */
#define C0_ERRPC $30
/* End R4000, R4650, VR5000, VR5400, VR4100, CW4011 */
/*
* MIPS floating point coprocessor register definitions
*/
#define fp0 $f0 /* return reg 0 */
#define fp1 $f1 /* return reg 1 */
#define fp2 $f2 /* return reg 2 */
#define fp3 $f3 /* return reg 3 */
#define fp4 $f4 /* caller saved 0 */
#define fp5 $f5 /* caller saved 1 */
#define fp6 $f6 /* caller saved 2 */
#define fp7 $f7 /* caller saved 3 */
#define fp8 $f8 /* caller saved 4 */
#define fp9 $f9 /* caller saved 5 */
#define fp10 $f10 /* caller saved 6 */
#define fp11 $f11 /* caller saved 7 */
#define fp12 $f12 /* arg reg 0 */
#define fp13 $f13 /* arg reg 1 */
#define fp14 $f14 /* arg reg 2 */
#define fp15 $f15 /* arg reg 3 */
#define fp16 $f16 /* caller saved 8 */
#define fp17 $f17 /* caller saved 9 */
#define fp18 $f18 /* caller saved 10 */
#define fp19 $f19 /* caller saved 11 */
#define fp20 $f20 /* callee saved 0 */
#define fp21 $f21 /* callee saved 1 */
#define fp22 $f22 /* callee saved 2 */
#define fp23 $f23 /* callee saved 3 */
#define fp24 $f24 /* callee saved 4 */
#define fp25 $f25 /* callee saved 5 */
#define fp26 $f26 /* callee saved 6 */
#define fp27 $f27 /* callee saved 7 */
#define fp28 $f28 /* callee saved 8 */
#define fp29 $f29 /* callee saved 9 */
#define fp30 $f30 /* callee saved 10 */
#define fp31 $f31 /* callee saved 11 */
#define C1_IR $0 /* implementation/revision reg */
#define C1_SR $31 /* control/status reg */
/*
* define aliases for operations that are different in 64bit mode
*/
#if (_WRS_INT_REGISTER_SIZE == 4)
#define SW sw
#define LW lw
#define MFC0 mfc0
#define MTC0 mtc0
#define LI li
#define SUBU subu
#define ADDU addu
#define SRL srl
#define SLL sll
#ifdef _WRS_MIPS_ENABLE_LPA
#error LPA not supported on processors with 4-byte internal registers.
#endif
#define SW_LPA sw
#define LW_LPA lw
#define MFC0_LPA mfc0
#define MTC0_LPA mtc0
#elif (_WRS_INT_REGISTER_SIZE == 8)
#define SW sd /* storing machine registers */
#define LW ld /* loading machine registers */
#define MFC0 dmfc0 /* reading wide cop0 register */
#define MTC0 dmtc0 /* writing wide cop0 register */
#define LI dli
#define SUBU dsubu
#define ADDU daddu
#define SRL dsrl
#define SLL dsll
#if defined (_WRS_MIPS_ENABLE_LPA)
/* The variants which have 8 byte regs, but 4 byte TLB entryLo regs
* can not support LPA. Check for them here.
*/
#if defined (MIPSXX_mti5kx)
#error This variant can not support LPA because it has 32 bit TLB entryLo regs.
#endif
#define SW_LPA sd
#define LW_LPA ld
#define MFC0_LPA dmfc0
#define MTC0_LPA dmtc0
#else /* ! _WRS_MIPS_ENABLE_LPA */
#define SW_LPA sw
#define LW_LPA lw
#define MFC0_LPA mfc0
#define MTC0_LPA mtc0
#endif /* defined (_WRS_MIPS_ENABLE_LPA) */
#else /* _WRS_INT_REGISTER_SIZE */
#error "invalid _WRS_INT_REGISTER_SIZE value"
#endif /* _WRS_INT_REGISTER_SIZE */
#define _RTypeSize _WRS_INT_REGISTER_SIZE
#if (_WRS_FP_REGISTER_SIZE == 4)
#define SWC1 swc1
#define LWC1 lwc1
#define MFC1 mfc1
#define MTC1 mtc1
#elif (_WRS_FP_REGISTER_SIZE == 8)
#define SWC1 sdc1
#define LWC1 ldc1
#define MFC1 dmfc1 /* reading wide fp register */
#define MTC1 dmtc1 /* writing wide fp register */
#elif /* _WRS_FP_REGISTER_SIZE */
#error "invalid _WRS_FP_REGISTER_SIZE value"
#endif /* _WRS_FP_REGISTER_SIZE */
/* Hazard definitions */
/*
* A MIPS Hazard is defined as any combination of instructions which
* would cause unpredictable behavior in terms of pipeline delays,
* cache misses, and exceptions. Hazards are defined by the number
* of CPU cycles that must pass between certain combinations of
* instructions. Because some MIPS CPUs single-issue nop instructions
* while others dual-issue, the CPU cycles defined below are done so
* according to the instruction issue mechanism available.
*/
#define SINGLE_ISSUE 0
#define DUAL_ISSUE 1
#define CPU_CYCLES DUAL_ISSUE
/*
* Using the issue mechanism definitions above, the MIPS CPU cycles
* are defined below.
*/
#define ssnop .word 0x00000040
#if (CPU_CYCLES == SINGLE_ISSUE)
#define CPU_CYCLES_ONE ssnop
#define CPU_CYCLES_TWO ssnop; ssnop
#elif (CPU_CYCLES == DUAL_ISSUE)
#define CPU_CYCLES_ONE ssnop; ssnop
#define CPU_CYCLES_TWO ssnop; ssnop; ssnop; ssnop
#endif
/*
* Sixteen instructions are required to handle the VR5432 errata in
* order to fill its instruction prefetch. See HAZARD_VR5400 macro
* for details.
*/
#define CPU_CYCLES_SIXTEEN ssnop; ssnop; ssnop; ssnop; \
ssnop; ssnop; ssnop; ssnop; \
ssnop; ssnop; ssnop; ssnop; \
ssnop; ssnop; ssnop; ssnop
/*
* To assist with handling MIPS hazards, a number of categories of
* hazards have been defined here.
*
* HAZARD_TLB After modifying tlb CP0 registers, do not use the
* TLB for two CPU cycles.
* HAZARD_ERET After modifying the SR, do not return from an
* exception for two CPU cycles.
* HAZARD_INTERRUPT After modifying the SR, interrupts do not lock
* for two CPU cycles.
* HAZARD_CP_READ After a read from a Coprocessor register, the
* result is not available for one CPU cycle.
* HAZARD_CP_WRITE After a write to a Coprocessor register, the
* result is not effective for two CPU cycles.
* HAZARD_CACHE_TAG Cache TAG load and store instructions should
* not be used withing one CPU cycle of modifying
* the TAG registers.
* HAZARD_CACHE Cache instructions should not be used within 2
* CPU cycles of each other.
* HAZARD_VR5400 For the VR5432 CPU only. Serialized instructions
* (mtc0, ctc0, mfc0, cfc0, etc) must not appear within
* 16 instructions after a conditional branch or label.
*
* These hazard macros are intended for use with MIPS architecture-
* dependent assembly files which require handling hazards. For example,
* suppose interrupts are being locked, to address the hazard, please
* do the following:
*
* mtc0 t0, C0_SR
* HAZARD_INTERRUPT
* lw t0, 0(a0)
*
* Similarly, when reading from a coprocessor register, please do the
* following:
*
* mfc0 t0, C0_SR
* HAZARD_CP_READ
* and t0, t0, t1
* mtc0 t0, C0_SR
* HAZARD_CP_WRITE
*
*
* For more details on these categories, please refer to MIPS hazard
* documentation.
*/
/* Hazard macros */
/*
* The following is a do-nothing that results in no binary code. It is
* a placeholder req'd for proper macro expansion in some situations.
*/
#define HAZARD_NULL . = .
/*
* If this arch requires non-standard Hazard defs, include the hazard file
* defined for this arch. Otherwise, use the defaults.
*/
#define HAZARD_STRINGIFY(x) #x
#define HAZARD_HDR(file) HAZARD_STRINGIFY(arch/mips/file)
#define HAZARD_INCLUDE(file) HAZARD_HDR(HAZARD_FILE)
#ifdef HAZARD_FILE
#include HAZARD_INCLUDE(file)
#else
#ifdef _WRS_MIPS_FULL_HW_INTERLOCK
#define HAZARD_TLB
#define HAZARD_ERET
#define HAZARD_CP_READ HAZARD_NULL
#define HAZARD_CP_WRITE HAZARD_NULL
#define HAZARD_CACHE_TAG
#define HAZARD_CACHE HAZARD_NULL
#define HAZARD_INTERRUPT HAZARD_NULL
#else
#define HAZARD_TLB CPU_CYCLES_TWO
#define HAZARD_ERET CPU_CYCLES_TWO
#define HAZARD_CP_READ CPU_CYCLES_ONE
#define HAZARD_CP_WRITE CPU_CYCLES_TWO
#define HAZARD_CACHE_TAG CPU_CYCLES_ONE
#define HAZARD_CACHE CPU_CYCLES_TWO
#define HAZARD_INTERRUPT CPU_CYCLES_TWO
#endif /* _WRS_MIPS_FULL_HW_INTERLOCK */
#endif /* HAZARD_FILE */
#ifdef _WRS_MIPS_VR5400_ERRATA
#define HAZARD_VR5400 CPU_CYCLES_SIXTEEN
#else /* _WRS_MIPS_VR5400_ERRATA */
#define HAZARD_VR5400
#endif /* _WRS_MIPS_VR5400_ERRATA */
#ifdef _WRS_MIPS_ERET24K_ERRATA
#define ERET eret ; nop
#else /* _WRS_MIPS_ERET24K_ERRATA */
#define ERET eret
#endif /* _WRS_MIPS_ERET24K_ERRATA */
#if defined(_WRS_CAVIUM_CNMIPS_CORE) || defined(_WRS_CAVIUM_CNMIPS_II_CORE)
/* Macros to generate instructions */
/* must use register numbers here, not names or with $ prefix. */
/* defines for register numbers */
#define ZERO 0 /* zero register */
#define V0 2 /* return reg 0 */
#define V1 3 /* return reg 1 */
#define A0 4 /* arg reg 0 */
#define A1 5 /* arg reg 1 */
#define A2 6 /* arg reg 2 */
#define A3 7 /* arg reg 3 */
#define T0 8 /* caller saved 0 */
#define T1 9 /* caller saved 1 */
#define T2 10 /* caller saved 2 */
#define T3 11 /* caller saved 3 */
#define T4 12 /* caller saved 4 */
#define T5 13 /* caller saved 5 */
#define T6 14 /* caller saved 6 */
#define T7 15 /* caller saved 7 */
#define S0 16 /* callee saved 0 */
#define S1 17 /* callee saved 1 */
#define S2 18 /* callee saved 2 */
#define S3 19 /* callee saved 3 */
#define S4 20 /* callee saved 4 */
#define S5 21 /* callee saved 5 */
#define S6 22 /* callee saved 6 */
#define S7 23 /* callee saved 7 */
#define T8 24 /* caller saved 8 */
#define T9 25 /* caller saved 9 */
/* 192-bit * 64-bit Unsigned Multiply and Add: v3mulu */
#define CAV_V3MULU(rd,rs,rt) .word (0x70000011 | \
((rd) << 11) | \
((rs) << 21) | \
((rt) << 16))
/* Move to multiplier registers */
#define CAV_MTM0(rs) .word (0x70000008 | \
((rs) << 21))
#define CAV_MTM1(rs) .word (0x7000000c | \
((rs) << 21))
#define CAV_MTM2(rs) .word (0x7000000d | \
((rs) << 21))
#define CAV_MTP0(rs) .word (0x70000009 | \
((rs) << 21))
#define CAV_MTP1(rs) .word (0x7000000a | \
((rs) << 21))
#define CAV_MTP2(rs) .word (0x7000000b | \
((rs) << 21))
#endif /* defined(_WRS_CAVIUM_CNMIPS_CORE) || defined(_WRS_CAVIUM_CNMIPS_II_CORE) */
#if defined(MIPSXX_xlr) || defined(MIPSXX_xlp)
#define C0_EIRR $9,6
#define C0_EIMR $9,7
#endif /* MIPSXX_xlr || MIPSXX_xlp */
/*
* Stack frame allocation.
* These macros are used in assembly language routines to automate the
* allocation and use of stack frames. They create a stack frame that
* looks like this:
*
#ifdef _WRS_MIPS_N32_ABI
*
* +-------+<--- Original SP (16-byte aligned)
* | RA | Storage for return address (8 bytes for alignment)
* +-------+
* | extra | Optional additional storage requested by SETFRAME_EXTRA
* +-------+
* | r0-rN | Storage for up to 4 additional local registers
* +-------+
* | a0-aN | Storage for up to 8 argument regs
* +-------+<--- Adjusted SP (16-byte aligned)
*
#else /@ _WRS_MIPS_N32_ABI @/
*
* +-------+
* | a0-a3 | Storage provided by ABI contract from calling function
* +-------+<--- Original SP
* | RA | Storage for return address (8 bytes for alignment)
* +-------+
* | extra | Optional additional storage requested by SETFRAME_EXTRA
* +-------+
* | r0-rN | Storage for up to 4 additional local registers
* +-------+
* |(a0-a3)| Storage provided by ABI contract to called function
* +-------+<--- Adjusted SP
*
#endif /@ _WRS_MIPS_N32_ABI @/
*
*
*/
/* Return the size of the frame for the named routine */
#define FRAMESZ(routine) _##routine##Fsize
#ifdef _WRS_MIPS_N32_ABI
#define FRAMEASZ(routine) _##routine##ARsize
#endif
#ifdef _WRS_MIPS_N32_ABI
/*
* Calculate the frame size for the named routine
* up to 8 register slots allocated for subroutines to store argument registers
* 8 bytes are allocated for saving RA (independent of register size).
* nregs register locations are reserved for storing locally used registers.
* stack is kept 16-byte aligned.
*/
#define SETFRAME_EXTRA(routine,naregs,nregs,extra) \
FRAMEASZ(routine) = ((_RTypeSize)*(naregs)); \
FRAMESZ(routine) = ((((_RTypeSize)*((naregs)+(nregs)))+8+(extra)+15) & ~0x0f)
#else /* _WRS_MIPS_N32_ABI */
/*
* Calculate the frame size for the named routine
* 4 register slots allocated for subroutines to store argument registers
* 8 bytes are allocated for saving RA (independent of register size).
* nregs register locations are reserved for storing locally used registers.
* stack is kept 8-byte aligned.
*/
#define SETFRAME_EXTRA(routine,naregs,nregs,extra) \
FRAMESZ(routine) = ((((_RTypeSize)*(4+(nregs)))+8+(extra)+7) & ~0x07)
#endif /* _WRS_MIPS_N32_ABI */
#define SETFRAME(routine,naregs,nregs) \
SETFRAME_EXTRA(routine,naregs,nregs,0)
/* The location at which to store the return address */
#define FRAMERA(routine) (FRAMESZ(routine)-8)
/* Locations at which to store locally used registers */
#ifdef _WRS_MIPS_N32_ABI
#define FRAMER(routine,regn) (FRAMEASZ(routine)+(_RTypeSize)*(regn))
#else /* _WRS_MIPS_N32_ABI */
#define FRAMER(routine,regn) ((_RTypeSize)*(4+(regn)))
#endif /* _WRS_MIPS_N32_ABI */
#define FRAMER0(routine) FRAMER(routine,0)
#define FRAMER1(routine) FRAMER(routine,1)
#define FRAMER2(routine) FRAMER(routine,2)
#define FRAMER3(routine) FRAMER(routine,3)
/* Locations at which to store argument registers */
#ifdef _WRS_MIPS_N32_ABI
#define FRAMEA(routine, regn) ( (_RTypeSize)*(regn))
#else /* _WRS_MIPS_N32_ABI */
#define FRAMEA(routine, regn) (FRAMESZ(routine)+(_RTypeSize)*(regn))
#endif /* _WRS_MIPS_N32_ABI */
#define FRAMEA0(routine) FRAMEA(routine,0)
#define FRAMEA1(routine) FRAMEA(routine,1)
#define FRAMEA2(routine) FRAMEA(routine,2)
#define FRAMEA3(routine) FRAMEA(routine,3)
#ifdef _WRS_MIPS_N32_ABI
#define FRAMEA4(routine) FRAMEA(routine,4)
#define FRAMEA5(routine) FRAMEA(routine,5)
#define FRAMEA6(routine) FRAMEA(routine,6)
#define FRAMEA7(routine) FRAMEA(routine,7)
#endif /* _WRS_MIPS_N32_ABI */
/*
* _NABI() and _OABI() are used as wrappers for assembly instructions
* that should only be emited under the N32 or non-N32 ABI.
*/
#ifdef _WRS_MIPS_N32_ABI
# define _NABI(...) __VA_ARGS__
# define _OABI(...)
#else
# define _NABI(...)
# define _OABI(...) __VA_ARGS__
#endif
/*
* Offset to locate the correct word when loading
* a 32-bit parameter value from a stack frame
*/
#if (_WRS_INT_REGISTER_SIZE == 8) && (_BYTE_ORDER == _BIG_ENDIAN)
#define PARAM32_OFFSET 4
#else /* (_WRS_INT_REGISTER_SIZE == 8) && (_BYTE_ORDER == _BIG_ENDIAN) */
#define PARAM32_OFFSET 0
#endif /* (_WRS_INT_REGISTER_SIZE == 8) && (_BYTE_ORDER == _BIG_ENDIAN) */
/*
* SDA support for assembly loads and stores using the gp register
* to index into the sdata or sbss area
*/
#if defined(__GNUC__)
#define _WRS_MIPS_SDA_OFFSET(symbol) %gp_rel(symbol)(gp)
#else /* diab */
#define _WRS_MIPS_SDA_OFFSET(symbol) %sdaoff(symbol)(gp)
#endif /* defined(__GNUC__) */
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* __INCasmMipsh */