19
23
extern void nbif_ccallemu4(void);
20
24
extern void nbif_ccallemu5(void);
21
25
extern void nbif_ccallemu6(void);
22
extern void nbif_ccallemu7(void);
23
extern void nbif_ccallemu8(void);
24
extern void nbif_ccallemu9(void);
25
extern void nbif_ccallemu10(void);
26
extern void nbif_ccallemu11(void);
27
extern void nbif_ccallemu12(void);
28
extern void nbif_ccallemu13(void);
29
extern void nbif_ccallemu14(void);
30
extern void nbif_ccallemu15(void);
31
extern void nbif_ccallemu16(void);
32
extern void hipe_stack_marker_ra(void);
27
/* Default exception handler for native code. */
28
extern void nbif_fail(void);
30
/* Emulated code returns to its native code caller. */
31
extern unsigned int sparc_return_to_native(Process*);
33
/* Emulated code tailcalls native code. */
34
extern unsigned int sparc_tailcall_to_native(Process*);
36
/* Emulated code throws an exception to its native code caller. */
37
extern unsigned int sparc_throw_to_native(Process*);
35
39
static __inline__ void hipe_arch_glue_init(void)
37
41
static struct sdesc_with_exnra nbif_return_sdesc = {
38
.exnra = (unsigned long)nbif_fail,
42
.exnra = (unsigned long)&nbif_fail,
40
.bucket = { .hvalue = (unsigned long)nbif_return },
44
.bucket = { .hvalue = (unsigned long)&nbif_return },
41
45
.summary = (1<<9) | (1<<8),
45
48
hipe_init_sdesc_table(&nbif_return_sdesc.sdesc);
48
static __inline__ void hipe_push_sparc_trap_frame(Process *p)
51
static __inline__ void hipe_push_sparc_nra_frame(Process *p)
50
53
p->hipe.nsp[0] = (Eterm)p->hipe.nra;
54
static __inline__ void hipe_pop_sparc_trap_frame(Process *p)
57
static __inline__ void hipe_pop_sparc_nra_frame(Process *p)
56
59
p->hipe.nra = (void(*)(void))p->hipe.nsp[-1];
60
/* BEAM called native, which has thrown an exception. Clean up. */
61
static __inline__ void hipe_throw_from_native(Process *p)
63
p->hipe.nra = (void(*)(void))p->hipe.nsp[-1];
67
#define HIPE_CATCH_SIZE 1
63
/* PRE: arity <= NR_ARG_REGS */
71
64
static __inline__ void
72
hipe_push_sparc_params(Process *p, unsigned arity, Eterm reg[])
65
hipe_write_sparc_regs(Process *p, unsigned int arity, Eterm reg[])
76
for(i = 0; i < arity && i < HIPE_SPARC_ARGS_IN_REGS; ++i)
69
for(i = arity; --i >= 0;)
77
70
p->def_arg_reg[i] = reg[i];
79
p->hipe.nsp[i - HIPE_SPARC_ARGS_IN_REGS] = reg[i];
80
if( arity > HIPE_SPARC_ARGS_IN_REGS )
81
p->hipe.nsp += arity - HIPE_SPARC_ARGS_IN_REGS;
74
/* PRE: arity <= NR_ARG_REGS */
84
75
static __inline__ void
85
hipe_pop_sparc_params(Process *p, unsigned arity, Eterm reg[])
76
hipe_read_sparc_regs(Process *p, unsigned int arity, Eterm reg[])
89
for(i = 0; i < arity && i < HIPE_SPARC_ARGS_IN_REGS; ++i)
80
for(i = arity; --i >= 0;)
90
81
reg[i] = p->def_arg_reg[i];
92
reg[i] = p->hipe.nsp[-(arity - i)];
93
if( arity > HIPE_SPARC_ARGS_IN_REGS )
94
p->hipe.nsp -= arity - HIPE_SPARC_ARGS_IN_REGS;
85
static __inline__ void
86
hipe_push_sparc_params(Process *p, unsigned int arity, Eterm reg[])
91
if (i > NR_ARG_REGS) {
92
Eterm *nsp = p->hipe.nsp;
100
/* INV: i <= NR_ARG_REGS */
101
hipe_write_sparc_regs(p, i, reg);
104
static __inline__ void
105
hipe_pop_sparc_params(Process *p, unsigned int arity, Eterm reg[])
110
if (i > NR_ARG_REGS) {
111
Eterm *nsp = p->hipe.nsp;
114
} while (i > NR_ARG_REGS);
116
/* INV: i == NR_ARG_REGS */
118
/* INV: i <= NR_ARG_REGS */
119
hipe_read_sparc_regs(p, i, reg);
97
122
/* BEAM recursively calls native code. */
98
static __inline__ unsigned
99
hipe_call_to_native(Process *p, unsigned arity, Eterm reg[])
123
static __inline__ unsigned int
124
hipe_call_to_native(Process *p, unsigned int arity, Eterm reg[])
101
unsigned nstkargs = arity <= HIPE_SPARC_ARGS_IN_REGS ? 0 : arity-HIPE_SPARC_ARGS_IN_REGS;
102
hipe_check_nstack(p, HIPE_CATCH_SIZE + nstkargs + HIPE_SPARC_LEAF_WORDS);
103
hipe_push_sparc_trap_frame(p); /* pushes HIPE_CATCH_SIZE words */
104
hipe_push_sparc_params(p, arity, reg); /* pushes nstkargs words */
105
/* guaranteed LEAF words */
107
return sparc_large_call_to_native(p); /* Get all arguments */
109
return sparc_call_to_native(p); /* Only read 3 argsuments */
128
if ((nstkargs = arity - NR_ARG_REGS) < 0)
130
hipe_check_nstack(p, nstkargs + 1 + SPARC_LEAF_WORDS);
131
hipe_push_sparc_nra_frame(p); /* needs 1 word */
132
hipe_push_sparc_params(p, arity, reg); /* needs nstkargs words */
133
return sparc_call_to_native(p);
112
136
/* Native called BEAM, which now tailcalls native. */
113
static __inline__ unsigned
114
hipe_tailcall_to_native(Process *p, unsigned arity, Eterm reg[])
137
static __inline__ unsigned int
138
hipe_tailcall_to_native(Process *p, unsigned int arity, Eterm reg[])
116
unsigned nstkargs = arity <= HIPE_SPARC_ARGS_IN_REGS ? 0 : arity-HIPE_SPARC_ARGS_IN_REGS;
117
hipe_check_nstack(p, nstkargs + HIPE_SPARC_LEAF_WORDS);
118
hipe_push_sparc_params(p, arity, reg); /* pushes nstkargs words */
119
return sparc_tailcall_to_native(p); /* guaranteed LEAF words */
142
if ((nstkargs = arity - NR_ARG_REGS) < 0)
144
hipe_check_nstack(p, nstkargs + SPARC_LEAF_WORDS);
145
hipe_push_sparc_params(p, arity, reg); /* needs nstkargs words */
146
return sparc_tailcall_to_native(p);
122
149
/* BEAM called native, which has returned. Clean up. */
123
150
static __inline__ void hipe_return_from_native(Process *p)
125
hipe_pop_sparc_trap_frame(p);
152
hipe_pop_sparc_nra_frame(p);
155
/* BEAM called native, which has thrown an exception. Clean up. */
156
static __inline__ void hipe_throw_from_native(Process *p)
158
hipe_pop_sparc_nra_frame(p);
129
161
/* BEAM called native, which now calls BEAM.
130
162
Move the parameters to reg[].
134
166
hipe_call_from_native_is_recursive(Process *p, Eterm reg[])
136
168
hipe_pop_sparc_params(p, p->arity, reg);
137
if( p->hipe.nra != nbif_return )
169
if (p->hipe.nra != &nbif_return)
139
hipe_pop_sparc_trap_frame(p);
171
hipe_pop_sparc_nra_frame(p);
175
/* Native makes a call which needs to unload the parameters.
176
This differs from hipe_call_from_native_is_recursive() in
177
that it doesn't check for or pop the native-to-BEAM trap frame.
178
It's currently only used in the implementation of apply. */
179
static __inline__ void
180
hipe_pop_params(Process *p, unsigned int arity, Eterm reg[])
182
hipe_pop_sparc_params(p, arity, reg);
143
185
/* Native called BEAM, which now returns back to native. */
144
static __inline__ unsigned hipe_return_to_native(Process *p)
186
static __inline__ unsigned int hipe_return_to_native(Process *p)
146
188
return sparc_return_to_native(p);
149
191
/* Native called BEAM, which now throws an exception back to native. */
150
static __inline__ unsigned hipe_throw_to_native(Process *p)
192
static __inline__ unsigned int hipe_throw_to_native(Process *p)
152
194
return sparc_throw_to_native(p);
156
198
Move the arguments to a safe place. */
157
199
static __inline__ void hipe_reschedule_from_native(Process *p)
159
if( p->arg_reg != p->def_arg_reg ) {
202
ASSERT(p->arity == 0);
204
if (p->arg_reg != p->def_arg_reg) {
161
206
for(i = 0; i < p->arity; ++i)
162
207
p->arg_reg[i] = p->def_arg_reg[i];
166
212
/* Resume a BIF call which had failed with RESCHEDULE. */
167
213
static __inline__ unsigned
168
214
hipe_reschedule_to_native(Process *p, unsigned arity, Eterm reg[])
218
return sparc_tailcall_to_native(p);
171
221
return hipe_tailcall_to_native(p, arity, reg);
174
225
/* Return the address of a stub switching a native closure call to BEAM. */
175
static __inline__ void *hipe_closure_stub_address(unsigned arity)
226
static __inline__ void *hipe_closure_stub_address(unsigned int arity)
178
229
case 0: return nbif_ccallemu0;
179
230
case 1: return nbif_ccallemu1;
180
231
case 2: return nbif_ccallemu2;
181
232
case 3: return nbif_ccallemu3;
182
233
case 4: return nbif_ccallemu4;
183
234
case 5: return nbif_ccallemu5;
184
case 6: return nbif_ccallemu6;
185
case 7: return nbif_ccallemu7;
186
case 8: return nbif_ccallemu8;
187
case 9: return nbif_ccallemu9;
188
case 10: return nbif_ccallemu10;
189
case 11: return nbif_ccallemu11;
190
case 12: return nbif_ccallemu12;
191
case 13: return nbif_ccallemu13;
192
case 14: return nbif_ccallemu14;
193
case 15: return nbif_ccallemu15;
194
default: return nbif_ccallemu16;
235
default: return nbif_ccallemu6;
239
#endif /* HIPE_SPARC_GLUE_H */