# 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