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
|