# Declare a function called NAME and an __fn_NAME stub for it.
# Make the stub use la_TYPE to load the target address into $2.
.macro stub,name,type
.set nomips16
.section .mips16.fn.\name, "ax", @progbits
.ent __fn_\name
__fn_\name:
la_\type \name
mfc1 $4,$f12
jr $2
nop
.end __fn_\name
.set mips16
.text
.ent \name
\name:
__fn_local_\name:
jr $31
nop
.end \name
.endm
# Like stub, but ensure NAME is a local symbol.
.macro lstub,name,type
stub \name, \type
.equ local_\name,1
.endm
# Like stub, but ensure NAME is a hidden symbol.
.macro hstub,name,type
.globl \name
.hidden \name
stub \name, \type
.endm
# Like lstub, but make the MIPS16 function global rather than local.
.macro gstub,name,type
.globl \name
stub \name, \type
.endm
# Use an absolute sequence to load NAME into a register.
.macro la_noshared,name
lui $2,%hi(\name)
addiu $2,$2,%lo(\name)
.endm
# Use the normal PIC sequence to load __fn_local_NAME into $2
# and emit a dummy relocation against NAME. This macro is always
# used at the start of a function.
.macro la_shared,name
.reloc 0,R_MIPS_NONE,\name
.cpload $25
la $2,__fn_local_\name
.endm
# Use TYPE (either LSTUB, HSTUB or GSTUB) to define functions
# called a_NAME and b_NAME. The former uses absolute accesses
# and the latter uses PIC accesses.
.macro decl,name,type
\type a_\name, noshared
\type b_\name, shared
.endm
# Emit the MIPS16 PIC sequence for setting $28 from $25.
# Make the value of $25 available in $2 as well.
.macro cpload_mips16
li $2,%hi(_gp_disp)
addiu $3,$pc,%lo(_gp_disp)
sll $2,16
addu $2,$2,$3
move $28,$2
.endm
# Likewise, but for non-MIPS16 code.
.macro cpload_nomips16
.cpload $25
move $2,$28
.endm
# Start a PIC function in ISA mode MODE, which is either "mips16"
# or "nomips16".
.macro pic_prologue,mode
cpload_\mode
addiu $sp,$sp,-32
sw $2,16($sp)
sw $31,20($sp)
.endm
# Use a PIC function to call NAME.
.macro pic_call,name,mode
.ifdef local_\name
.ifc \mode,mips16
lw $2,%got(__fn_local_\name)($2)
addiu $2,%lo(__fn_local_\name)
.else
lw $2,%got(\name)($2)
addiu $2,%lo(\name)
.endif
.else
lw $2,%call16(\name)($2)
.endif
jalr $2
move $25,$2
lw $2,16($sp)
move $28,$2
.endm
# Finish a PIC function started by pic_prologue.
.macro pic_epilogue
lw $2,20($sp)
jr $2
addiu $sp,$sp,32
.endm
# Use PIC %call16 sequences to call a_NAME and b_NAME.
# MODE selects the ISA mode of the code: either "mips16"
# or "nomips16".
.macro callpic,name,mode
.text
.set \mode
.ent callpic_\name\()_\mode
callpic_\name\()_\mode:
pic_prologue \mode
pic_call a_\name,\mode
pic_call b_\name,\mode
pic_epilogue
.end callpic_\name\()_\mode
.endm
# Use absolute jals to call a_NAME and b_NAME. MODE selects the
# ISA mode of the code: either "mips16" or "nomips16".
.macro jals,name,mode
.text
.set \mode
.ent jals_\name\()_\mode
jals_\name\()_\mode:
.option pic0
jal a_\name
nop
jal b_\name
nop
.option pic2
.end jals_\name\()_\mode
.endm