2 * helpers.c: architecture independent helper functions
5 * Dietmar Maurer (dietmar@ximian.com)
7 * (C) 2001 Ximian, Inc.
11 #include <mono/os/gc_wrapper.h>
18 mono_map_store_svt_type (int svt)
22 return MB_TERM_STIND_I4;
24 return MB_TERM_STIND_REF;
26 return MB_TERM_STIND_I8;
28 return MB_TERM_STIND_R8;
30 g_assert_not_reached ();
37 mono_get_val_sizes (MonoValueType type, int *size, int *align)
41 *size = *align = sizeof (gint32);
44 *size = *align = sizeof (gint64);
47 *size = *align = sizeof (gpointer);
50 *size = *align = sizeof (double);
53 g_assert_not_reached ();
58 * mono_map_stind_type:
59 * @type: the type to map
61 * Translates the MonoType @type into the corresponding store opcode
62 * for the code generator.
65 mono_map_stind_type (MonoType *type)
68 return MB_TERM_STIND_REF;
73 case MONO_TYPE_BOOLEAN:
74 return MB_TERM_STIND_I1;
78 return MB_TERM_STIND_I2;
79 #if SIZEOF_VOID_P == 4
85 return MB_TERM_STIND_I4;
87 case MONO_TYPE_OBJECT:
88 case MONO_TYPE_STRING:
90 case MONO_TYPE_SZARRAY:
92 return MB_TERM_STIND_REF;
95 #if SIZEOF_VOID_P == 8
99 return MB_TERM_STIND_I8;
101 return MB_TERM_STIND_R4;
103 return MB_TERM_STIND_R8;
104 case MONO_TYPE_VALUETYPE:
105 if (type->data.klass->enumtype)
106 return mono_map_stind_type (type->data.klass->enum_basetype);
108 return MB_TERM_STIND_OBJ;
110 g_warning ("unknown type %02x", type->type);
111 g_assert_not_reached ();
114 g_assert_not_reached ();
119 * mono_map_remote_stind_type:
120 * @type: the type to map
122 * Translates the MonoType @type into the corresponding remote store opcode
123 * for the code generator.
126 mono_map_remote_stind_type (MonoType *type)
129 return MB_TERM_REMOTE_STIND_REF;
132 switch (type->type) {
135 case MONO_TYPE_BOOLEAN:
136 return MB_TERM_REMOTE_STIND_I1;
140 return MB_TERM_REMOTE_STIND_I2;
141 #if SIZEOF_VOID_P == 4
147 return MB_TERM_REMOTE_STIND_I4;
148 case MONO_TYPE_CLASS:
149 case MONO_TYPE_OBJECT:
150 case MONO_TYPE_STRING:
152 case MONO_TYPE_SZARRAY:
153 case MONO_TYPE_ARRAY:
154 return MB_TERM_REMOTE_STIND_REF;
155 #if SIZEOF_VOID_P == 8
161 return MB_TERM_REMOTE_STIND_I8;
163 return MB_TERM_REMOTE_STIND_R4;
165 return MB_TERM_REMOTE_STIND_R8;
166 case MONO_TYPE_VALUETYPE:
167 if (type->data.klass->enumtype)
168 return mono_map_remote_stind_type (type->data.klass->enum_basetype);
170 return MB_TERM_REMOTE_STIND_OBJ;
172 g_warning ("unknown type %02x", type->type);
173 g_assert_not_reached ();
176 g_assert_not_reached ();
181 mono_map_starg_type (MonoType *type)
184 return MB_TERM_STIND_REF;
186 switch (type->type) {
189 case MONO_TYPE_BOOLEAN:
193 #if SIZEOF_VOID_P == 4
199 return MB_TERM_STIND_I4;
200 case MONO_TYPE_CLASS:
201 case MONO_TYPE_OBJECT:
202 case MONO_TYPE_STRING:
204 case MONO_TYPE_SZARRAY:
205 case MONO_TYPE_ARRAY:
206 return MB_TERM_STIND_REF;
207 #if SIZEOF_VOID_P == 8
213 return MB_TERM_STIND_I8;
215 return MB_TERM_STIND_R4;
217 return MB_TERM_STIND_R8;
218 case MONO_TYPE_VALUETYPE:
219 if (type->data.klass->enumtype)
220 return mono_map_starg_type (type->data.klass->enum_basetype);
222 return MB_TERM_STIND_OBJ;
224 g_warning ("unknown type %02x", type->type);
225 g_assert_not_reached ();
228 g_assert_not_reached ();
233 mono_map_arg_type (MonoType *type)
236 return MB_TERM_ARG_I4;
238 switch (type->type) {
241 case MONO_TYPE_BOOLEAN:
245 #if SIZEOF_VOID_P == 4
251 return MB_TERM_ARG_I4;
252 case MONO_TYPE_CLASS:
253 case MONO_TYPE_OBJECT:
255 case MONO_TYPE_SZARRAY:
256 case MONO_TYPE_ARRAY:
257 case MONO_TYPE_STRING:
258 #if SIZEOF_VOID_P == 8
259 return MB_TERM_ARG_I8;
261 return MB_TERM_ARG_I4;
265 #if SIZEOF_VOID_P == 8
269 return MB_TERM_ARG_I8;
271 return MB_TERM_ARG_R4;
273 return MB_TERM_ARG_R8;
274 case MONO_TYPE_VALUETYPE:
275 if (type->data.klass->enumtype)
276 return mono_map_arg_type (type->data.klass->enum_basetype);
278 return MB_TERM_ARG_OBJ;
280 g_warning ("unknown type %02x", type->type);
281 g_assert_not_reached ();
284 g_assert_not_reached ();
289 * mono_map_ldind_type:
290 * @type: the type to map
292 * Translates the MonoType @type into the corresponding load opcode
293 * for the code generator.
296 mono_map_ldind_type (MonoType *type, MonoValueType *svt)
300 return MB_TERM_LDIND_REF;
303 switch (type->type) {
306 return MB_TERM_LDIND_I1;
308 case MONO_TYPE_BOOLEAN:
310 return MB_TERM_LDIND_U1;
313 return MB_TERM_LDIND_I2;
317 return MB_TERM_LDIND_U2;
318 #if SIZEOF_VOID_P == 4
323 return MB_TERM_LDIND_I4;
324 #if SIZEOF_VOID_P == 4
329 return MB_TERM_LDIND_U4;
330 case MONO_TYPE_CLASS:
331 case MONO_TYPE_OBJECT:
332 case MONO_TYPE_STRING:
334 case MONO_TYPE_SZARRAY:
335 case MONO_TYPE_ARRAY:
337 return MB_TERM_LDIND_REF;
338 #if SIZEOF_VOID_P == 8
345 return MB_TERM_LDIND_I8;
348 return MB_TERM_LDIND_R4;
351 return MB_TERM_LDIND_R8;
352 case MONO_TYPE_VALUETYPE:
353 if (type->data.klass->enumtype) {
354 return mono_map_ldind_type (type->data.klass->enum_basetype, svt);
357 return MB_TERM_LDIND_OBJ;
360 g_warning ("unknown type %02x", type->type);
361 g_assert_not_reached ();
364 g_assert_not_reached ();
369 mono_map_ldarg_type (MonoType *type, MonoValueType *svt)
373 return MB_TERM_LDIND_REF;
376 switch (type->type) {
379 case MONO_TYPE_BOOLEAN:
383 #if SIZEOF_VOID_P == 4
390 return MB_TERM_LDIND_U4;
391 case MONO_TYPE_CLASS:
392 case MONO_TYPE_OBJECT:
393 case MONO_TYPE_STRING:
395 case MONO_TYPE_SZARRAY:
396 case MONO_TYPE_ARRAY:
398 return MB_TERM_LDIND_REF;
401 #if SIZEOF_VOID_P == 8
406 return MB_TERM_LDIND_I8;
409 return MB_TERM_LDIND_R4;
412 return MB_TERM_LDIND_R8;
413 case MONO_TYPE_VALUETYPE:
414 if (type->data.klass->enumtype) {
415 return mono_map_ldarg_type (type->data.klass->enum_basetype, svt);
418 return MB_TERM_LDIND_OBJ;
421 g_warning ("unknown type %02x", type->type);
422 g_assert_not_reached ();
425 g_assert_not_reached ();
430 * mono_map_call_type:
431 * @type: the type to map
433 * Translates the MonoType @type into the corresponding call opcode
434 * for the code generator.
437 mono_map_call_type (MonoType *type, MonoValueType *svt)
440 return MB_TERM_CALL_I4;
442 switch (type->type) {
445 return MB_TERM_CALL_VOID;
448 case MONO_TYPE_BOOLEAN:
452 #if SIZEOF_VOID_P == 4
459 return MB_TERM_CALL_I4;
460 case MONO_TYPE_VALUETYPE:
461 if (type->data.klass->enumtype) {
462 return mono_map_call_type (type->data.klass->enum_basetype, svt);
465 return MB_TERM_CALL_VOID;
467 case MONO_TYPE_CLASS:
468 case MONO_TYPE_OBJECT:
469 case MONO_TYPE_STRING:
471 case MONO_TYPE_SZARRAY:
472 case MONO_TYPE_ARRAY:
474 #if SIZEOF_VOID_P == 8
475 return MB_TERM_CALL_I8;
477 return MB_TERM_CALL_I4;
481 #if SIZEOF_VOID_P == 8
486 return MB_TERM_CALL_I8;
490 return MB_TERM_CALL_R8;
492 g_warning ("unknown type %02x", type->type);
493 g_assert_not_reached ();
496 g_assert_not_reached ();
501 mono_ctree_new (MonoMemPool *mp, int op, MBTree *left, MBTree *right)
503 MBTree *t = mono_mempool_alloc0 (mp, sizeof (MBTree));
511 t->svt = VAL_UNKNOWN;
517 mono_ctree_new_leaf (MonoMemPool *mp, int op)
519 return mono_ctree_new (mp, op, NULL, NULL);
523 mono_ctree_new_icon4 (MonoMemPool *mp, gint32 data)
525 MBTree *t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
531 * prints the tree to stdout
534 mono_print_ctree (MonoFlowGraph *cfg, MBTree *tree)
541 arity = (tree->left != NULL) + (tree->right != NULL);
544 printf (" (%s", mono_burg_term_string [tree->op]);
546 printf (" %s", mono_burg_term_string [tree->op]);
549 case MB_TERM_CONST_I4:
550 printf ("[%d]", tree->data.i);
553 if (VARINFO (cfg, tree->data.i).reg >= 0)
554 printf ("[%s|%d]", arch_get_reg_name (VARINFO (cfg, tree->data.i).reg),
557 printf ("[%d]", tree->data.i);
561 g_assert (!(tree->right && !tree->left));
563 mono_print_ctree (cfg, tree->left);
564 mono_print_ctree (cfg, tree->right);
571 * prints the whole forest to stdout
574 mono_print_forest (MonoFlowGraph *cfg, GPtrArray *forest)
576 const int top = forest->len;
579 for (i = 0; i < top; i++) {
580 MBTree *t = (MBTree *) g_ptr_array_index (forest, i);
582 mono_print_ctree (cfg, t);
589 * mono_disassemble_code:
590 * @code: a pointer to the code
591 * @size: the code size in bytes
593 * Disassemble to code to stdout.
596 mono_disassemble_code (guint8 *code, int size, char *id)
601 if (!(ofd = fopen ("/tmp/test.s", "w")))
602 g_assert_not_reached ();
604 fprintf (ofd, "%s:\n", id);
606 for (i = 0; i < size; ++i)
607 fprintf (ofd, ".byte %d\n", (unsigned int) code [i]);
611 system ("as /tmp/test.s -o /tmp/test.o;objdump -d /tmp/test.o");