1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
# 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
|