~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to erts/emulator/hipe/hipe_sparc_glue.h

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* $Id$
2
2
 * hipe_sparc_glue.h
3
3
 */
4
 
 
5
 
#include "hipe_bif0.h"  /* for stack descriptor stuff */
6
 
 
7
 
 
8
 
extern unsigned sparc_call_to_native(Process*);
9
 
extern unsigned sparc_large_call_to_native(Process*);
10
 
extern unsigned sparc_return_to_native(Process*);
11
 
extern unsigned sparc_tailcall_to_native(Process*);
12
 
extern unsigned sparc_throw_to_native(Process*);
13
 
extern void nbif_fail(void);
 
4
#ifndef HIPE_SPARC_GLUE_H
 
5
#define HIPE_SPARC_GLUE_H
 
6
 
 
7
#include "hipe_sparc_asm.h"     /* for NR_ARG_REGS and LEAF_WORDS */
 
8
 
 
9
/* tell hipe_mode_switch.c how many argument registers we use */
 
10
#define NR_ARG_REGS     SPARC_NR_ARG_REGS
 
11
 
 
12
/* Emulated code recursively calls native code.
 
13
   The return address is `nbif_return', which is exported so that
 
14
   tailcalls from native to emulated code can be identified. */
 
15
extern unsigned int sparc_call_to_native(Process*);
14
16
extern void nbif_return(void);
 
17
 
 
18
/* Native-mode stubs for calling emulated-mode closures. */
15
19
extern void nbif_ccallemu0(void);
16
20
extern void nbif_ccallemu1(void);
17
21
extern void nbif_ccallemu2(void);
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);
33
 
 
 
26
 
 
27
/* Default exception handler for native code. */
 
28
extern void nbif_fail(void);
 
29
 
 
30
/* Emulated code returns to its native code caller. */
 
31
extern unsigned int sparc_return_to_native(Process*);
 
32
 
 
33
/* Emulated code tailcalls native code. */
 
34
extern unsigned int sparc_tailcall_to_native(Process*);
 
35
 
 
36
/* Emulated code throws an exception to its native code caller. */
 
37
extern unsigned int sparc_throw_to_native(Process*);
34
38
 
35
39
static __inline__ void hipe_arch_glue_init(void)
36
40
{
37
41
    static struct sdesc_with_exnra nbif_return_sdesc = {
38
 
        .exnra = (unsigned long)nbif_fail,
 
42
        .exnra = (unsigned long)&nbif_fail,
39
43
        .sdesc = {
40
 
            .bucket = { .hvalue = (unsigned long)nbif_return },
 
44
            .bucket = { .hvalue = (unsigned long)&nbif_return },
41
45
            .summary = (1<<9) | (1<<8),
42
46
        },
43
47
    };
44
 
 
45
48
    hipe_init_sdesc_table(&nbif_return_sdesc.sdesc);
46
49
}
47
50
 
48
 
static __inline__ void hipe_push_sparc_trap_frame(Process *p)
 
51
static __inline__ void hipe_push_sparc_nra_frame(Process *p)
49
52
{
50
53
    p->hipe.nsp[0] = (Eterm)p->hipe.nra;
51
54
    p->hipe.nsp += 1;
52
55
}
53
56
 
54
 
static __inline__ void hipe_pop_sparc_trap_frame(Process *p)
 
57
static __inline__ void hipe_pop_sparc_nra_frame(Process *p)
55
58
{
56
59
    p->hipe.nra = (void(*)(void))p->hipe.nsp[-1];
57
60
    p->hipe.nsp -= 1;
58
61
}
59
62
 
60
 
/* BEAM called native, which has thrown an exception. Clean up. */
61
 
static __inline__ void hipe_throw_from_native(Process *p)
62
 
{
63
 
    p->hipe.nra = (void(*)(void))p->hipe.nsp[-1];
64
 
    p->hipe.nsp -= 1;    
65
 
}
66
 
 
67
 
#define HIPE_CATCH_SIZE 1
68
 
 
69
 
 
70
 
 
 
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[])
73
66
{
74
 
    unsigned i;
75
 
 
76
 
    for(i = 0; i < arity && i < HIPE_SPARC_ARGS_IN_REGS; ++i)
 
67
#if NR_ARG_REGS > 0
 
68
    int i;
 
69
    for(i = arity; --i >= 0;)
77
70
        p->def_arg_reg[i] = reg[i];
78
 
    for(; i < arity; ++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;
 
71
#endif
82
72
}
83
73
 
 
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[])
86
77
{
87
 
    unsigned i;
88
 
 
89
 
    for(i = 0; i < arity && i < HIPE_SPARC_ARGS_IN_REGS; ++i)
 
78
#if NR_ARG_REGS > 0
 
79
    int i;
 
80
    for(i = arity; --i >= 0;)
90
81
        reg[i] = p->def_arg_reg[i];
91
 
    for(; i < arity; ++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;
 
82
#endif
 
83
}
 
84
 
 
85
static __inline__ void
 
86
hipe_push_sparc_params(Process *p, unsigned int arity, Eterm reg[])
 
87
{
 
88
    unsigned int i;
 
89
 
 
90
    i = arity;
 
91
    if (i > NR_ARG_REGS) {
 
92
        Eterm *nsp = p->hipe.nsp;
 
93
        i = NR_ARG_REGS;
 
94
        do {
 
95
            *nsp++ = reg[i++];
 
96
        } while (i < arity);
 
97
        p->hipe.nsp = nsp;
 
98
        i = NR_ARG_REGS;
 
99
    }
 
100
    /* INV: i <= NR_ARG_REGS */
 
101
    hipe_write_sparc_regs(p, i, reg);
 
102
}
 
103
 
 
104
static __inline__ void
 
105
hipe_pop_sparc_params(Process *p, unsigned int arity, Eterm reg[])
 
106
{
 
107
    unsigned int i;
 
108
 
 
109
    i = arity;
 
110
    if (i > NR_ARG_REGS) {
 
111
        Eterm *nsp = p->hipe.nsp;
 
112
        do {
 
113
            reg[--i] = *--nsp;
 
114
        } while (i > NR_ARG_REGS);
 
115
        p->hipe.nsp = nsp;
 
116
        /* INV: i == NR_ARG_REGS */
 
117
    }
 
118
    /* INV: i <= NR_ARG_REGS */
 
119
    hipe_read_sparc_regs(p, i, reg);
95
120
}
96
121
 
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[])
100
125
{
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 */
106
 
    if (arity > 3)
107
 
      return sparc_large_call_to_native(p);     /* Get all arguments */  
108
 
    else
109
 
      return sparc_call_to_native(p);           /* Only read 3 argsuments */
 
126
    int nstkargs;
 
127
 
 
128
    if ((nstkargs = arity - NR_ARG_REGS) < 0)
 
129
        nstkargs = 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);
110
134
}
111
135
 
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[])
115
139
{
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 */
 
140
    int nstkargs;
 
141
 
 
142
    if ((nstkargs = arity - NR_ARG_REGS) < 0)
 
143
        nstkargs = 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);
120
147
}
121
148
 
122
149
/* BEAM called native, which has returned. Clean up. */
123
150
static __inline__ void hipe_return_from_native(Process *p)
124
151
{
125
 
    hipe_pop_sparc_trap_frame(p);
 
152
    hipe_pop_sparc_nra_frame(p);
126
153
}
127
154
 
 
155
/* BEAM called native, which has thrown an exception. Clean up. */
 
156
static __inline__ void hipe_throw_from_native(Process *p)
 
157
{
 
158
    hipe_pop_sparc_nra_frame(p);
 
159
}
128
160
 
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[])
135
167
{
136
168
    hipe_pop_sparc_params(p, p->arity, reg);
137
 
    if( p->hipe.nra != nbif_return )
 
169
    if (p->hipe.nra != &nbif_return)
138
170
        return 1;
139
 
    hipe_pop_sparc_trap_frame(p);
 
171
    hipe_pop_sparc_nra_frame(p);
140
172
    return 0;
141
173
}
142
174
 
 
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[])
 
181
{
 
182
    hipe_pop_sparc_params(p, arity, reg);
 
183
}
 
184
 
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)
145
187
{
146
188
    return sparc_return_to_native(p);
147
189
}
148
190
 
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)
151
193
{
152
194
    return sparc_throw_to_native(p);
153
195
}
156
198
   Move the arguments to a safe place. */
157
199
static __inline__ void hipe_reschedule_from_native(Process *p)
158
200
{
159
 
    if( p->arg_reg != p->def_arg_reg ) {
160
 
        unsigned i;
 
201
#if NR_ARG_REGS == 0
 
202
    ASSERT(p->arity == 0);
 
203
#else
 
204
    if (p->arg_reg != p->def_arg_reg) {
 
205
        unsigned int i;
161
206
        for(i = 0; i < p->arity; ++i)
162
207
            p->arg_reg[i] = p->def_arg_reg[i];
163
208
    }
 
209
#endif
164
210
}
165
211
 
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[])
169
215
{
 
216
#if NR_ARG_REGS == 0
 
217
    ASSERT(arity == 0);
 
218
    return sparc_tailcall_to_native(p);
 
219
#else
170
220
    p->arity = 0;
171
221
    return hipe_tailcall_to_native(p, arity, reg);
 
222
#endif
172
223
}
173
224
 
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)
176
227
{
177
 
    switch( arity ) {
 
228
    switch (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;
195
236
    }
196
237
}
 
238
 
 
239
#endif /* HIPE_SPARC_GLUE_H */