X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-ia64.c;h=e59aac9bcb7a652e989dec623b56e1c6c8b9ec5b;hb=dba1e96418a00b863db3565d5997314105bd8aa3;hp=9adc39ff41251813853d74523fbd84280d23f9fa;hpb=e0316978fe0bef61b2dbe79469c8e3ddfb3828cb;p=mono.git diff --git a/mono/mini/mini-ia64.c b/mono/mini/mini-ia64.c index 9adc39ff412..e59aac9bcb7 100644 --- a/mono/mini/mini-ia64.c +++ b/mono/mini/mini-ia64.c @@ -30,9 +30,6 @@ static gint appdomain_tls_offset = -1; static gint thread_tls_offset = -1; -const char * const ia64_desc [OP_LAST]; -static const char*const * ins_spec = ia64_desc; - #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) #define IS_IMM32(val) ((((guint64)val) >> 32) == 0) @@ -59,6 +56,7 @@ static const char*const * ins_spec = ia64_desc; #define GP_SCRATCH_REG 31 #define GP_SCRATCH_REG2 30 #define FP_SCRATCH_REG 32 +#define FP_SCRATCH_REG2 33 #define LOOP_ALIGNMENT 8 #define bb_is_loop_start(bb) ((bb)->loop_body_start && (bb)->nesting) @@ -584,40 +582,6 @@ mono_arch_break (void) { } -static gboolean -is_regsize_var (MonoType *t) { - if (t->byref) - return TRUE; - t = mono_type_get_underlying_type (t); - switch (t->type) { - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_FNPTR: - case MONO_TYPE_BOOLEAN: - return TRUE; - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - return TRUE; - case MONO_TYPE_GENERICINST: - if (!mono_type_generic_inst_is_valuetype (t)) - return TRUE; - return FALSE; - case MONO_TYPE_VALUETYPE: - return FALSE; - } - return FALSE; -} - GList * mono_arch_get_allocatable_int_vars (MonoCompile *cfg) { @@ -634,7 +598,7 @@ mono_arch_get_allocatable_int_vars (MonoCompile *cfg) cinfo = get_call_info (sig, FALSE); for (i = 0; i < sig->param_count + sig->hasthis; ++i) { - MonoInst *ins = cfg->varinfo [i]; + MonoInst *ins = cfg->args [i]; ArgInfo *ainfo = &cinfo->args [i]; @@ -660,7 +624,7 @@ mono_arch_get_allocatable_int_vars (MonoCompile *cfg) (ins->opcode != OP_LOCAL && ins->opcode != OP_ARG)) continue; - if (is_regsize_var (ins->inst_vtype)) { + if (mono_is_regsize_var (ins->inst_vtype)) { g_assert (MONO_VARINFO (cfg, i)->reg == -1); g_assert (i == vmv->idx); vars = g_list_prepend (vars, vmv); @@ -722,7 +686,7 @@ mono_ia64_alloc_stacked_registers (MonoCompile *cfg) } /* - * Need to allocate at least 2 out register for use by CEE_THROW / the system + * Need to allocate at least 2 out register for use by OP_THROW / the system * exception throwing code. */ cfg->arch.n_out_regs = MAX (cfg->arch.n_out_regs, 2); @@ -874,7 +838,6 @@ mono_arch_allocate_vars (MonoCompile *cfg) // printf ("allocated local %d to ", i); mono_print_tree_nl (inst); } } - g_free (offsets); offset += locals_stack_size; if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG)) { @@ -885,7 +848,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) } for (i = 0; i < sig->param_count + sig->hasthis; ++i) { - inst = cfg->varinfo [i]; + inst = cfg->args [i]; if (inst->opcode != OP_REGVAR) { ArgInfo *ainfo = &cinfo->args [i]; gboolean inreg = TRUE; @@ -984,14 +947,14 @@ add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, MonoInst *arg, ArgStorage arg->opcode = OP_OUTARG_REG; arg->inst_left = tree; arg->inst_right = (MonoInst*)call; - arg->unused = reg; + arg->backend.reg3 = reg; call->used_iregs |= 1 << reg; break; case ArgInFloatReg: arg->opcode = OP_OUTARG_FREG; arg->inst_left = tree; arg->inst_right = (MonoInst*)call; - arg->unused = reg; + arg->backend.reg3 = reg; call->used_fregs |= 1 << reg; break; default: @@ -999,12 +962,47 @@ add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, MonoInst *arg, ArgStorage } } +static void +emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) +{ + MonoInst *arg; + MonoMethodSignature *tmp_sig; + MonoInst *sig_arg; + + /* FIXME: Add support for signature tokens to AOT */ + cfg->disable_aot = TRUE; + + g_assert (cinfo->sig_cookie.storage == ArgOnStack); + + /* + * mono_ArgIterator_Setup assumes the signature cookie is + * passed first and all the arguments which were before it are + * passed on the stack after the signature. So compensate by + * passing a different signature. + */ + tmp_sig = mono_metadata_signature_dup (call->signature); + tmp_sig->param_count -= call->signature->sentinelpos; + tmp_sig->sentinelpos = 0; + memcpy (tmp_sig->params, call->signature->params + call->signature->sentinelpos, tmp_sig->param_count * sizeof (MonoType*)); + + MONO_INST_NEW (cfg, sig_arg, OP_ICONST); + sig_arg->inst_p0 = tmp_sig; + + MONO_INST_NEW (cfg, arg, OP_OUTARG); + arg->inst_left = sig_arg; + arg->inst_imm = 16 + cinfo->sig_cookie.offset; + arg->type = STACK_PTR; + + /* prepend, so they get reversed */ + arg->next = call->out_args; + call->out_args = arg; +} + /* * take the arguments and generate the arch-specific * instructions to properly call the function in call. * This includes pushing, moving arguments to the right register * etc. - * Issue: who does the spilling if needed, and when? */ MonoCallInst* mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, int is_virtual) @@ -1034,37 +1032,8 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, ainfo = cinfo->args + i; if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (i == sig->sentinelpos)) { - MonoMethodSignature *tmp_sig; - /* Emit the signature cookie just before the implicit arguments */ - MonoInst *sig_arg; - /* FIXME: Add support for signature tokens to AOT */ - cfg->disable_aot = TRUE; - - g_assert (cinfo->sig_cookie.storage == ArgOnStack); - - /* - * mono_ArgIterator_Setup assumes the signature cookie is - * passed first and all the arguments which were before it are - * passed on the stack after the signature. So compensate by - * passing a different signature. - */ - tmp_sig = mono_metadata_signature_dup (call->signature); - tmp_sig->param_count -= call->signature->sentinelpos; - tmp_sig->sentinelpos = 0; - memcpy (tmp_sig->params, call->signature->params + call->signature->sentinelpos, tmp_sig->param_count * sizeof (MonoType*)); - - MONO_INST_NEW (cfg, sig_arg, OP_ICONST); - sig_arg->inst_p0 = tmp_sig; - - MONO_INST_NEW (cfg, arg, OP_OUTARG); - arg->inst_left = sig_arg; - arg->inst_imm = 16 + cinfo->sig_cookie.offset; - arg->type = STACK_PTR; - - /* prepend, so they get reversed */ - arg->next = call->out_args; - call->out_args = arg; + emit_sig_cookie (cfg, call, cinfo); } if (is_virtual && i == 0) { @@ -1111,32 +1080,32 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, if (ainfo->storage == ArgAggregate) { MonoInst *vtaddr, *load, *load2, *offset_ins, *set_reg; - int slot; + int slot, j; vtaddr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL); /* * Part of the structure is passed in registers. */ - for (i = 0; i < ainfo->nregs; ++i) { + for (j = 0; j < ainfo->nregs; ++j) { int offset, load_op, dest_reg, arg_storage; - slot = ainfo->reg + i; + slot = ainfo->reg + j; if (ainfo->atype == AggregateSingleHFA) { load_op = CEE_LDIND_R4; - offset = i * 4; - dest_reg = ainfo->reg + i; + offset = j * 4; + dest_reg = ainfo->reg + j; arg_storage = ArgInFloatReg; } else if (ainfo->atype == AggregateDoubleHFA) { load_op = CEE_LDIND_R8; - offset = i * 8; - dest_reg = ainfo->reg + i; + offset = j * 8; + dest_reg = ainfo->reg + j; arg_storage = ArgInFloatReg; } else { load_op = CEE_LDIND_I; - offset = i * 8; - dest_reg = cfg->arch.reg_out0 + ainfo->reg + i; + offset = j * 8; + dest_reg = cfg->arch.reg_out0 + ainfo->reg + j; arg_storage = ArgInIReg; } @@ -1152,7 +1121,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, MONO_INST_NEW (cfg, load, load_op); load->inst_left = load2; - if (i == 0) + if (j == 0) set_reg = arg; else MONO_INST_NEW (cfg, set_reg, OP_OUTARG_REG); @@ -1166,16 +1135,16 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, /* * Part of the structure is passed on the stack. */ - for (i = ainfo->nregs; i < ainfo->nslots; ++i) { + for (j = ainfo->nregs; j < ainfo->nslots; ++j) { MonoInst *outarg; - slot = ainfo->reg + i; + slot = ainfo->reg + j; MONO_INST_NEW (cfg, load, CEE_LDIND_I); load->ssa_op = MONO_SSA_LOAD; load->inst_i0 = (cfg)->varinfo [vtaddr->inst_c0]; - NEW_ICONST (cfg, offset_ins, (i * sizeof (gpointer))); + NEW_ICONST (cfg, offset_ins, (j * sizeof (gpointer))); MONO_INST_NEW (cfg, load2, CEE_ADD); load2->inst_left = load; load2->inst_right = offset_ins; @@ -1183,7 +1152,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, MONO_INST_NEW (cfg, load, CEE_LDIND_I); load->inst_left = load2; - if (i == 0) + if (j == 0) outarg = arg; else MONO_INST_NEW (cfg, outarg, OP_OUTARG); @@ -1241,6 +1210,11 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, } } + /* Handle the case where there are no implicit arguments */ + if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sig->sentinelpos)) { + emit_sig_cookie (cfg, call, cinfo); + } + call->stack_usage = cinfo->stack_usage; cfg->param_area = MAX (cfg->param_area, call->stack_usage); cfg->arch.n_out_regs = MAX (cfg->arch.n_out_regs, cinfo->reg_usage); @@ -1261,7 +1235,6 @@ peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb) switch (ins->opcode) { case OP_MOVE: case OP_FMOVE: - case OP_SETREG: /* * Removes: * @@ -1308,127 +1281,6 @@ peephole_pass (MonoCompile *cfg, MonoBasicBlock *bb) bb->last_ins = last_ins; } -typedef enum { - CMP_EQ, - CMP_NE, - CMP_LE, - CMP_GE, - CMP_LT, - CMP_GT, - CMP_LE_UN, - CMP_GE_UN, - CMP_LT_UN, - CMP_GT_UN -} CompRelation; - -typedef enum { - CMP_TYPE_L, - CMP_TYPE_I, - CMP_TYPE_F -} CompType; - -static CompRelation -opcode_to_cond (int opcode) -{ - switch (opcode) { - case CEE_BEQ: - case OP_CEQ: - case OP_IBEQ: - case OP_ICEQ: - case OP_FBEQ: - case OP_FCEQ: - case OP_COND_EXC_EQ: - return CMP_EQ; - case CEE_BNE_UN: - case OP_COND_EXC_NE_UN: - case OP_IBNE_UN: - case OP_FBNE_UN: - return CMP_NE; - case CEE_BLE: - case OP_IBLE: - case OP_FBLE: - return CMP_LE; - case CEE_BGE: - case OP_IBGE: - case OP_FBGE: - return CMP_GE; - case CEE_BLT: - case OP_COND_EXC_LT: - case OP_CLT: - case OP_IBLT: - case OP_ICLT: - case OP_FBLT: - case OP_FCLT: - return CMP_LT; - case CEE_BGT: - case OP_COND_EXC_GT: - case OP_CGT: - case OP_IBGT: - case OP_ICGT: - case OP_FBGT: - case OP_FCGT: - return CMP_GT; - - case CEE_BLE_UN: - case OP_COND_EXC_LE_UN: - case OP_IBLE_UN: - case OP_FBLE_UN: - return CMP_LE_UN; - case CEE_BGE_UN: - case OP_IBGE_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_FBLT_UN: - case OP_FCLT_UN: - case OP_COND_EXC_LT_UN: - return CMP_LT_UN; - case CEE_BGT_UN: - case OP_COND_EXC_GT_UN: - case OP_CGT_UN: - case OP_IBGT_UN: - case OP_ICGT_UN: - case OP_FCGT_UN: - case OP_FBGT_UN: - return CMP_GT_UN; - default: - printf ("%s\n", mono_inst_name (opcode)); - NOT_IMPLEMENTED; - } -} - -static CompType -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_IBLE_UN)) - return CMP_TYPE_I; - else if ((opcode >= OP_ICEQ) && (opcode <= OP_ICLT_UN)) - return CMP_TYPE_I; - else if ((opcode >= OP_FBEQ) && (opcode <= OP_FBLE_UN)) - return CMP_TYPE_F; - else if ((opcode >= OP_FCEQ) && (opcode <= OP_FCLT_UN)) - return CMP_TYPE_F; - 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; - } -} - int cond_to_ia64_cmp [][3] = { {OP_IA64_CMP_EQ, OP_IA64_CMP4_EQ, OP_IA64_FCMP_EQ}, {OP_IA64_CMP_NE, OP_IA64_CMP4_NE, OP_IA64_FCMP_NE}, @@ -1445,7 +1297,7 @@ int cond_to_ia64_cmp [][3] = { static int opcode_to_ia64_cmp (int opcode, int cmp_opcode) { - return cond_to_ia64_cmp [opcode_to_cond (opcode)][opcode_to_type (opcode, cmp_opcode)]; + return cond_to_ia64_cmp [mono_opcode_to_cond (opcode)][mono_opcode_to_type (opcode, cmp_opcode)]; } int cond_to_ia64_cmp_imm [][3] = { @@ -1465,7 +1317,7 @@ static int opcode_to_ia64_cmp_imm (int opcode, int cmp_opcode) { /* The condition needs to be reversed */ - return cond_to_ia64_cmp_imm [opcode_to_cond (opcode)][opcode_to_type (opcode, cmp_opcode)]; + return cond_to_ia64_cmp_imm [mono_opcode_to_cond (opcode)][mono_opcode_to_type (opcode, cmp_opcode)]; } static void @@ -1501,10 +1353,8 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) MonoInst *ins, *next, *temp, *temp2, *temp3, *last_ins = NULL; ins = bb->code; - if (bb->max_ireg > cfg->rs->next_vireg) - cfg->rs->next_vireg = bb->max_ireg; - if (bb->max_freg > cfg->rs->next_vfreg) - cfg->rs->next_vfreg = bb->max_freg; + if (bb->max_vreg > cfg->rs->next_vreg) + cfg->rs->next_vreg = bb->max_vreg; while (ins) { switch (ins->opcode) { @@ -1514,7 +1364,9 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_STOREI8_MEMBASE_IMM: case OP_STORE_MEMBASE_IMM: /* There are no store_membase instructions on ia64 */ - if (ia64_is_imm14 (ins->inst_offset)) { + if (ins->inst_offset == 0) { + temp2 = NULL; + } else if (ia64_is_imm14 (ins->inst_offset)) { NEW_INS (cfg, temp2, OP_ADD_IMM); temp2->sreg1 = ins->inst_destbasereg; temp2->inst_imm = ins->inst_offset; @@ -1558,7 +1410,8 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) } ins->inst_offset = 0; - ins->inst_destbasereg = temp2->dreg; + if (temp2) + ins->inst_destbasereg = temp2->dreg; break; case OP_STOREI1_MEMBASE_REG: case OP_STOREI2_MEMBASE_REG: @@ -1600,37 +1453,17 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_LOAD_MEMBASE: case OP_LOADR4_MEMBASE: case OP_LOADR8_MEMBASE: - /* There are no load_membase instructions on ia64 */ - if (ins->inst_offset == 0) { - break; - } - else if (ia64_is_imm14 (ins->inst_offset)) { - NEW_INS (cfg, temp2, OP_ADD_IMM); - temp2->sreg1 = ins->inst_basereg; - temp2->inst_imm = ins->inst_offset; - temp2->dreg = mono_regstate_next_int (cfg->rs); - } - else { - NEW_INS (cfg, temp, OP_I8CONST); - temp->inst_c0 = ins->inst_offset; - temp->dreg = mono_regstate_next_int (cfg->rs); - NEW_INS (cfg, temp2, CEE_ADD); - temp2->sreg1 = ins->inst_basereg; - temp2->sreg2 = temp->dreg; - temp2->dreg = mono_regstate_next_int (cfg->rs); - } - - ins->inst_offset = 0; - ins->inst_basereg = temp2->dreg; - break; - case OP_IA64_FETCHADD4_IMM: - case OP_IA64_FETCHADD8_IMM: case OP_ATOMIC_EXCHANGE_I4: case OP_ATOMIC_EXCHANGE_I8: case OP_ATOMIC_ADD_NEW_I4: case OP_ATOMIC_ADD_NEW_I8: + case OP_ATOMIC_ADD_IMM_NEW_I4: + case OP_ATOMIC_ADD_IMM_NEW_I8: /* There are no membase instructions on ia64 */ - if (ia64_is_imm14 (ins->inst_offset)) { + if (ins->inst_offset == 0) { + break; + } + else if (ia64_is_imm14 (ins->inst_offset)) { NEW_INS (cfg, temp2, OP_ADD_IMM); temp2->sreg1 = ins->inst_basereg; temp2->inst_imm = ins->inst_offset; @@ -1645,6 +1478,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp2->sreg2 = temp->dreg; temp2->dreg = mono_regstate_next_int (cfg->rs); } + ins->inst_offset = 0; ins->inst_basereg = temp2->dreg; break; @@ -1656,6 +1490,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_IXOR_IMM: case OP_AND_IMM: case OP_SHL_IMM: + case OP_SHR_IMM: case OP_ISHL_IMM: case OP_LSHL_IMM: case OP_ISHR_IMM: @@ -1693,6 +1528,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) switched = TRUE; break; case OP_SHL_IMM: + case OP_SHR_IMM: case OP_ISHL_IMM: case OP_LSHL_IMM: case OP_ISHR_IMM: @@ -1745,6 +1581,9 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_SHL_IMM: ins->opcode = OP_LSHL; break; + case OP_SHR_IMM: + ins->opcode = OP_LSHR; + break; case OP_LSHL_IMM: ins->opcode = OP_LSHL; break; @@ -1772,30 +1611,20 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_ICOMPARE_IMM: { /* Instead of compare+b, ia64 has compare+br */ gboolean imm; + CompRelation cond; /* * The compare_imm instructions have switched up arguments, and * some of them take an imm between -127 and 128. */ next = ins->next; - switch (next->opcode) { - case CEE_BGE: - case CEE_BLT: - case OP_COND_EXC_LT: - case OP_IBGE: - case OP_IBLT: + cond = mono_opcode_to_cond (next->opcode); + if ((cond == CMP_LT) || (cond == CMP_GE)) imm = ia64_is_imm8 (ins->inst_imm - 1); - break; - case OP_IBGE_UN: - case OP_IBLT_UN: - case CEE_BGE_UN: - case CEE_BLT_UN: + else if ((cond == CMP_LT_UN) || (cond == CMP_GE_UN)) imm = ia64_is_imm8 (ins->inst_imm - 1) && (ins->inst_imm > 0); - break; - default: + else imm = ia64_is_imm8 (ins->inst_imm); - break; - } if (imm) { ins->opcode = opcode_to_ia64_cmp_imm (next->opcode, ins->opcode); @@ -2048,8 +1877,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) } bb->last_ins = last_ins; - bb->max_ireg = cfg->rs->next_vireg; - bb->max_freg = cfg->rs->next_vfreg; + bb->max_vreg = cfg->rs->next_vreg; } void @@ -2089,7 +1917,7 @@ emit_load_volatile_arguments (MonoCompile *cfg, Ia64CodegenState code) ArgInfo *ainfo = cinfo->args + i; gint32 stack_offset; MonoType *arg_type; - ins = cfg->varinfo [i]; + ins = cfg->args [i]; if (sig->hasthis && (i == 0)) arg_type = &mono_defaults.object_class->byval_arg; @@ -2302,7 +2130,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) while (ins) { offset = code.buf - cfg->native_code; - max_len = ((int)(((guint8 *)ins_spec [ins->opcode])[MONO_INST_LEN])) + 128; + max_len = ((int)(((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN])) + 128; while (offset + max_len + 16 > cfg->code_size) { ia64_codegen_close (code); @@ -2330,7 +2158,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_MOVE: ia64_mov (code, ins->dreg, ins->sreg1); break; - case CEE_BR: + case OP_BR: case OP_IA64_BR_COND: { int pred = 0; if (ins->opcode == OP_IA64_BR_COND) @@ -2360,7 +2188,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ia64_begin_bundle (code); ins->inst_c0 = code.buf - cfg->native_code; break; - case CEE_NOP: + case OP_NOP: break; case OP_BR_REG: ia64_mov_to_br (code, IA64_B6, ins->sreg1); @@ -2496,10 +2324,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_LSHL_IMM: ia64_shl_imm (code, ins->dreg, ins->sreg1, ins->inst_imm); break; - case OP_LSHR_IMM: - ia64_shr_imm (code, ins->dreg, ins->sreg1, ins->inst_imm); - break; + case OP_SHR_IMM: case OP_ISHR_IMM: + case OP_LSHR_IMM: ia64_shr_imm (code, ins->dreg, ins->sreg1, ins->inst_imm); break; case OP_ISHR_UN_IMM: @@ -2509,6 +2336,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_LSHR_UN_IMM: ia64_shr_u_imm (code, ins->dreg, ins->sreg1, ins->inst_imm); break; + case CEE_MUL: + /* Based on gcc code */ + ia64_setf_sig (code, FP_SCRATCH_REG, ins->sreg1); + ia64_setf_sig (code, FP_SCRATCH_REG2, ins->sreg2); + ia64_xmpy_l (code, FP_SCRATCH_REG, FP_SCRATCH_REG, FP_SCRATCH_REG2); + ia64_getf_sig (code, ins->dreg, FP_SCRATCH_REG); + break; case OP_STOREI1_MEMBASE_REG: ia64_st1_hint (code, ins->inst_destbasereg, ins->sreg1, 0); @@ -2793,8 +2627,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; case CEE_CONV_I8: case CEE_CONV_I: - /* FIXME: Sign extend ? */ - ia64_mov (code, ins->dreg, ins->sreg1); + ia64_sxt4 (code, ins->dreg, ins->sreg1); break; case CEE_CONV_U8: case CEE_CONV_U: @@ -2890,7 +2723,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_FNEG: ia64_fmerge_ns (code, ins->dreg, ins->sreg1, ins->sreg1); break; - case CEE_CKFINITE: + case OP_CKFINITE: /* Quiet NaN */ ia64_fclass_m (code, 6, 7, ins->sreg1, 0x080); emit_cond_system_exception (cfg, code, "ArithmeticException", 6); @@ -2987,7 +2820,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) code = emit_move_return_value (cfg, ins, code); break; - case CEE_JMP: { + case OP_JMP: { /* * Keep in sync with the code in emit_epilog. */ @@ -3022,7 +2855,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; } - case CEE_BREAK: + case OP_BREAK: code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, mono_arch_break); break; @@ -3032,8 +2865,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* FIXME: Sigaltstack support */ /* keep alignment */ - ia64_adds_imm (code, GP_SCRATCH_REG, MONO_ARCH_FRAME_ALIGNMENT - 1, ins->sreg1); - ia64_movl (code, GP_SCRATCH_REG2, ~(MONO_ARCH_FRAME_ALIGNMENT - 1)); + ia64_adds_imm (code, GP_SCRATCH_REG, MONO_ARCH_LOCALLOC_ALIGNMENT - 1, ins->sreg1); + ia64_movl (code, GP_SCRATCH_REG2, ~(MONO_ARCH_LOCALLOC_ALIGNMENT - 1)); ia64_and (code, GP_SCRATCH_REG, GP_SCRATCH_REG, GP_SCRATCH_REG2); ia64_sub (code, IA64_SP, IA64_SP, GP_SCRATCH_REG); @@ -3041,7 +2874,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ia64_mov (code, ins->dreg, IA64_SP); /* An area at sp is reserved by the ABI for parameter passing */ - abi_offset = - ALIGN_TO (cfg->param_area + 16, MONO_ARCH_FRAME_ALIGNMENT); + abi_offset = - ALIGN_TO (cfg->param_area + 16, MONO_ARCH_LOCALLOC_ALIGNMENT); if (ia64_is_adds_imm (abi_offset)) ia64_adds_imm (code, IA64_SP, abi_offset, IA64_SP); else { @@ -3076,12 +2909,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_MEMORY_BARRIER: ia64_mf (code); break; - case OP_IA64_FETCHADD4_IMM: + case OP_ATOMIC_ADD_IMM_NEW_I4: g_assert (ins->inst_offset == 0); ia64_fetchadd4_acq_hint (code, ins->dreg, ins->inst_basereg, ins->inst_imm, 0); ia64_adds_imm (code, ins->dreg, ins->inst_imm, ins->dreg); break; - case OP_IA64_FETCHADD8_IMM: + case OP_ATOMIC_ADD_IMM_NEW_I8: g_assert (ins->inst_offset == 0); ia64_fetchadd8_acq_hint (code, ins->dreg, ins->inst_basereg, ins->inst_imm, 0); ia64_adds_imm (code, ins->dreg, ins->inst_imm, ins->dreg); @@ -3192,7 +3025,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; } - case CEE_ENDFINALLY: + case OP_ENDFINALLY: case OP_ENDFILTER: { /* FIXME: Return the value in ENDFILTER */ MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region); @@ -3216,7 +3049,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ia64_br_cond_reg (code, IA64_B6); break; } - case CEE_THROW: + case OP_THROW: ia64_mov (code, cfg->arch.reg_out0, ins->sreg1); code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_arch_throw_exception"); @@ -4035,7 +3868,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) ArgInfo *ainfo = cinfo->args + i; gint32 stack_offset; MonoType *arg_type; - inst = cfg->varinfo [i]; + inst = cfg->args [i]; if (sig->hasthis && (i == 0)) arg_type = &mono_defaults.object_class->byval_arg; @@ -4051,9 +3884,13 @@ mono_arch_emit_prolog (MonoCompile *cfg) switch (ainfo->storage) { case ArgInIReg: case ArgInFloatReg: - /* FIXME: big offsets */ g_assert (inst->opcode == OP_REGOFFSET); - ia64_adds_imm (code, GP_SCRATCH_REG, inst->inst_offset, inst->inst_basereg); + if (ia64_is_adds_imm (inst->inst_offset)) + ia64_adds_imm (code, GP_SCRATCH_REG, inst->inst_offset, inst->inst_basereg); + else { + ia64_movl (code, GP_SCRATCH_REG2, inst->inst_offset); + ia64_add (code, GP_SCRATCH_REG, GP_SCRATCH_REG, GP_SCRATCH_REG2); + } if (arg_type->byref) ia64_st8_hint (code, GP_SCRATCH_REG, cfg->arch.reg_in0 + ainfo->reg, 0); else { @@ -4167,7 +4004,7 @@ mono_arch_emit_epilog (MonoCompile *cfg) ia64_codegen_init (code, buf); - /* the code restoring the registers must be kept in sync with CEE_JMP */ + /* the code restoring the registers must be kept in sync with OP_JMP */ pos = 0; if (method->save_lmf) { @@ -4422,7 +4259,7 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, gboolean ena /* Save arguments to the stack */ for (i = 0; i < n; ++i) { - ins = cfg->varinfo [i]; + ins = cfg->args [i]; if (ins->opcode == OP_REGVAR) { ia64_movl (code, GP_SCRATCH_REG, (i * 8)); @@ -4768,38 +4605,29 @@ mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethod (strcmp (cmethod->klass->name, "Interlocked") == 0)) { if (strcmp (cmethod->name, "Increment") == 0) { - MonoInst *ins_iconst; guint32 opcode; if (fsig->params [0]->type == MONO_TYPE_I4) - opcode = OP_ATOMIC_ADD_NEW_I4; + opcode = OP_ATOMIC_ADD_IMM_NEW_I4; else if (fsig->params [0]->type == MONO_TYPE_I8) - opcode = OP_ATOMIC_ADD_NEW_I8; + opcode = OP_ATOMIC_ADD_IMM_NEW_I8; else g_assert_not_reached (); MONO_INST_NEW (cfg, ins, opcode); - MONO_INST_NEW (cfg, ins_iconst, OP_ICONST); - ins_iconst->inst_imm = 1; - + ins->inst_imm = 1; ins->inst_i0 = args [0]; - ins->inst_i1 = ins_iconst; } else if (strcmp (cmethod->name, "Decrement") == 0) { - MonoInst *ins_iconst; guint32 opcode; if (fsig->params [0]->type == MONO_TYPE_I4) - opcode = OP_ATOMIC_ADD_NEW_I4; + opcode = OP_ATOMIC_ADD_IMM_NEW_I4; else if (fsig->params [0]->type == MONO_TYPE_I8) - opcode = OP_ATOMIC_ADD_NEW_I8; + opcode = OP_ATOMIC_ADD_IMM_NEW_I8; else g_assert_not_reached (); MONO_INST_NEW (cfg, ins, opcode); - MONO_INST_NEW (cfg, ins_iconst, OP_ICONST); - ins_iconst->inst_imm = -1; - + ins->inst_imm = -1; ins->inst_i0 = args [0]; - ins->inst_i1 = ins_iconst; - /* FIXME: */ } else if (strcmp (cmethod->name, "Exchange") == 0) { guint32 opcode;