#include <string.h>
#include <math.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <mono/metadata/appdomain.h>
#include <mono/metadata/debug-helpers.h>
* spill variable if necessary.
*/
static inline int
-mono_spillvar_offset (MonoCompile *cfg, int spillvar)
+mono_spillvar_offset_int (MonoCompile *cfg, int spillvar)
{
MonoSpillInfo *info;
return info->offset;
}
-#if MONO_ARCH_USE_FPSTACK
-
/*
* returns the offset used by spillvar. It allocates a new
* spill float variable if necessary.
return info->offset;
}
+static inline int
+mono_spillvar_offset (MonoCompile *cfg, int spillvar, gboolean fp)
+{
+ if (fp)
+ return mono_spillvar_offset_float (cfg, spillvar);
+ else
+ return mono_spillvar_offset_int (cfg, spillvar);
+}
+
+#if MONO_ARCH_USE_FPSTACK
+
/*
* Creates a store for spilled floating point items
*/
static inline InstList*
inst_list_prepend (guint8 *mem, InstList *list, MonoInst *data)
{
- InstList *item = (InstList*)mem;
+ InstList *item = (InstList*)(gpointer)mem;
item->data = data;
item->prev = NULL;
item->next = list;
MONO_INST_NEW (cfg, load, OP_LOAD_MEMBASE);
load->dreg = sel;
load->inst_basereg = cfg->frame_reg;
- load->inst_offset = mono_spillvar_offset (cfg, spill);
+ load->inst_offset = mono_spillvar_offset (cfg, spill, fp);
insert_after_ins (ins, item, load);
DEBUG (printf ("SPILLED LOAD (%d at 0x%08lx(%%ebp)) R%d (freed %s)\n", spill, (long)load->inst_offset, i, mono_regname_full (sel, fp)));
if (fp)
MONO_INST_NEW (cfg, load, fp ? OP_LOADR8_MEMBASE : OP_LOAD_MEMBASE);
load->dreg = sel;
load->inst_basereg = cfg->frame_reg;
- load->inst_offset = mono_spillvar_offset (cfg, spill);
+ load->inst_offset = mono_spillvar_offset (cfg, spill, fp);
insert_after_ins (ins, item, load);
DEBUG (printf ("\tSPILLED LOAD (%d at 0x%08lx(%%ebp)) R%d (freed %s)\n", spill, (long)load->inst_offset, i, mono_regname_full (sel, fp)));
if (fp)
MONO_INST_NEW (cfg, store, fp ? OP_STORER8_MEMBASE_REG : OP_STORE_MEMBASE_REG);
store->sreg1 = reg;
store->inst_destbasereg = cfg->frame_reg;
- store->inst_offset = mono_spillvar_offset (cfg, spill);
+ store->inst_offset = mono_spillvar_offset (cfg, spill, fp);
if (ins) {
store->next = ins->next;
ins->next = store;
else {
g_assert (reg >= MONO_MAX_IREGS);
g_assert (hreg < MONO_MAX_IREGS);
+#ifndef __arm__
+ /* this seems to trigger a gcc compilation bug sometime (hreg is 0) */
g_assert (! is_global_ireg (hreg));
+#endif
rs->vassign [reg] = hreg;
rs->isymbolic [hreg] = reg;
insert_before_ins (ins, tmp, copy);
}
else {
- DEBUG (printf ("\tshortcut assignment of R%d to %s\n", ins->sreg2, mono_arch_regname (dest_sreg2)));
- assign_ireg (cfg, rs, ins->sreg2, dest_sreg2);
+ val = rs->vassign [ins->sreg2];
+ if (val == -1) {
+ DEBUG (printf ("\tshortcut assignment of R%d to %s\n", ins->sreg2, mono_arch_regname (dest_sreg2)));
+ assign_reg (cfg, rs, ins->sreg2, dest_sreg2, FALSE);
+ } else if (val < -1) {
+ /* FIXME: */
+ g_assert_not_reached ();
+ } else {
+ /* Argument already in hard reg, need to copy */
+ MonoInst *copy = create_copy_ins (cfg, dest_sreg2, val, NULL, ip, FALSE);
+ insert_before_ins (ins, tmp, copy);
+ }
}
} else {
int need_spill = TRUE;
g_list_free (fspill_list);
}
+CompRelation
+mono_opcode_to_cond (int opcode)
+{
+ switch (opcode) {
+ case CEE_BEQ:
+ case OP_CEQ:
+ case OP_IBEQ:
+ case OP_ICEQ:
+ case OP_LBEQ:
+ case OP_LCEQ:
+ case OP_FBEQ:
+ case OP_FCEQ:
+ case OP_COND_EXC_EQ:
+ case OP_COND_EXC_IEQ:
+ return CMP_EQ;
+ case CEE_BNE_UN:
+ case OP_IBNE_UN:
+ case OP_LBNE_UN:
+ case OP_FBNE_UN:
+ case OP_COND_EXC_NE_UN:
+ case OP_COND_EXC_INE_UN:
+ return CMP_NE;
+ case CEE_BLE:
+ case OP_IBLE:
+ case OP_LBLE:
+ case OP_FBLE:
+ return CMP_LE;
+ case CEE_BGE:
+ case OP_IBGE:
+ case OP_LBGE:
+ case OP_FBGE:
+ return CMP_GE;
+ case CEE_BLT:
+ case OP_CLT:
+ case OP_IBLT:
+ case OP_ICLT:
+ case OP_LBLT:
+ case OP_LCLT:
+ case OP_FBLT:
+ case OP_FCLT:
+ case OP_COND_EXC_LT:
+ case OP_COND_EXC_ILT:
+ return CMP_LT;
+ case CEE_BGT:
+ case OP_CGT:
+ case OP_IBGT:
+ case OP_ICGT:
+ case OP_LBGT:
+ case OP_LCGT:
+ case OP_FBGT:
+ case OP_FCGT:
+ case OP_COND_EXC_GT:
+ case OP_COND_EXC_IGT:
+ return CMP_GT;
+
+ case CEE_BLE_UN:
+ case OP_IBLE_UN:
+ case OP_LBLE_UN:
+ case OP_FBLE_UN:
+ case OP_COND_EXC_LE_UN:
+ case OP_COND_EXC_ILE_UN:
+ return CMP_LE_UN;
+ case CEE_BGE_UN:
+ case OP_IBGE_UN:
+ case OP_LBGE_UN:
+ case OP_FBGE_UN:
+ return CMP_GE_UN;
+ case CEE_BLT_UN:
+ case OP_CLT_UN:
+ case OP_IBLT_UN:
+ case OP_ICLT_UN:
+ case OP_LBLT_UN:
+ case OP_LCLT_UN:
+ case OP_FBLT_UN:
+ case OP_FCLT_UN:
+ case OP_COND_EXC_LT_UN:
+ case OP_COND_EXC_ILT_UN:
+ return CMP_LT_UN;
+ case CEE_BGT_UN:
+ case OP_CGT_UN:
+ case OP_IBGT_UN:
+ case OP_ICGT_UN:
+ case OP_LBGT_UN:
+ case OP_LCGT_UN:
+ case OP_FCGT_UN:
+ case OP_FBGT_UN:
+ case OP_COND_EXC_GT_UN:
+ case OP_COND_EXC_IGT_UN:
+ return CMP_GT_UN;
+ default:
+ printf ("%s\n", mono_inst_name (opcode));
+ g_assert_not_reached ();
+ }
+}
+
+CompType
+mono_opcode_to_type (int opcode, int cmp_opcode)
+{
+ if ((opcode >= CEE_BEQ) && (opcode <= CEE_BLT_UN))
+ return CMP_TYPE_L;
+ else if ((opcode >= OP_CEQ) && (opcode <= OP_CLT_UN))
+ return CMP_TYPE_L;
+ else if ((opcode >= OP_IBEQ) && (opcode <= OP_IBLT_UN))
+ return CMP_TYPE_I;
+ else if ((opcode >= OP_ICEQ) && (opcode <= OP_ICLT_UN))
+ return CMP_TYPE_I;
+ else if ((opcode >= OP_LBEQ) && (opcode <= OP_LBLT_UN))
+ return CMP_TYPE_L;
+ else if ((opcode >= OP_LCEQ) && (opcode <= OP_LCLT_UN))
+ return CMP_TYPE_L;
+ else if ((opcode >= OP_FBEQ) && (opcode <= OP_FBLT_UN))
+ return CMP_TYPE_F;
+ else if ((opcode >= OP_FCEQ) && (opcode <= OP_FCLT_UN))
+ return CMP_TYPE_F;
+ else if ((opcode >= OP_COND_EXC_IEQ) && (opcode <= OP_COND_EXC_ILT_UN))
+ return CMP_TYPE_I;
+ else if ((opcode >= OP_COND_EXC_EQ) && (opcode <= OP_COND_EXC_LT_UN)) {
+ switch (cmp_opcode) {
+ case OP_ICOMPARE:
+ case OP_ICOMPARE_IMM:
+ return CMP_TYPE_I;
+ default:
+ return CMP_TYPE_L;
+ }
+ } else {
+ g_error ("Unknown opcode '%s' in opcode_to_type", mono_inst_name (opcode));
+ return 0;
+ }
+}
+
gboolean
mono_is_regsize_var (MonoType *t)
{