#include <string.h>
#include <math.h>
#include <unistd.h>
-#include <sys/mman.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/debug-helpers.h>
const char * const sparc_desc [OP_LAST];
static const char*const * ins_spec = sparc_desc;
#elif defined(__i386__)
+#ifdef _MSC_VER
+extern const char * const pentium_desc [OP_LAST];
+#else
const char * const pentium_desc [OP_LAST];
+#endif
static const char*const * ins_spec = pentium_desc;
#elif defined(__ia64__)
const char * const ia64_desc [OP_LAST];
static const char*const * ins_spec = ia64_desc;
+#elif defined(__arm__)
+const char * const arm_cpu_desc [OP_LAST];
+static const char*const * ins_spec = arm_cpu_desc;
+#elif defined(__s390__)
+const char * const s390_cpu_desc [OP_LAST];
+static const char*const * ins_spec = s390_cpu_desc;
#else
#error "Not implemented"
#endif
if (!*si) {
*si = info = mono_mempool_alloc (cfg->mempool, sizeof (MonoSpillInfo));
info->next = NULL;
- cfg->stack_offset += sizeof (gpointer);
- info->offset = - cfg->stack_offset;
+ if (cfg->flags & MONO_CFG_HAS_SPILLUP) {
+ info->offset = cfg->stack_offset;
+ cfg->stack_offset += sizeof (gpointer);
+ } else {
+ cfg->stack_offset += sizeof (gpointer);
+ info->offset = - cfg->stack_offset;
+ }
}
if (i == spillvar)
if (!*si) {
*si = info = mono_mempool_alloc (cfg->mempool, sizeof (MonoSpillInfo));
info->next = NULL;
- cfg->stack_offset += sizeof (double);
- info->offset = - cfg->stack_offset;
+ if (cfg->flags & MONO_CFG_HAS_SPILLUP) {
+ cfg->stack_offset += 7;
+ cfg->stack_offset &= ~7;
+ info->offset = cfg->stack_offset;
+ cfg->stack_offset += sizeof (double);
+ } else {
+ /* FIXME: align */
+ cfg->stack_offset += sizeof (double);
+ info->offset = - cfg->stack_offset;
+ }
}
if (i == spillvar)
return load;
}
+#define regmask(reg) (((regmask_t)1) << (reg))
+
#define is_hard_ireg(r) ((r) >= 0 && (r) < MONO_MAX_IREGS)
#define is_hard_freg(r) ((r) >= 0 && (r) < MONO_MAX_FREGS)
-#define is_global_ireg(r) (is_hard_ireg ((r)) && (MONO_ARCH_CALLEE_SAVED_REGS & (1 << (r))))
-#define is_local_ireg(r) (is_hard_ireg ((r)) && (MONO_ARCH_CALLEE_REGS & (1 << (r))))
-#define is_global_freg(r) (is_hard_freg ((r)) && (MONO_ARCH_CALLEE_SAVED_FREGS & (1 << (r))))
-#define is_local_freg(r) (is_hard_ireg ((r)) && (MONO_ARCH_CALLEE_FREGS & (1 << (r))))
+#define is_global_ireg(r) (is_hard_ireg ((r)) && (MONO_ARCH_CALLEE_SAVED_REGS & (regmask (r))))
+#define is_local_ireg(r) (is_hard_ireg ((r)) && (MONO_ARCH_CALLEE_REGS & (regmask (r))))
+#define is_global_freg(r) (is_hard_freg ((r)) && (MONO_ARCH_CALLEE_SAVED_FREGS & (regmask (r))))
+#define is_local_freg(r) (is_hard_ireg ((r)) && (MONO_ARCH_CALLEE_FREGS & (regmask (r))))
#define ireg_is_freeable(r) is_local_ireg ((r))
#define freg_is_freeable(r) is_hard_freg ((r))
#define dreg_is_fp(ins) (ins_spec [(ins)->opcode] [MONO_INST_DEST] == 'f')
#endif
-#define regpair_reg2_mask(desc,hreg1) ((MONO_ARCH_INST_REGPAIR_REG2 (desc,hreg1) != -1) ? (1 << MONO_ARCH_INST_REGPAIR_REG2 (desc,hreg1)) : MONO_ARCH_CALLEE_REGS)
+#define regpair_reg2_mask(desc,hreg1) ((MONO_ARCH_INST_REGPAIR_REG2 (desc,hreg1) != -1) ? (regmask (MONO_ARCH_INST_REGPAIR_REG2 (desc,hreg1))) : MONO_ARCH_CALLEE_REGS)
+
+#ifdef MONO_ARCH_IS_GLOBAL_IREG
+#undef is_global_ireg
+#define is_global_ireg(reg) MONO_ARCH_IS_GLOBAL_IREG ((reg))
+#endif
typedef struct {
int born_in;
int last_use;
int prev_use;
int flags; /* used to track fp spill/load */
- guint32 preferred_mask; /* the hreg where the register should be allocated, or 0 */
+ regmask_t preferred_mask; /* the hreg where the register should be allocated, or 0 */
} RegTrack;
static void
if (spec [MONO_INST_DEST]) {
gboolean fp = dreg_is_fp (ins);
- if (is_soft_reg (ins->dreg, fp))
- g_print (" R%d <-", ins->dreg);
- else if (spec [MONO_INST_DEST] == 'b') {
+ if (is_soft_reg (ins->dreg, fp)) {
+ if (spec [MONO_INST_DEST] == 'b') {
+ if (ins->inst_offset == 0)
+ g_print (" [R%d] <-", ins->dreg);
+ else
+ g_print (" [R%d + 0x%lx] <-", ins->dreg, (long)ins->inst_offset);
+ }
+ else
+ g_print (" R%d <-", ins->dreg);
+ } else if (spec [MONO_INST_DEST] == 'b') {
if (ins->inst_offset == 0)
g_print (" [%s] <-", mono_arch_regname (ins->dreg));
else
ins->next = load;
DEBUG (g_print ("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)
- i = mono_regstate_alloc_float (cfg->rs, 1 << sel);
+ i = mono_regstate_alloc_float (cfg->rs, regmask (sel));
else
- i = mono_regstate_alloc_int (cfg->rs, 1 << sel);
+ i = mono_regstate_alloc_int (cfg->rs, regmask (sel));
g_assert (i == sel);
return sel;
}
+/* This isn't defined on older glib versions and on some platforms */
+#ifndef G_GUINT64_FORMAT
+#define G_GUINT64_FORMAT "ul"
+#endif
+
static int
-get_register_spilling (MonoCompile *cfg, InstList *item, MonoInst *ins, guint32 regmask, int reg, gboolean fp)
+get_register_spilling (MonoCompile *cfg, InstList *item, MonoInst *ins, regmask_t regmask, int reg, gboolean fp)
{
MonoInst *load;
int i, sel, spill;
symbolic = cfg->rs->isymbolic;
}
- DEBUG (g_print ("\tstart regmask to assign R%d: 0x%08x (R%d <- R%d R%d)\n", reg, regmask, ins->dreg, ins->sreg1, ins->sreg2));
+ DEBUG (g_print ("\tstart regmask to assign R%d: 0x%08" G_GUINT64_FORMAT " (R%d <- R%d R%d)\n", reg, (guint64)regmask, ins->dreg, ins->sreg1, ins->sreg2));
/* exclude the registers in the current instruction */
if ((sreg1_is_fp (ins) == fp) && (reg != ins->sreg1) && (reg_is_freeable (ins->sreg1, fp) || (is_soft_reg (ins->sreg1, fp) && rassign (cfg, ins->sreg1, fp) >= 0))) {
if (is_soft_reg (ins->sreg1, fp))
- regmask &= ~ (1 << rassign (cfg, ins->sreg1, fp));
+ regmask &= ~ (regmask (rassign (cfg, ins->sreg1, fp)));
else
- regmask &= ~ (1 << ins->sreg1);
+ regmask &= ~ (regmask (ins->sreg1));
DEBUG (g_print ("\t\texcluding sreg1 %s\n", mono_regname_full (ins->sreg1, fp)));
}
if ((sreg2_is_fp (ins) == fp) && (reg != ins->sreg2) && (reg_is_freeable (ins->sreg2, fp) || (is_soft_reg (ins->sreg2, fp) && rassign (cfg, ins->sreg2, fp) >= 0))) {
if (is_soft_reg (ins->sreg2, fp))
- regmask &= ~ (1 << rassign (cfg, ins->sreg2, fp));
+ regmask &= ~ (regmask (rassign (cfg, ins->sreg2, fp)));
else
- regmask &= ~ (1 << ins->sreg2);
+ regmask &= ~ (regmask (ins->sreg2));
DEBUG (g_print ("\t\texcluding sreg2 %s %d\n", mono_regname_full (ins->sreg2, fp), ins->sreg2));
}
if ((dreg_is_fp (ins) == fp) && (reg != ins->dreg) && reg_is_freeable (ins->dreg, fp)) {
- regmask &= ~ (1 << ins->dreg);
+ regmask &= ~ (regmask (ins->dreg));
DEBUG (g_print ("\t\texcluding dreg %s\n", mono_regname_full (ins->dreg, fp)));
}
- DEBUG (g_print ("\t\tavailable regmask: 0x%08x\n", regmask));
+ DEBUG (g_print ("\t\tavailable regmask: 0x%08" G_GUINT64_FORMAT "\n", (guint64)regmask));
g_assert (regmask); /* need at least a register we can free */
sel = -1;
/* we should track prev_use and spill the register that's farther */
if (fp) {
for (i = 0; i < MONO_MAX_FREGS; ++i) {
- if (regmask & (1 << i)) {
+ if (regmask & (regmask (i))) {
sel = i;
DEBUG (g_print ("\t\tselected register %s has assignment %d\n", mono_arch_fregname (sel), cfg->rs->fsymbolic [sel]));
break;
}
else {
for (i = 0; i < MONO_MAX_IREGS; ++i) {
- if (regmask & (1 << i)) {
+ if (regmask & (regmask (i))) {
sel = i;
DEBUG (g_print ("\t\tselected register %s has assignment %d\n", mono_arch_regname (sel), cfg->rs->isymbolic [sel]));
break;
ins->next = load;
DEBUG (g_print ("\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)
- i = mono_regstate_alloc_float (cfg->rs, 1 << sel);
+ i = mono_regstate_alloc_float (cfg->rs, regmask (sel));
else
- i = mono_regstate_alloc_int (cfg->rs, 1 << sel);
+ i = mono_regstate_alloc_int (cfg->rs, regmask (sel));
g_assert (i == sel);
return sel;
static void
free_up_ireg (MonoCompile *cfg, InstList *item, MonoInst *ins, int hreg)
{
- if (!(cfg->rs->ifree_mask & (1 << hreg))) {
+ if (!(cfg->rs->ifree_mask & (regmask (hreg)))) {
DEBUG (g_print ("\tforced spill of R%d\n", cfg->rs->isymbolic [hreg]));
get_register_force_spilling (cfg, item, ins, cfg->rs->isymbolic [hreg], FALSE);
mono_regstate_free_int (cfg->rs, hreg);
free_up_reg (MonoCompile *cfg, InstList *item, MonoInst *ins, int hreg, gboolean fp)
{
if (fp) {
- if (!(cfg->rs->ffree_mask & (1 << hreg))) {
+ if (!(cfg->rs->ffree_mask & (regmask (hreg)))) {
DEBUG (g_print ("\tforced spill of R%d\n", cfg->rs->isymbolic [hreg]));
get_register_force_spilling (cfg, item, ins, cfg->rs->isymbolic [hreg], fp);
mono_regstate_free_float (cfg->rs, hreg);
}
}
else {
- if (!(cfg->rs->ifree_mask & (1 << hreg))) {
+ if (!(cfg->rs->ifree_mask & (regmask (hreg)))) {
DEBUG (g_print ("\tforced spill of R%d\n", cfg->rs->isymbolic [hreg]));
get_register_force_spilling (cfg, item, ins, cfg->rs->isymbolic [hreg], fp);
mono_regstate_free_int (cfg->rs, hreg);
}
static MonoInst*
-create_copy_ins (MonoCompile *cfg, int dest, int src, MonoInst *ins, gboolean fp)
+create_copy_ins (MonoCompile *cfg, int dest, int src, MonoInst *ins, const unsigned char *ip, gboolean fp)
{
MonoInst *copy;
copy->dreg = dest;
copy->sreg1 = src;
+ copy->cil_code = ip;
if (ins) {
copy->next = ins->next;
+ copy->cil_code = ins->cil_code;
ins->next = copy;
}
DEBUG (g_print ("\tforced copy from %s to %s\n", mono_regname_full (src, fp), mono_regname_full (dest, fp)));
/* flags used in reginfo->flags */
enum {
- MONO_FP_NEEDS_LOAD_SPILL = 1 << 0,
- MONO_FP_NEEDS_SPILL = 1 << 1,
- MONO_FP_NEEDS_LOAD = 1 << 2
+ MONO_FP_NEEDS_LOAD_SPILL = regmask (0),
+ MONO_FP_NEEDS_SPILL = regmask (1),
+ MONO_FP_NEEDS_LOAD = regmask (2)
};
static int
-alloc_int_reg (MonoCompile *cfg, InstList *tmp, MonoInst *ins, guint32 dest_mask, int sym_reg, RegTrack *info)
+alloc_int_reg (MonoCompile *cfg, InstList *tmp, MonoInst *ins, regmask_t dest_mask, int sym_reg, RegTrack *info)
{
int val;
}
static int
-alloc_float_reg (MonoCompile *cfg, InstList *tmp, MonoInst *ins, guint32 dest_mask, int sym_reg)
+alloc_float_reg (MonoCompile *cfg, InstList *tmp, MonoInst *ins, regmask_t dest_mask, int sym_reg)
{
int val;
}
static int
-alloc_reg (MonoCompile *cfg, InstList *tmp, MonoInst *ins, guint32 dest_mask, int sym_reg, RegTrack *info, gboolean fp)
+alloc_reg (MonoCompile *cfg, InstList *tmp, MonoInst *ins, regmask_t dest_mask, int sym_reg, RegTrack *info, gboolean fp)
{
if (fp)
return alloc_float_reg (cfg, tmp, ins, dest_mask, sym_reg);
}
static inline void
-assign_reg (MonoRegState *rs, int reg, int hreg, gboolean fp)
+assign_reg (MonoCompile *cfg, MonoRegState *rs, int reg, int hreg, gboolean fp)
{
if (fp) {
g_assert (reg >= MONO_MAX_FREGS);
rs->fassign [reg] = hreg;
rs->fsymbolic [hreg] = reg;
- rs->ffree_mask &= ~ (1 << hreg);
+ rs->ffree_mask &= ~ (regmask (hreg));
}
else {
g_assert (reg >= MONO_MAX_IREGS);
rs->iassign [reg] = hreg;
rs->isymbolic [hreg] = reg;
- rs->ifree_mask &= ~ (1 << hreg);
+ rs->ifree_mask &= ~ (regmask (hreg));
}
}
static inline void
-assign_ireg (MonoRegState *rs, int reg, int hreg)
+assign_ireg (MonoCompile *cfg, MonoRegState *rs, int reg, int hreg)
{
- assign_reg (rs, reg, hreg, FALSE);
+ assign_reg (cfg, rs, reg, hreg, FALSE);
}
/*
rs->ffree_mask = MONO_ARCH_CALLEE_FREGS;
if (use_fpstack)
- rs->ffree_mask = 0xff & ~(1 << MONO_ARCH_FPSTACK_SIZE);
+ rs->ffree_mask = 0xff & ~(regmask (MONO_ARCH_FPSTACK_SIZE));
ins = bb->code;
dest_dreg = MONO_ARCH_INST_FIXED_REG (spec [MONO_INST_DEST]);
if (dest_dreg != -1)
- reginfod [ins->dreg].preferred_mask = (1 << dest_dreg);
+ reginfod [ins->dreg].preferred_mask = (regmask (dest_dreg));
if (MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_DEST])) {
/* The virtual register is allocated sequentially */
int prev_dreg, prev_sreg1, prev_sreg2, clob_dreg;
int dest_dreg, dest_sreg1, dest_sreg2, clob_reg;
int dreg_high, sreg1_high;
- guint32 dreg_mask, sreg1_mask, sreg2_mask, mask;
+ regmask_t dreg_mask, sreg1_mask, sreg2_mask, mask;
+ const unsigned char *ip;
--i;
ins = tmp->data;
spec = ins_spec [ins->opcode];
prev_dreg = -1;
+ prev_sreg2 = -1;
clob_dreg = -1;
clob_reg = -1;
dest_dreg = -1;
DEBUG (g_print ("processing:"));
DEBUG (print_ins (i, ins));
+ ip = ins->cil_code;
+
/*
* FIXED REGS
*/
* TRACK FIXED SREG2
*/
if (dest_sreg2 != -1) {
- if (rs->ifree_mask & (1 << dest_sreg2)) {
+ if (rs->ifree_mask & (regmask (dest_sreg2))) {
if (is_global_ireg (ins->sreg2)) {
/* Argument already in hard reg, need to copy */
- MonoInst *copy = create_copy_ins (cfg, dest_sreg2, ins->sreg2, NULL, FALSE);
+ MonoInst *copy = create_copy_ins (cfg, dest_sreg2, ins->sreg2, NULL, ip, FALSE);
insert_before_ins (ins, tmp, copy);
}
else {
DEBUG (g_print ("\tshortcut assignment of R%d to %s\n", ins->sreg2, mono_arch_regname (dest_sreg2)));
- assign_ireg (rs, ins->sreg2, dest_sreg2);
+ assign_ireg (cfg, rs, ins->sreg2, dest_sreg2);
}
} else {
int need_spill = TRUE;
- dreg_mask &= ~ (1 << dest_sreg2);
- sreg1_mask &= ~ (1 << dest_sreg2);
+ dreg_mask &= ~ (regmask (dest_sreg2));
+ sreg1_mask &= ~ (regmask (dest_sreg2));
/*
* First check if dreg is assigned to dest_sreg2, since we
DEBUG (g_print ("\tchanging dreg R%d to %s from %s\n", ins->dreg, mono_arch_regname (new_dest), mono_arch_regname (dest_sreg2)));
prev_dreg = ins->dreg;
- assign_ireg (rs, ins->dreg, new_dest);
+ assign_ireg (cfg, rs, ins->dreg, new_dest);
clob_dreg = ins->dreg;
- create_copy_ins (cfg, dest_sreg2, new_dest, ins, FALSE);
+ create_copy_ins (cfg, dest_sreg2, new_dest, ins, ip, FALSE);
need_spill = FALSE;
}
if (is_global_ireg (ins->sreg2)) {
- MonoInst *copy = create_copy_ins (cfg, dest_sreg2, ins->sreg2, NULL, FALSE);
+ MonoInst *copy = create_copy_ins (cfg, dest_sreg2, ins->sreg2, NULL, ip, FALSE);
insert_before_ins (ins, tmp, copy);
}
else {
if (!is_global_ireg (ins->sreg2))
/* force-set sreg2 */
- assign_ireg (rs, ins->sreg2, dest_sreg2);
+ assign_ireg (cfg, rs, ins->sreg2, dest_sreg2);
}
ins->sreg2 = dest_sreg2;
}
if (spec [MONO_INST_DEST] && (!fp || (fp && !use_fpstack)) && is_soft_reg (ins->dreg, fp))
prev_dreg = ins->dreg;
+ if (spec [MONO_INST_DEST] == 'b') {
+ /*
+ * The dest reg is read by the instruction, not written, so
+ * avoid allocating sreg1/sreg2 to the same reg.
+ */
+ if (dest_sreg1 != -1)
+ dreg_mask &= ~ (regmask (dest_sreg1));
+ if (dest_sreg2 != -1)
+ dreg_mask &= ~ (regmask (dest_sreg2));
+ }
+
/*
* If dreg is a fixed regpair, free up both of the needed hregs to avoid
* various complex situations.
if ((!fp || (fp && !use_fpstack)) && (is_soft_reg (ins->dreg, fp))) {
if (dest_dreg != -1)
- dreg_mask = (1 << dest_dreg);
+ dreg_mask = (regmask (dest_dreg));
val = rassign (cfg, ins->dreg, fp);
spill = -val -1;
}
val = alloc_reg (cfg, tmp, ins, dreg_mask, ins->dreg, ®info [ins->dreg], fp);
- assign_reg (rs, ins->dreg, val, fp);
+ assign_reg (cfg, rs, ins->dreg, val, fp);
if (spill)
create_spilled_store (cfg, spill, val, prev_dreg, ins, fp);
}
create_spilled_store (cfg, spill, val, reg2, ins, fp);
}
else {
- if (! (mask & (1 << val))) {
+ if (! (mask & (regmask (val)))) {
val = mono_regstate_alloc_int (rs, mask);
if (val < 0)
val = get_register_spilling (cfg, tmp, ins, mask, reg2, fp);
/* Reallocate hreg to the correct register */
- create_copy_ins (cfg, rs->iassign [reg2], val, ins, fp);
+ create_copy_ins (cfg, rs->iassign [reg2], val, ins, ip, fp);
mono_regstate_free_int (rs, rs->iassign [reg2]);
}
}
DEBUG (g_print ("\tassigned dreg-high %s to dest R%d\n", mono_arch_regname (val), reg2));
- assign_reg (rs, reg2, val, fp);
+ assign_reg (cfg, rs, reg2, val, fp);
dreg_high = val;
ins->unused = val;
if ((dest_dreg != -1) && (ins->dreg != dest_dreg)) {
/* this instruction only outputs to dest_dreg, need to copy */
- create_copy_ins (cfg, ins->dreg, dest_dreg, ins, fp);
+ create_copy_ins (cfg, ins->dreg, dest_dreg, ins, ip, fp);
ins->dreg = dest_dreg;
if (fp) {
}
}
+ if (spec [MONO_INST_DEST] == 'b') {
+ /*
+ * The dest reg is read by the instruction, not written, so
+ * avoid allocating sreg1/sreg2 to the same reg.
+ */
+ sreg1_mask &= ~ (regmask (ins->dreg));
+ sreg2_mask &= ~ (regmask (ins->dreg));
+ }
+
/*
* TRACK CLOBBERING
*/
- if ((clob_reg != -1) && (!(rs->ifree_mask & (1 << clob_reg)))) {
+ if ((clob_reg != -1) && (!(rs->ifree_mask & (regmask (clob_reg))))) {
DEBUG (g_print ("\tforced spill of clobbered reg R%d\n", rs->isymbolic [clob_reg]));
get_register_force_spilling (cfg, tmp, ins, rs->isymbolic [clob_reg], FALSE);
mono_regstate_free_int (rs, clob_reg);
dreg2 = -1;
for (j = 0; j < MONO_MAX_IREGS; ++j) {
- s = 1 << j;
+ s = regmask (j);
if ((clob_mask & s) && !(rs->ifree_mask & s) && (j != ins->sreg1) && (j != dreg) && (j != dreg2)) {
get_register_force_spilling (cfg, tmp, ins, rs->isymbolic [j], FALSE);
mono_regstate_free_int (rs, j);
dreg = -1;
for (j = 0; j < MONO_MAX_FREGS; ++j) {
- s = 1 << j;
+ s = regmask (j);
if ((clob_mask & s) && !(rs->ffree_mask & s) && (j != ins->sreg1) && (j != dreg)) {
get_register_force_spilling (cfg, tmp, ins, rs->fsymbolic [j], TRUE);
mono_regstate_free_float (rs, j);
hreg = regpair >> 24;
reg = regpair & 0xffffff;
- assign_reg (rs, reg, hreg, FALSE);
+ assign_reg (cfg, rs, reg, hreg, FALSE);
- sreg1_mask &= ~(1 << hreg);
+ sreg1_mask &= ~(regmask (hreg));
DEBUG (g_print ("\tassigned arg reg %s to R%d\n", mono_arch_regname (hreg), reg));
hreg = regpair >> 24;
reg = regpair & 0xffffff;
- assign_reg (rs, reg, hreg, TRUE);
+ assign_reg (cfg, rs, reg, hreg, TRUE);
DEBUG (g_print ("\tassigned arg reg %s to R%d\n", mono_arch_fregname (hreg), reg));
/* To simplify things, we allocate the same regpair to sreg1 and dreg */
if (dest_sreg1 != -1)
g_assert (dest_sreg1 == ins->dreg);
- val = mono_regstate_alloc_int (rs, 1 << ins->dreg);
+ val = mono_regstate_alloc_int (rs, regmask (ins->dreg));
g_assert (val >= 0);
- assign_reg (rs, ins->sreg1, val, fp);
+ assign_reg (cfg, rs, ins->sreg1, val, fp);
DEBUG (g_print ("\tassigned sreg1-low %s to R%d\n", mono_regname_full (val, fp), ins->sreg1));
- g_assert ((1 << dreg_high) & regpair_reg2_mask (spec [MONO_INST_SRC1], ins->dreg));
- val = mono_regstate_alloc_int (rs, 1 << dreg_high);
+ g_assert ((regmask (dreg_high)) & regpair_reg2_mask (spec [MONO_INST_SRC1], ins->dreg));
+ val = mono_regstate_alloc_int (rs, regmask (dreg_high));
g_assert (val >= 0);
- assign_reg (rs, ins->sreg1 + 1, val, fp);
+ assign_reg (cfg, rs, ins->sreg1 + 1, val, fp);
DEBUG (g_print ("\tassigned sreg1-high %s to R%d\n", mono_regname_full (val, fp), ins->sreg1 + 1));
}
if (dest_sreg1 != -1) {
- sreg1_mask = 1 << dest_sreg1;
+ sreg1_mask = regmask (dest_sreg1);
- if (!(rs->ifree_mask & (1 << dest_sreg1))) {
+ if (!(rs->ifree_mask & (regmask (dest_sreg1)))) {
DEBUG (g_print ("\tforced spill of R%d\n", rs->isymbolic [dest_sreg1]));
get_register_force_spilling (cfg, tmp, ins, rs->isymbolic [dest_sreg1], FALSE);
mono_regstate_free_int (rs, dest_sreg1);
}
if (is_global_ireg (ins->sreg1)) {
/* The argument is already in a hard reg, need to copy */
- MonoInst *copy = create_copy_ins (cfg, dest_sreg1, ins->sreg1, NULL, FALSE);
+ MonoInst *copy = create_copy_ins (cfg, dest_sreg1, ins->sreg1, NULL, ip, FALSE);
insert_before_ins (ins, tmp, copy);
ins->sreg1 = dest_sreg1;
}
spill = -val -1;
}
- if (((ins->opcode == OP_MOVE) || (ins->opcode == OP_SETREG)) && !spill && !fp && (!is_global_ireg (ins->dreg) && (rs->ifree_mask & (1 << ins->dreg)))) {
+ if (((ins->opcode == OP_MOVE) || (ins->opcode == OP_SETREG)) && !spill && !fp && (!is_global_ireg (ins->dreg) && (rs->ifree_mask & (regmask (ins->dreg))))) {
/*
* Allocate the same hreg to sreg1 as well so the
* peephole can get rid of the move.
*/
- sreg1_mask = 1 << ins->dreg;
+ sreg1_mask = regmask (ins->dreg);
}
val = alloc_reg (cfg, tmp, ins, sreg1_mask, ins->sreg1, ®info [ins->sreg1], fp);
- assign_reg (rs, ins->sreg1, val, fp);
+ assign_reg (cfg, rs, ins->sreg1, val, fp);
DEBUG (g_print ("\tassigned sreg1 %s to R%d\n", mono_regname_full (val, fp), ins->sreg1));
if (spill) {
else {
prev_sreg1 = -1;
}
- sreg2_mask &= ~(1 << ins->sreg1);
+ sreg2_mask &= ~(regmask (ins->sreg1));
}
/* Handle the case when sreg1 is a regpair but dreg is not */
g_assert_not_reached ();
}
else {
- if (! (mask & (1 << val))) {
+ if (! (mask & (regmask (val)))) {
/* The vreg is already allocated to a wrong hreg */
/* FIXME: */
g_assert_not_reached ();
val = get_register_spilling (cfg, tmp, ins, mask, reg2, fp);
/* Reallocate hreg to the correct register */
- create_copy_ins (cfg, rs->iassign [reg2], val, ins, fp);
+ create_copy_ins (cfg, rs->iassign [reg2], val, ins, ip, fp);
mono_regstate_free_int (rs, rs->iassign [reg2]);
#endif
sreg1_high = val;
DEBUG (g_print ("\tassigned sreg1 hreg %s to dest R%d\n", mono_arch_regname (val), reg2));
- assign_reg (rs, reg2, val, fp);
+ assign_reg (cfg, rs, reg2, val, fp);
}
/* Handle dreg==sreg1 */
int reg2 = alloc_reg (cfg, tmp, ins, dreg_mask, ins->sreg2, NULL, fp);
DEBUG (g_print ("\tneed to copy sreg2 %s to reg %s\n", mono_regname_full (ins->sreg2, fp), mono_regname_full (reg2, fp)));
- sreg2_copy = create_copy_ins (cfg, reg2, ins->sreg2, NULL, fp);
+ sreg2_copy = create_copy_ins (cfg, reg2, ins->sreg2, NULL, ip, fp);
prev_sreg2 = ins->sreg2 = reg2;
if (fp)
}
DEBUG (g_print ("\tneed to copy sreg1 %s to dreg %s\n", mono_regname_full (ins->sreg1, fp), mono_regname_full (ins->dreg, fp)));
- copy = create_copy_ins (cfg, ins->dreg, ins->sreg1, NULL, fp);
+ copy = create_copy_ins (cfg, ins->dreg, ins->sreg1, NULL, ip, fp);
insert_before_ins (ins, tmp, copy);
if (sreg2_copy)
* Need to prevent sreg2 to be allocated to sreg1, since that
* would screw up the previous copy.
*/
- sreg2_mask &= ~ (1 << ins->sreg1);
+ sreg2_mask &= ~ (regmask (ins->sreg1));
/* we set sreg1 to dest as well */
prev_sreg1 = ins->sreg1 = ins->dreg;
- sreg2_mask &= ~ (1 << ins->dreg);
+ sreg2_mask &= ~ (regmask (ins->dreg));
}
/*
spill = -val -1;
}
val = alloc_reg (cfg, tmp, ins, sreg2_mask, ins->sreg2, ®info [ins->sreg2], fp);
- assign_reg (rs, ins->sreg2, val, fp);
+ assign_reg (cfg, rs, ins->sreg2, val, fp);
DEBUG (g_print ("\tassigned sreg2 %s to R%d\n", mono_regname_full (val, fp), ins->sreg2));
if (spill)
create_spilled_store (cfg, spill, val, prev_sreg2, ins, fp);