]>
Commit | Line | Data |
---|---|---|
540d4a2f JB |
1 | --- mono-1.1.17/mono/arch/alpha/tramp.c.orig 2006-08-25 21:35:19.000000000 +0200 |
2 | +++ mono-1.1.17/mono/arch/alpha/tramp.c 2006-08-30 12:00:25.805971000 +0200 | |
3 | @@ -162,16 +162,54 @@ | |
5a8943fb JB |
4 | } |
5 | ||
540d4a2f JB |
6 | static inline unsigned int * |
7 | -emit_store_return_default(unsigned int *pi, const gint SIZE ) | |
8 | +emit_store_return_default(unsigned int *pi, const gint SIZE, MonoMethodSignature *sig ) | |
5a8943fb | 9 | { |
540d4a2f JB |
10 | - // 2 instructions. |
11 | unsigned int *p = (unsigned int *)pi; | |
5a8943fb | 12 | + guint32 simpletype; |
540d4a2f | 13 | + // 2 instructions. |
5a8943fb | 14 | |
540d4a2f JB |
15 | /* TODO: This probably do different stuff based on the value. |
16 | you know, like stq/l/w. and s/f. | |
17 | */ | |
18 | alpha_ldq( p, alpha_t0, alpha_fp, (SIZE-8) ); // load void * retval | |
5a8943fb JB |
19 | - alpha_stq( p, alpha_v0, alpha_t0, 0 ); // store the result to *retval. |
20 | + /* XXX: may need more variants */ | |
21 | + if (sig->ret->byref) { | |
22 | + alpha_stq( p, alpha_v0, alpha_t0, 0 ); // store the result to *retval. | |
23 | + } else { | |
24 | + simpletype = sig->ret->type; | |
25 | + if ((simpletype == MONO_TYPE_VALUETYPE) && sig->ret->data.klass->enumtype) { | |
26 | + simpletype = sig->ret->data.klass->enum_basetype->type; | |
27 | + } | |
28 | + switch(simpletype) { | |
29 | + case MONO_TYPE_BOOLEAN: | |
30 | + case MONO_TYPE_I1: | |
31 | + case MONO_TYPE_U1: | |
32 | + case MONO_TYPE_CHAR: | |
33 | + case MONO_TYPE_I2: | |
34 | + case MONO_TYPE_U2: | |
35 | + case MONO_TYPE_VOID: | |
36 | + case MONO_TYPE_I4: | |
37 | + case MONO_TYPE_U4: | |
38 | + case MONO_TYPE_I: | |
39 | + case MONO_TYPE_U: | |
40 | + case MONO_TYPE_I8: | |
41 | + case MONO_TYPE_U8: | |
42 | + case MONO_TYPE_CLASS: | |
43 | + case MONO_TYPE_OBJECT: | |
44 | + case MONO_TYPE_SZARRAY: | |
45 | + case MONO_TYPE_ARRAY: | |
46 | + case MONO_TYPE_STRING: | |
47 | + alpha_stq( p, alpha_v0, alpha_t0, 0 ); // store the result to *retval. | |
48 | + break; | |
49 | + case MONO_TYPE_R4: | |
50 | + case MONO_TYPE_R8: | |
51 | + alpha_stt( p, alpha_fv0, alpha_t0, 0 ); // store the result to *retval. | |
52 | + break; | |
53 | + default: | |
54 | + g_error ("Can't handle as return value 0x%x", sig->ret->type); | |
55 | + } | |
56 | + | |
57 | + } | |
58 | return p; | |
59 | } | |
60 | ||
540d4a2f | 61 | @@ -332,22 +370,22 @@ |
5a8943fb JB |
62 | break; |
63 | case MONO_TYPE_R4: | |
64 | case MONO_TYPE_R8: | |
65 | - /* | |
66 | - // floating point... Maybe this does the correct thing. | |
67 | - if( i > alpharegs ) | |
68 | + // floating point; both types use double C type in mono | |
69 | + if( i >= alpharegs ) | |
70 | { | |
71 | - alpha_ldq( p, alpha_t1, alpha_t0, ARG_LOC( i ) ); | |
72 | - alpha_cpys( p, alpha_ft1, alpha_ft1, alpha_ft2 ); | |
73 | - alpha_stt( p, alpha_ft2, alpha_sp, pos ); | |
74 | + // load into temp register, then store on the stack | |
75 | + alpha_ldt( p, alpha_ft1, alpha_t0, ARG_LOC( i ) ); | |
76 | + alpha_stt( p, alpha_ft1, alpha_sp, pos ); | |
77 | pos -= 8; | |
78 | } | |
79 | else | |
80 | { | |
81 | - alpha_ldq( p, alpha_t1, alpha_t0, ARG_LOC(i) ); | |
82 | - alpha_cpys( p, alpha_ft1, alpha_ft1, alpha_fa0 + i + hasthis ); | |
83 | + // load into register | |
84 | + // (float regs are numbered in the same way as integer ones, | |
85 | + // so we can abuse regbase) | |
86 | + alpha_ldt( p, regbase + i, alpha_t0, ARG_LOC(i) ); | |
87 | } | |
88 | break; | |
89 | - */ | |
90 | case MONO_TYPE_VALUETYPE: | |
91 | g_error ("Not implemented: ValueType as parameter to delegate." ); | |
92 | break; | |
540d4a2f | 93 | @@ -360,7 +398,7 @@ |
5a8943fb JB |
94 | |
95 | // Now call the function and store the return parameter. | |
96 | p = emit_call( p, STACK_SIZE ); | |
97 | - p = emit_store_return_default( p, STACK_SIZE ); | |
98 | + p = emit_store_return_default( p, STACK_SIZE, sig ); | |
99 | p = emit_epilog( p, STACK_SIZE ); | |
100 | ||
101 | if( p > buffer + BUFFER_SIZE ) |