2 Copyright (c) 2003 Bernie Solomon <bernard@ugsolutions.com>
4 Permission is hereby granted, free of charge, to any person obtaining
5 a copy of this software and associated documentation files (the
6 "Software"), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions:
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Trampoline generation for HPPA - currently (Oct 9th 2003) only
25 supports 64 bits - and the HP compiler.
29 #include "mono/interpreter/interp.h"
30 #include "mono/metadata/appdomain.h"
31 #include "mono/metadata/tabledefs.h"
32 #include "hppa-codegen.h"
34 #if SIZEOF_VOID_P != 8
35 #error "HPPA code only currently supports 64bit pointers"
38 // debugging flag which dumps code generated
39 static int debug_asm = 0;
42 static void flush_cache(void *address, int length)
45 #error "currently only supports the HP C compiler"
47 int cache_line_size = 16;
48 ulong_t end = (ulong_t)address + length;
50 register ulong_t offset = (ulong_t) address;
51 register ulong_t r0 = 0;
53 _asm("LDSID", 0, offset, sid);
55 _asm("FDC", r0, 0, offset);
56 offset = (offset + (cache_line_size - 1)) & ~(cache_line_size - 1);
57 while (offset < end) {
58 (void)_asm("FDC", r0, 0, offset);
59 offset += cache_line_size;
62 offset = (ulong_t) address;
63 _asm("FIC", r0, 0, offset);
64 offset = (offset + (cache_line_size - 1)) & ~(cache_line_size - 1);
65 while (offset < end) {
66 (void)_asm("FIC", r0, 0, offset);
67 offset += cache_line_size;
70 // sync needs at least 7 instructions after it... this is what is used for NOP
81 static void disassemble (guint32 *code, int n_instrs)
83 const char *tmp_file = "/tmp/mono_adb.in";
84 FILE *fp = fopen(tmp_file, "w");
86 for (i = 0; i < n_instrs; i++)
87 fprintf(fp, "0x%08x=i\n", code[i]);
90 system("adb64 </tmp/mono_adb.in");
94 #define ADD_INST(code, pc, gen_exp) \
95 do { if ((code) == NULL) (pc)++; else { gen_exp; pc++; } } while (0)
98 * void func (void (*callme)(), void *retval, void *this_obj, stackval *arguments);
102 mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor)
107 unsigned int *code = NULL;
108 unsigned int *code_start = NULL;
110 #define FP_ARG_REG(r) (4 + (26 - arg_reg))
114 int parameter_offset;
119 fprintf(stderr, "trampoline: # params %d has this %d exp this %d string %d, ret type %d\n",
120 sig->param_count, sig->hasthis, sig->explicit_this, string_ctor, sig->ret->type);
123 // everything takes 8 bytes unless it is a bigger struct
124 for (param = 0; param < sig->param_count; param++) {
125 if (sig->params[param]->byref)
128 if (sig->params[param]->type != MONO_TYPE_VALUETYPE)
131 if (sig->params [param]->data.klass->enumtype)
134 frame_size += 15; // large structs are 16 byte aligned
136 frame_size += mono_class_native_size (sig->params [param]->data.klass, NULL);
147 if ((frame_size & 15) != 0)
149 // minimum is 64 bytes
154 fprintf(stderr, "outgoing frame size: %d\n", frame_size);
156 frame_size += 16; // for the frame marker (called routines stuff return address etc. here)
157 frame_size += 32; // spill area for r4, r5 and r27 (16 byte aligned)
159 spill_offset = -frame_size;
160 parameter_offset = spill_offset + 32; // spill area size is really 24
163 /* the rest executes twice - once to count instructions so we can
164 allocate memory in one block and once to fill it in... the count
165 should be pretty fast anyway...
172 parameter_slot = parameter_offset;
174 ADD_INST(code, pc, hppa_std(code, 2, -16, 30)); // STD %r2,-16(%r30)
175 ADD_INST(code, pc, hppa_std_ma(code, 3, frame_size, 30));
176 ADD_INST(code, pc, hppa_std(code, 4, spill_offset, 30));
177 ADD_INST(code, pc, hppa_std(code, 5, spill_offset + 8, 30));
178 ADD_INST(code, pc, hppa_copy(code, 29, 3)); // COPY %r29,%r3
179 ADD_INST(code, pc, hppa_std(code, 27, spill_offset + 16, 30));
180 ADD_INST(code, pc, hppa_nop(code)); // NOP
182 ADD_INST(code, pc, hppa_std(code, 26, -64, 29)); // STD %r26,-64(%r29) callme
183 ADD_INST(code, pc, hppa_std(code, 25, -56, 29)); // STD %r25,-56(%r29) retval
184 ADD_INST(code, pc, hppa_std(code, 24, -48, 29)); // STD %r24,-48(%r29) this_obj
185 ADD_INST(code, pc, hppa_std(code, 23, -40, 29)); // STD %r23,-40(%r29) arguments
187 if (sig->param_count > 0)
188 ADD_INST(code, pc, hppa_copy(code, 23, 4)); // r4 is the current pointer to the stackval array of args
191 if (sig->call_convention != MONO_CALL_THISCALL) {
192 ADD_INST(code, pc, hppa_copy(code, 24, arg_reg));
196 fprintf(stderr, "case I didn't handle\n");
200 for (param = 0; param < sig->param_count; param++) {
201 int type = sig->params[param]->type;
202 if (sig->params[param]->byref) {
204 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, 5));
205 ADD_INST(code, pc, hppa_std(code, 5, parameter_slot, 30));
207 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, arg_reg));
210 arg_offset += sizeof(stackval);
217 case MONO_TYPE_BOOLEAN:
225 ADD_INST(code, pc, hppa_ldw(code, arg_offset, 4, 5));
229 ADD_INST(code, pc, hppa_stw(code, 5, parameter_slot + 4, 30));
234 ADD_INST(code, pc, hppa_sth(code, 5, parameter_slot + 6, 30));
236 case MONO_TYPE_BOOLEAN:
239 ADD_INST(code, pc, hppa_stb(code, 5, parameter_slot + 7, 30));
243 ADD_INST(code, pc, hppa_ldw(code, arg_offset, 4, arg_reg));
246 arg_offset += sizeof(stackval);
253 case MONO_TYPE_STRING:
254 case MONO_TYPE_OBJECT:
255 case MONO_TYPE_CLASS:
256 case MONO_TYPE_SZARRAY:
259 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, 5));
260 ADD_INST(code, pc, hppa_std(code, 5, parameter_slot, 30));
262 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, arg_reg));
265 arg_offset += sizeof(stackval);
270 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, 5));
271 ADD_INST(code, pc, hppa_std(code, 5, parameter_slot, 30));
273 ADD_INST(code, pc, hppa_fldd(code, arg_offset, 4, FP_ARG_REG(arg_reg)));
276 arg_offset += sizeof(stackval);
281 ADD_INST(code, pc, hppa_fldd(code, arg_offset, 4, 22));
282 ADD_INST(code, pc, hppa_fcnv_dbl_sng(code, 22, 22));
283 ADD_INST(code, pc, hppa_fstw(code, 22, parameter_slot + 4, 30));
285 ADD_INST(code, pc, hppa_fldd(code, arg_offset, 4, FP_ARG_REG(arg_reg)));
286 ADD_INST(code, pc, hppa_fcnv_dbl_sng(code, FP_ARG_REG(arg_reg), FP_ARG_REG(arg_reg)));
289 arg_offset += sizeof(stackval);
292 case MONO_TYPE_VALUETYPE:
293 if (sig->params [param]->data.klass->enumtype) {
294 type = sig->params [param]->data.klass->enum_basetype->type;
297 int size = mono_class_native_size (sig->params [param]->data.klass, NULL);
298 // assumes struct is 8 byte aligned whatever its size... (as interp.c guarantees at present)
299 // copies multiple of 8 bytes which may include some trailing garbage but should be safe
302 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, 5));
303 ADD_INST(code, pc, hppa_ldd(code, 0, 5, 5));
304 ADD_INST(code, pc, hppa_std(code, 5, parameter_slot, 30));
306 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, arg_reg));
307 ADD_INST(code, pc, hppa_ldd(code, 0, arg_reg, arg_reg));
313 if ((parameter_slot & 15) != 0) {
320 ADD_INST(code, pc, hppa_ldd(code, arg_offset, 4, 5));
321 // might generate a lot of code for very large structs... should
322 // use a loop or routine call them
325 ADD_INST(code, pc, hppa_ldd(code, soffset, 5, 31));
326 ADD_INST(code, pc, hppa_std(code, 31, parameter_slot, 30));
328 ADD_INST(code, pc, hppa_ldd(code, soffset, 5, arg_reg));
338 arg_offset += sizeof(stackval);
343 g_error ("mono_create_trampoline: unhandled arg type %d", type);
352 // for large return structs just pass on the buffer given to us.
353 if (sig->ret->type == MONO_TYPE_VALUETYPE && sig->ret->data.klass->enumtype == 0) {
354 int size = mono_class_native_size (sig->ret->data.klass, NULL);
356 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 28));
357 ADD_INST(code, pc, hppa_ldd(code, 0, 28, 28));
361 ADD_INST(code, pc, hppa_nop(code)); // NOP
362 ADD_INST(code, pc, hppa_ldd(code, -64, 29, 5));
363 ADD_INST(code, pc, hppa_ldd(code, 24, 5, 27));
364 ADD_INST(code, pc, hppa_ldd(code, 16, 5, 5));
365 ADD_INST(code, pc, hppa_blve(code, 5));
366 ADD_INST(code, pc, hppa_ldo(code, parameter_offset + 64, 30, 29));
367 ADD_INST(code, pc, hppa_ldd(code, spill_offset + 16, 30, 27));
368 ADD_INST(code, pc, hppa_nop(code)); // NOP
371 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19)); // LDD -56(%r3),%r19
372 ADD_INST(code, pc, hppa_std(code, 28, 0, 19)); // STD %r28,0(%r19)
374 else if (sig->ret->type != MONO_TYPE_VOID) {
375 int type = sig->ret->type;
379 case MONO_TYPE_BOOLEAN:
382 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19)); // LDD -56(%r3),%r19
383 ADD_INST(code, pc, hppa_stb(code, 28, 0, 19)); // STB %r28,0(%r19)
387 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19)); // LDD -56(%r3),%r19
388 ADD_INST(code, pc, hppa_stw(code, 28, 0, 19)); // STW %r28,0(%r19)
393 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19)); // LDD -56(%r3),%r19
394 ADD_INST(code, pc, hppa_sth(code, 28, 0, 19)); // STH %r28,0(%r19)
400 case MONO_TYPE_STRING:
401 case MONO_TYPE_OBJECT:
402 case MONO_TYPE_CLASS:
403 case MONO_TYPE_SZARRAY:
405 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19)); // LDD -56(%r3),%r19
406 ADD_INST(code, pc, hppa_std(code, 28, 0, 19)); // STD %r28,0(%r19)
409 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19)); // LDD -56(%r3),%r19
410 ADD_INST(code, pc, hppa_fstd(code, 4, 0, 19)); // FSTD %fr4,0(%r19)
413 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19)); // LDD -56(%r3),%r19
414 ADD_INST(code, pc, hppa_fstw(code, 4, 0, 19)); // FSTW %fr4r,0(%r19)
416 case MONO_TYPE_VALUETYPE:
417 if (sig->ret->data.klass->enumtype) {
418 type = sig->ret->data.klass->enum_basetype->type;
421 int size = mono_class_native_size (sig->ret->data.klass, NULL);
425 ADD_INST(code, pc, hppa_ldd(code, -56, 3, 19));
426 ADD_INST(code, pc, hppa_ldd(code, 0, 19, 19));
428 ADD_INST(code, pc, hppa_std(code, 28, 0, 19));
433 // get rest of value right aligned in the register
434 ADD_INST(code, pc, hppa_extrdu(code, reg, 8 * size - 1, 8 * size, reg));
435 if ((size & 1) != 0) {
436 ADD_INST(code, pc, hppa_stb(code, reg, off + size - 1, 19));
437 ADD_INST(code, pc, hppa_extrdu(code, reg, 55, 56, reg));
440 if ((size & 2) != 0) {
441 ADD_INST(code, pc, hppa_sth(code, reg, off + size - 2, 19));
442 ADD_INST(code, pc, hppa_extrdu(code, reg, 47, 48, reg));
446 ADD_INST(code, pc, hppa_stw(code, reg, off + size - 4, 19));
451 g_error ("mono_create_trampoline: unhandled ret type %d", type);
456 ADD_INST(code, pc, hppa_ldd(code, -frame_size-16, 30, 2));
457 ADD_INST(code, pc, hppa_ldd(code, spill_offset, 30, 4));
458 ADD_INST(code, pc, hppa_ldd(code, spill_offset + 8, 30, 5));
459 ADD_INST(code, pc, hppa_bve(code, 2, 0));
460 ADD_INST(code, pc, hppa_ldd_mb(code, -frame_size, 30, 3));
463 descriptor = (void **)g_malloc(4 * sizeof(void *) + pc * sizeof(unsigned int));
464 code = (unsigned int *)((char *)descriptor + 4 * sizeof(void *));
469 g_assert(pc == save_pc);
472 fprintf(stderr, "generated: %d bytes\n", pc * 4);
473 disassemble(code_start, pc);
476 // must do this so we can actually execute the code we just put in memory
477 flush_cache(code_start, 4 * pc);
481 descriptor[2] = code_start;
484 return (MonoPIFunc)descriptor;
488 mono_arch_create_method_pointer (MonoMethod *method)
490 MonoMethodSignature *sig = method->signature;
495 void **descriptor = NULL;
497 unsigned int *code = NULL;
498 unsigned int *code_start = NULL;
502 int invoke_rec_offset;
503 int stack_vals_offset;
511 fprintf(stderr, "mono_create_method_pointer %s: flags %d\n", method->name, method->flags);
512 fprintf(stderr, "method: # params %d has this %d exp this %d\n", sig->param_count, sig->hasthis, sig->explicit_this);
513 fprintf(stderr, "ret %d\n", sig->ret->type);
514 for (i = 0; i < sig->param_count; i++)
515 fprintf(stderr, "%d: %d\n", i, sig->params[i]->type);
518 // the extra stackval is for the return val if necessary
519 // the 64 is for outgoing parameters and the 16 is the frame marker.
520 // the other 16 is space for struct return vals < 16 bytes
521 frame_size = sizeof(MonoInvocation) + (sig->param_count + 1) * sizeof(stackval) + 16 + 64 + 16;
524 invoke_rec_offset = -frame_size;
525 vtoffsets = (int *)alloca(sig->param_count * sizeof(int));
527 t = invoke_rec_offset;
529 for (i = 0; i < sig->param_count; ++i)
530 if (sig->params[i]->type == MONO_TYPE_VALUETYPE &&
531 !sig->params[i]->data.klass->enumtype && !sig->params[i]->byref) {
532 int size = mono_class_native_size (sig->params[i]->data.klass, NULL);
540 stack_vals_offset = invoke_rec_offset + sizeof(MonoInvocation);
541 stack_vals_offset += 7;
542 stack_vals_offset &= ~7;
546 spill_offset = -frame_size + 8;
549 stack_val_pos = stack_vals_offset;
553 ADD_INST(code, pc, hppa_std(code, 2, -16, 30));
554 ADD_INST(code, pc, hppa_std_ma(code, 3, frame_size, 30));
555 ADD_INST(code, pc, hppa_std(code, 4, spill_offset, 30));
556 ADD_INST(code, pc, hppa_copy(code, 29, 3));
557 ADD_INST(code, pc, hppa_std(code, 27, spill_offset + 8, 30));
558 ADD_INST(code, pc, hppa_std(code, 28, spill_offset + 16, 30));
559 ADD_INST(code, pc, hppa_nop(code));
561 ADD_INST(code, pc, hppa_std(code, 26, -64, 29)); // STD %r26,-64(%r29)
562 ADD_INST(code, pc, hppa_std(code, 25, -56, 29)); // STD %r25,-56(%r29)
563 ADD_INST(code, pc, hppa_std(code, 24, -48, 29)); // STD %r24,-48(%r29)
564 ADD_INST(code, pc, hppa_std(code, 23, -40, 29)); // STD %r23,-40(%r29)
565 ADD_INST(code, pc, hppa_std(code, 22, -32, 29)); // STD %r22,-32(%r29)
566 ADD_INST(code, pc, hppa_std(code, 21, -24, 29)); // STD %r21,-24(%r29)
567 ADD_INST(code, pc, hppa_std(code, 20, -16, 29)); // STD %r20,-16(%r29)
568 ADD_INST(code, pc, hppa_std(code, 19, -8, 29)); // STD %r19,-8(%r29)
570 ADD_INST(code, pc, hppa_std(code, 0, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, parent), 30));
571 ADD_INST(code, pc, hppa_std(code, 0, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, ex), 30));
572 ADD_INST(code, pc, hppa_std(code, 0, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, ex_handler), 30));
573 ADD_INST(code, pc, hppa_std(code, 0, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, ip), 30));
577 ADD_INST(code, pc, hppa_ldd(code, 0, 27, 19));
578 ADD_INST(code, pc, hppa_std(code, 19, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, method), 30));
581 if (sig->call_convention != MONO_CALL_THISCALL) {
582 ADD_INST(code, pc, hppa_std(code, arg_reg, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, obj), 30));
585 fprintf(stderr, "case I didn't handle 2\n");
590 data[2] = (void *)stackval_from_data;
592 for (i = 0; i < sig->param_count; ++i) {
594 data[4 + i] = sig->params[i];
595 ADD_INST(code, pc, hppa_ldd(code, (4 + i) * 8, 27, 26)); // LDD x(%r27),%r26 == type
596 ADD_INST(code, pc, hppa_ldo(code, stack_val_pos, 30, 25)); // LDD x(%r30),%r25 == &stackval
597 if (sig->params[i]->byref) {
598 ADD_INST(code, pc, hppa_ldo(code, arg_val_pos, 3, 24));
600 int type = sig->params[i]->type;
607 case MONO_TYPE_STRING:
608 case MONO_TYPE_OBJECT:
609 case MONO_TYPE_CLASS:
610 case MONO_TYPE_SZARRAY:
613 ADD_INST(code, pc, hppa_ldo(code, arg_val_pos, 3, 24));
617 ADD_INST(code, pc, hppa_ldo(code, arg_val_pos + 4, 3, 24));
622 ADD_INST(code, pc, hppa_ldo(code, arg_val_pos + 6, 3, 24));
626 case MONO_TYPE_BOOLEAN:
627 ADD_INST(code, pc, hppa_ldo(code, arg_val_pos + 7, 3, 24));
629 case MONO_TYPE_VALUETYPE:
630 if (sig->params [i]->data.klass->enumtype) {
631 type = sig->params [i]->data.klass->enum_basetype->type;
634 int size = mono_class_native_size (sig->params[i]->data.klass, NULL);
636 ADD_INST(code, pc, hppa_ldo(code, arg_val_pos, 3, 24));
640 ADD_INST(code, pc, hppa_ldo(code, arg_val_pos, 3, 24));
646 arg_val_pos -=8 ; // as it is incremented later
648 ADD_INST(code, pc, hppa_ldo(code, vtoffsets[i], 30, 19));
649 ADD_INST(code, pc, hppa_std(code, 19, 0, 25));
653 fprintf(stderr, "can not cope in create method pointer %d\n", sig->params[i]->type);
658 ADD_INST(code, pc, hppa_ldo(code, sig->pinvoke, 0, 23)); // LDI sig->pinvoke,%r23
659 ADD_INST(code, pc, hppa_ldd(code, 16, 27, 19)); // LDD x(%r27),%r19 == stackval_from_data
660 ADD_INST(code, pc, hppa_ldd(code, 16, 19, 20)); // LDD 16(%r19),%r20
661 ADD_INST(code, pc, hppa_ldd(code, 24, 19, 27)); // LDD 24(%r19),%r27
662 ADD_INST(code, pc, hppa_blve(code, 20)); // BVE,L (%r20),%r2
663 ADD_INST(code, pc, hppa_ldo(code, -16, 30, 29)); // LDO -16(%r30),%r29
664 ADD_INST(code, pc, hppa_ldd(code, spill_offset + 8, 30, 27));
666 stack_val_pos += sizeof (stackval);
668 g_assert(stack_val_pos < -96);
671 ADD_INST(code, pc, hppa_ldo(code, stack_vals_offset, 30, 19));
672 ADD_INST(code, pc, hppa_std(code, 19, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, stack_args), 30));
673 ADD_INST(code, pc, hppa_ldo(code, stack_val_pos, 30, 19));
674 ADD_INST(code, pc, hppa_std(code, 19, invoke_rec_offset + G_STRUCT_OFFSET (MonoInvocation, retval), 30));
676 if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->data.klass->enumtype) {
677 int size = mono_class_native_size (sig->ret->data.klass, NULL);
678 // for large return structs pass on the pointer given us by our caller.
680 ADD_INST(code, pc, hppa_ldd(code, spill_offset + 16, 30, 28));
681 else // use space left on stack for the return value
682 ADD_INST(code, pc, hppa_ldo(code, stack_val_pos + sizeof(stackval), 30, 28));
683 ADD_INST(code, pc, hppa_std(code, 28, stack_val_pos, 30));
686 ADD_INST(code, pc, hppa_ldo(code, invoke_rec_offset, 30, 26)); // address of invocation
689 data[1] = (void *)ves_exec_method;
690 ADD_INST(code, pc, hppa_ldd(code, 8, 27, 19)); // LDD 8(%r27),%r19
691 ADD_INST(code, pc, hppa_ldd(code, 16, 19, 20)); // LDD 16(%r19),%r20
692 ADD_INST(code, pc, hppa_ldd(code, 24, 19, 27)); // LDD 24(%r19),%r27
693 ADD_INST(code, pc, hppa_blve(code, 20)); // BVE,L (%r20),%r2
694 ADD_INST(code, pc, hppa_ldo(code, -16, 30, 29)); // LDO -16(%r30),%r29
695 ADD_INST(code, pc, hppa_ldd(code, spill_offset + 8, 30, 27));
696 if (sig->ret->byref) {
697 fprintf(stderr, "can'ty cope with ret byref\n");
699 int simpletype = sig->ret->type;
701 switch (simpletype) {
704 case MONO_TYPE_BOOLEAN:
712 ADD_INST(code, pc, hppa_ldw(code, stack_val_pos, 30, 28)); // LDW x(%r30),%r28
718 case MONO_TYPE_STRING:
719 case MONO_TYPE_OBJECT:
720 case MONO_TYPE_CLASS:
721 case MONO_TYPE_SZARRAY:
723 ADD_INST(code, pc, hppa_ldd(code, stack_val_pos, 30, 28)); // LDD x(%r30),%r28
726 ADD_INST(code, pc, hppa_fldd(code, stack_val_pos, 30, 4)); // FLDD x(%r30),%fr4
728 case MONO_TYPE_VALUETYPE:
729 if (sig->ret->data.klass->enumtype) {
730 simpletype = sig->ret->data.klass->enum_basetype->type;
733 int size = mono_class_native_size (sig->ret->data.klass, NULL);
735 ADD_INST(code, pc, hppa_ldd(code, stack_val_pos, 30, 28));
737 ADD_INST(code, pc, hppa_ldd(code, 8, 28, 29));
738 ADD_INST(code, pc, hppa_ldd(code, 0, 28, 28));
743 fprintf(stderr, "can't cope with ret type %d\n", simpletype);
748 ADD_INST(code, pc, hppa_ldd(code, -frame_size-16, 30, 2));
749 ADD_INST(code, pc, hppa_ldd(code, spill_offset, 30, 4));
750 ADD_INST(code, pc, hppa_bve(code, 2, 0));
751 ADD_INST(code, pc, hppa_ldd_mb(code, -frame_size, 30, 3));
753 descriptor = (void **)malloc((8 + sig->param_count) * sizeof(void *) + sizeof(unsigned int) * pc);
754 data = descriptor + 4;
755 code = (unsigned int *)(data + 4 + sig->param_count);
761 fprintf(stderr, "generated: %d bytes\n", pc * 4);
762 disassemble(code_start, pc);
765 flush_cache(code_start, 4 * pc);
769 descriptor[2] = code_start;
770 descriptor[3] = data;
772 ji = g_new0 (MonoJitInfo, 1);
774 ji->code_size = 4; // does this matter?
775 ji->code_start = descriptor;
777 mono_jit_info_table_add (mono_get_root_domain (), ji);
779 return ji->code_start;