#include <mono/utils/mono-math.h>
#include "mini-hppa.h"
-#include "inssel.h"
#include "trace.h"
#include "cpu-hppa.h"
mono_arch_cpu_init (void)
{
guint32 dummy;
- mono_arch_cpu_optimizazions(&dummy);
+ mono_arch_cpu_optimizations(&dummy);
}
/*
* This function returns the optimizations supported on this cpu.
*/
guint32
-mono_arch_cpu_optimizazions (guint32 *exclude_mask)
+mono_arch_cpu_optimizations (guint32 *exclude_mask)
{
guint32 opts = 0;
*exclude_mask = 0;
return opts;
}
+/*
+ * This function test for all SIMD functions supported.
+ *
+ * Returns a bitmask corresponding to all supported versions.
+ *
+ */
+guint32
+mono_arch_cpu_enumerate_simd_versions (void)
+{
+ /* SIMD is currently unimplemented */
+ return 0;
+}
+
void
mono_arch_flush_icache (guint8 *code, gint size)
{
case MONO_TYPE_VALUETYPE:
if (type->data.klass->enumtype) {
- type = type->data.klass->enum_basetype;
+ type = mono_class_enum_basetype (type->data.klass);
goto handle_enum;
}
/* Fall through */
DEBUG_FUNC_ENTER();
m->flags |= MONO_CFG_HAS_SPILLUP;
- header = mono_method_get_header (m->method);
+ header = m->header;
sig = mono_method_signature (m->method);
DEBUG (printf ("Allocating locals - incoming params:\n"));
arg->inst_left = in;
arg->inst_call = call;
arg->type = in->type;
- MONO_INST_LIST_ADD_TAIL (&arg->node, &call->out_args);
+
+ /* prepend, we'll need to reverse them later */
+ arg->next = call->out_args;
+ call->out_args = arg;
switch (ainfo->storage) {
case ArgInIReg:
}
}
+ /*
+ * Reverse the call->out_args list.
+ */
+ {
+ MonoInst *prev = NULL, *list = call->out_args, *next;
+ while (list) {
+ next = list->next;
+ list->next = prev;
+ prev = list;
+ list = next;
+ }
+ call->out_args = prev;
+ }
call->stack_usage = cinfo->stack_usage;
cfg->param_area = MAX (cfg->param_area, call->stack_usage);
cfg->param_area = ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT);
return call;
}
-static void
-peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb)
+void
+mono_arch_peephole_pass_1 (MonoCompile *cfg, MonoBasicBlock *bb)
+{
+}
+
+void
+mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb)
{
DEBUG_FUNC_ENTER();
DEBUG_FUNC_EXIT();
}
-#define NEW_INS(cfg,ins,dest,op) do { \
+static void
+insert_after_ins (MonoBasicBlock *bb, MonoInst *ins, MonoInst *to_insert)
+{
+ if (ins == NULL) {
+ ins = bb->code;
+ bb->code = to_insert;
+ to_insert->next = ins;
+ } else {
+ to_insert->next = ins->next;
+ ins->next = to_insert;
+ }
+}
+
+#define NEW_INS(cfg,dest,op) do { \
(dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
(dest)->opcode = (op); \
- MONO_INST_LIST_ADD_TAIL (&(dest)->node, &(ins)->node); \
+ insert_after_ins (bb, last_ins, (dest)); \
} while (0)
static int
* represented with very simple instructions with no register
* requirements.
*/
-static void
+void
mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
{
- MonoInst *ins, *next, *temp, *temp2;
+ MonoInst *ins, *next, *temp, *last_ins = NULL;
int imm;
- /* setup the virtual reg allocator */
- if (bb->max_vreg > cfg->rs->next_vreg)
- cfg->rs->next_vreg = bb->max_vreg;
-
MONO_BB_FOR_EACH_INS (bb, ins) {
loop_start:
switch (ins->opcode) {
case OP_ADD_IMM:
case OP_ADDCC_IMM:
if (!hppa_check_bits (ins->inst_imm, 11)) {
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
- temp->dreg = mono_regstate_next_int (cfg->rs);
+ temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
ins->opcode = map_to_reg_reg_op (ins->opcode);
}
case OP_SUB_IMM:
case OP_SUBCC_IMM:
if (!hppa_check_bits (ins->inst_imm, 11)) {
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
- temp->dreg = mono_regstate_next_int (cfg->rs);
+ temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
ins->opcode = map_to_reg_reg_op (ins->opcode);
}
break;
}
else {
- int tmp = mono_regstate_next_int (cfg->rs);
- NEW_INS (cfg, ins, temp, OP_ICONST);
+ int tmp = mono_alloc_ireg (cfg);
+ NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_c0;
temp->dreg = tmp;
break;
case CEE_MUL: {
- int freg1 = mono_regstate_next_float (cfg->rs);
- int freg2 = mono_regstate_next_float (cfg->rs);
+ int freg1 = mono_alloc_freg (cfg);
+ int freg2 = mono_alloc_freg (cfg);
- NEW_INS(cfg, ins, temp, OP_STORE_MEMBASE_REG);
+ NEW_INS(cfg, temp, OP_STORE_MEMBASE_REG);
temp->sreg1 = ins->sreg1;
temp->inst_destbasereg = hppa_sp;
temp->inst_offset = -16;
- NEW_INS(cfg, temp, temp2, OP_LOADR4_MEMBASE);
- temp2->dreg = freg1;
- temp2->inst_basereg = hppa_sp;
- temp2->inst_offset = -16;
+ NEW_INS(cfg, temp, OP_LOADR4_MEMBASE);
+ temp->dreg = freg1;
+ temp->inst_basereg = hppa_sp;
+ temp->inst_offset = -16;
- NEW_INS(cfg, temp2, temp, OP_STORE_MEMBASE_REG);
+ NEW_INS(cfg, temp, OP_STORE_MEMBASE_REG);
temp->sreg1 = ins->sreg2;
temp->inst_destbasereg = hppa_sp;
temp->inst_offset = -16;
- NEW_INS(cfg, temp, temp2, OP_LOADR4_MEMBASE);
- temp2->dreg = freg2;
- temp2->inst_basereg = hppa_sp;
- temp2->inst_offset = -16;
+ NEW_INS(cfg, temp, OP_LOADR4_MEMBASE);
+ temp->dreg = freg2;
+ temp->inst_basereg = hppa_sp;
+ temp->inst_offset = -16;
- NEW_INS (cfg, temp2, temp, OP_HPPA_XMPYU);
+ NEW_INS (cfg, temp, OP_HPPA_XMPYU);
temp->dreg = freg2;
temp->sreg1 = freg1;
temp->sreg2 = freg2;
- NEW_INS(cfg, temp, temp2, OP_HPPA_STORER4_RIGHT);
- temp2->sreg1 = freg2;
- temp2->inst_destbasereg = hppa_sp;
- temp2->inst_offset = -16;
+ NEW_INS(cfg, temp, OP_HPPA_STORER4_RIGHT);
+ temp->sreg1 = freg2;
+ temp->inst_destbasereg = hppa_sp;
+ temp->inst_offset = -16;
ins->opcode = OP_LOAD_MEMBASE;
ins->inst_basereg = hppa_sp;
default:
break;
}
+ last_ins = ins;
}
- bb->max_vreg = cfg->rs->next_vreg;
+ bb->last_ins = last_ins;
+ bb->max_vreg = cfg->next_vreg;
}
-void
-mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
-{
- DEBUG_FUNC_ENTER();
- if (MONO_INST_LIST_EMPTY (&bb->ins_list))
- return;
- mono_arch_lowering_pass (cfg, bb);
- mono_local_regalloc (cfg, bb);
- DEBUG_FUNC_EXIT();
-}
-
void
hppa_patch (guint32 *code, const gpointer target)
{
* Determine the vtable slot used by a virtual call.
*/
gpointer*
-mono_arch_get_vcall_slot_addr (guint8 *code8, gpointer *regs)
+mono_arch_get_vcall_slot_addr (guint8 *code8, mgreg_t *regs)
{
guint32 *code = (guint32*)((unsigned long)code8 & ~3);
} while (0)
#define EMIT_COND_BRANCH_FLAGS(ins,r1,r2,b0,b1) do {\
- if (ins->flags & MONO_INST_BRLABEL) { \
- mono_add_patch_info (cfg, (guint8*)code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0); \
- if (b0) \
- hppa_combt (code, r1, r2, b1, 0); \
- else \
- hppa_combf (code, r1, r2, b1, 0); \
- } else { \
- if (b0) \
- hppa_combf (code, r1, r2, b1, 2); \
- else \
- hppa_combt (code, r1, r2, b1, 2); \
- hppa_nop (code); \
- mono_add_patch_info (cfg, (guint8*)code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb); \
- hppa_bl (code, 0, hppa_r0); \
- } \
+ if (b0) \
+ hppa_combf (code, r1, r2, b1, 2); \
+ else \
+ hppa_combt (code, r1, r2, b1, 2); \
+ hppa_nop (code); \
+ mono_add_patch_info (cfg, (guint8*)code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb); \
+ hppa_bl (code, 0, hppa_r0); \
hppa_nop (code); \
} while (0)
#define EMIT_FLOAT_COND_BRANCH_FLAGS(ins,r1,r2,b0) do {\
hppa_fcmp (code, HPPA_FP_FMT_DBL, b0, r1, r2); \
hppa_ftest (code, 0); \
- if (ins->flags & MONO_INST_BRLABEL) \
- mono_add_patch_info (cfg, (guint8*)code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0); \
- else \
- mono_add_patch_info (cfg, (guint8*)code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb); \
+ mono_add_patch_info (cfg, (guint8*)code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb); \
hppa_bl (code, 8, hppa_r0); \
hppa_nop (code); \
} while (0)
MonoCallInst *call;
guint offset;
guint32 *code = (guint32*)(cfg->native_code + cfg->code_len);
+ MonoInst *last_ins = NULL;
int max_len, cpos;
const char *spec;
DEBUG_FUNC_ENTER();
- if (cfg->opt & MONO_OPT_PEEPHOLE)
- peephole_pass (cfg, bb);
if (cfg->verbose_level > 2)
g_print ("[%s::%s] Basic block %d starting at offset 0x%x\n", cfg->method->klass->name, cfg->method->name, bb->block_num, bb->native_offset);
cfg->code_size *= 2;
cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
code = (guint32*)(cfg->native_code + offset);
- mono_jit_stats.code_reallocs++;
+ cfg->stat_code_reallocs++;
}
code_start = (guint8*)code;
// if (ins->cil_code)
mono_debug_record_line_number (cfg, ins, offset);
switch (ins->opcode) {
+ case OP_RELAXED_NOP:
+ break;
case OP_STOREI1_MEMBASE_IMM:
EMIT_STORE_MEMBASE_IMM (ins, stb);
break;
break;
case OP_BR: {
guint32 target;
- if (ins->flags & MONO_INST_BRLABEL) {
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_LABEL, ins->inst_i0);
- } else {
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_target_bb);
- }
+ DEBUG (printf ("target: %p, next: %p, curr: %p, last: %p\n", ins->inst_target_bb, bb->next_bb, ins, bb->last_ins));
+ mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_target_bb);
hppa_bl (code, 8, hppa_r0);
/* TODO: if the branch is too long, we may need to
* use a long-branch sequence:
}
cpos += max_len;
+
+ last_ins = ins;
}
cfg->code_len = (guint8*)code - cfg->native_code;
}
void
-mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors)
+mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors)
{
MonoJumpInfo *patch_info;
};
void*
-mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments)
+mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers)
{
guint32 *code = (guint32*)p;
DEBUG_FUNC_ENTER();
*/
max_offset = 0;
for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
- MonoInst *ins;
+ MonoInst *ins = bb->code;
bb->max_offset = max_offset;
if (cfg->prof_options & MONO_PROFILE_COVERAGE)
max_offset += 6;
- MONO_BB_FOR_EACH_INS (bb, ins) {
+ MONO_BB_FOR_EACH_INS (bb, ins)
max_offset += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
}
while (cfg->code_len + max_epilog_size > (cfg->code_size - 16)) {
cfg->code_size *= 2;
cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- mono_jit_stats.code_reallocs++;
+ cfg->stat_code_reallocs++;
}
code = (guint32*)(cfg->native_code + cfg->code_len);
while (cfg->code_len + max_epilog_size > (cfg->code_size - 16)) {
cfg->code_size *= 2;
cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- mono_jit_stats.code_reallocs++;
+ cfg->stat_code_reallocs++;
}
code = cfg->native_code + cfg->code_len;
#endif
void
-mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
+mono_arch_finish_init (void)
{
}
MONO_INST_NEW (cfg, this, OP_MOVE);
this->type = this_type;
this->sreg1 = this_reg;
- this->dreg = mono_regstate_next_int (cfg->rs);
+ this->dreg = mono_alloc_ireg (cfg);
mono_bblock_add_inst (cfg->cbb, this);
mono_call_inst_add_outarg_reg (cfg, inst, this->dreg, hppa_r26, FALSE);
}
MONO_INST_NEW (cfg, vtarg, OP_MOVE);
vtarg->type = STACK_MP;
vtarg->sreg1 = vt_reg;
- vtarg->dreg = mono_regstate_next_int (cfg->rs);
+ vtarg->dreg = mono_alloc_ireg (cfg);
mono_bblock_add_inst (cfg->cbb, vtarg);
mono_call_inst_add_outarg_reg (cfg, inst, vtarg->dreg, hppa_r28, FALSE);
}
DEBUG_FUNC_ENTER();
DEBUG_FUNC_EXIT();
-#if 0
- if (cmethod->klass == mono_defaults.thread_class &&
- strcmp (cmethod->name, "MemoryBarrier") == 0) {
- if (sparcv9)
- MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER);
- }
-#endif
-
return ins;
}
return NULL;
}
-MonoInst* mono_arch_get_thread_intrinsic (MonoCompile* cfg)
+gpointer
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
{
- return NULL;
+ /* FIXME: implement */
+ g_assert_not_reached ();
}