1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Create trampolines to invoke arbitrary functions.
5 * Copyright (C) Ximian Inc.
7 * Authors: Laramie Leavitt (lar@leavitt.us)
12 /* A typical Alpha stack frame looks like this */
14 fun: // called from outside the module.
15 ldgp gp,0(pv) // load the global pointer
16 fun..ng: // called from inside the module.
17 lda sp, -SIZE( sp ) // grow the stack downwards.
19 stq ra, 0(sp) // save the return address.
21 stq s0, 8(sp) // callee-saved registers.
24 // Move the arguments to the argument registers...
26 mov addr, pv // Load the callee address
27 jsr ra, (pv) // call the method.
28 ldgp gp, 0(ra) // restore gp
30 // return value is in v0
32 ldq ra, 0(sp) // free stack frame
33 ldq s0, 8(sp) // restore callee-saved registers.
35 ldq sp, 32(sp) // restore stack pointer
37 ret zero, (ra), 1 // return.
39 // assuming that the procedure is in a0.
40 #define emit_prologue( p ) \
41 alpha_ldah( p, alpha_gp, alpha_pv, 0 ); \
42 alpha_lda( p, alpha_sp, alpha_sp, -32 ); \
43 alpha_lda( p, alpha_gp, alpha_gp, 0 ); \
44 alpha_stq( p, alpha_ra, alpha_sp, 0 ); \
45 alpha_stq( p, alpha_fp, alpha_sp, 8 ); \
46 alpha_mov( p, alpha_sp, alpha_fp )
48 #define emit_move_a0_to_pv( p ) \
49 alpha_mov( p, alpha_a0, alpha_pv )
51 #define emit_call( p ) \
52 alpha_jsr( p, alpha_ra, alpha_pv, 0 ); \
53 alpha_ldah( p, alpha_gp, alpha_ra, 0 ); \
54 alpha_lda( p, alpha_gp, alpha_gp, 0 ); \
56 #define emit_epilogue( p ) \
57 alpha_mov( p, alpha_fp, alpha_sp ); \
58 alpha_ldq( p, alpha_ra, alpha_sp, 0 ); \
59 alpha_ldq( p, alpha_fp, alpha_sp, 8 ); \
60 alpha_lda( p, alpha_sp, alpha_sp, 32 ); \
61 alpha_ret( p, alpha_ra )
64 /*****************************************************/
70 #include "alpha-codegen.h"
72 #include "mono/metadata/class.h"
73 #include "mono/metadata/tabledefs.h"
74 #include "mono/interpreter/interp.h"
75 #include "mono/metadata/appdomain.h"
76 #include "mono/metadata/debug-helpers.h"
78 #define AXP_GENERAL_REGS 6
79 #define AXP_MIN_STACK_SIZE 32
85 /*****************************************************/
96 sig_to_name (MonoMethodSignature *sig, const char *prefix)
98 /* from sparc.c. this should be global */
102 GString *res = g_string_new ("");
105 g_string_append (res, prefix);
106 g_string_append_c (res, '_');
109 mono_type_get_desc (res, sig->ret, TRUE);
111 for (i = 0; i < sig->param_count; ++i) {
112 g_string_append_c (res, '_');
113 mono_type_get_desc (res, sig->params [i], TRUE);
116 g_string_free (res, FALSE);
122 add_general ( size_data *sz, gboolean simple)
124 // we don't really know yet, so just put something in here.
125 if ( sz->i_regs >= AXP_GENERAL_REGS)
130 // ...and it probably doesn't matter if our code size is a
138 calculate_sizes (MonoMethodSignature *sig,
140 gboolean string_ctor)
143 guint32 simpletype, align;
147 sz->stack_size = AXP_MIN_STACK_SIZE;
148 sz->code_size = 4 * (PROLOG_INS + CALL_INS + EPILOG_INS);
151 add_general (&gr, sz, TRUE);
154 for (i = 0; i < sig->param_count; ++i) {
155 switch (sig->ret->type) {
158 case MONO_TYPE_BOOLEAN:
168 case MONO_TYPE_CLASS:
169 case MONO_TYPE_OBJECT:
172 case MONO_TYPE_SZARRAY:
173 case MONO_TYPE_ARRAY:
174 case MONO_TYPE_STRING:
176 add_general (&gr, sz, TRUE);
178 case MONO_TYPE_VALUETYPE:
180 g_error ("Can't handle as return value 0x%x", sig->ret->type);
184 /* align stack size to 8 */
185 sz->stack_size = (sz->stack_size + 8) & ~8;
186 sz->local_size = (sz->local_size + 8) & ~8;
190 /* void func (void (*callme)(), void *retval, */
191 /* void *this_obj, stackval *arguments); */
192 static inline guint8 *
193 emit_prolog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
197 stack_size = sz->stack_size;
199 /* function prolog */
200 alpha_ldah( p, alpha_gp, alpha_pv, 0 );
201 alpha_lda( p, alpha_sp, alpha_sp, -stack_size );
202 alpha_lda( p, alpha_gp, alpha_gp, 0 );
205 alpha_stq( p, alpha_ra, alpha_sp, 0 );
206 alpha_stq( p, alpha_fp, alpha_sp, 8 );
208 /* store the return parameter */
209 alpha_stq( p, alpha_a0, alpha_sp, 16 );
210 alpha_stq( p, alpha_a1, alpha_sp, 24 );
212 /* load fp into sp */
213 alpha_mov( p, alpha_sp, alpha_fp )
218 static inline guint8 *
219 emit_epilog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
221 alpha_mov( p, alpha_fp, alpha_sp );
223 /* restore fp, ra, sp */
224 alpha_ldq( p, alpha_ra, alpha_sp, 0 );
225 alpha_ldq( p, alpha_fp, alpha_sp, 8 );
226 alpha_lda( p, alpha_sp, alpha_sp, 32 );
229 alpha_ret( p, alpha_ra );
232 static inline guint8 *
233 emit_call( guint8 *p, MonoMethodSignature *sig, size_data *sz )
235 /* move a0 into pv, ready to call */
236 alpha_mov( p, alpha_a0, alpha_pv );
239 alpha_jsr( p, alpha_ra, alpha_pv, 0 );
242 alpha_ldah( p, alpha_gp, alpha_ra, 0 );
243 alpha_lda( p, alpha_gp, alpha_gp, 0 );
248 mono_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor)
250 g_error ("Unsupported arch");
255 mono_create_method_pointer (MonoMethod *method)
257 g_error ("Unsupported arch");