values [ins->dreg] = LLVMBuildPhi (builder, LLVMTypeOf (phi_values [0]), "");
LLVMAddIncoming (values [ins->dreg], phi_values, bbs, nelems);
+ MonoTypeEnum type = (MonoTypeEnum)ins->inst_c0;
+ switch (type) {
+ case MONO_TYPE_U1:
+ case MONO_TYPE_U2:
+ values [ins->dreg] = LLVMBuildZExt (ctx->builder, values [ins->dreg], LLVMInt32Type (), "");
+ break;
+ default:
+ break;
+ }
ctx->bblocks [bb->block_num].end_bblock = cbb;
break;
}
MINI_OP(OP_XCAST, "xcast", XREG, XREG, NONE)
/* Extract element of vector */
/* The index is assumed to be in range */
+/* inst_i0 is the element type */
MINI_OP(OP_XEXTRACT_I32, "xextract_i32", IREG, XREG, IREG)
MINI_OP(OP_XEXTRACT_I64, "xextract_i64", LREG, XREG, IREG)
MINI_OP(OP_XEXTRACT_R8, "xextract_r8", FREG, XREG, IREG)
ins->dreg = dreg;
ins->sreg1 = load_simd_vreg (cfg, cmethod, args [0], NULL);
ins->sreg2 = args [1]->dreg;
+ ins->inst_c0 = etype->type;
mini_type_to_eval_stack_type (cfg, etype, ins);
MONO_ADD_INS (cfg->cbb, ins);
return ins;
EMIT_NEW_ICONST (cfg, index_ins, 0);
}
- /* Emit index check for the end (index + len - 1 < array length) */
+ /* CopyTo () does complicated argument checks */
+ mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), index_ins->dreg, "ArgumentOutOfRangeException");
end_index_reg = alloc_ireg (cfg);
- EMIT_NEW_BIALU_IMM (cfg, ins, OP_IADD_IMM, end_index_reg, index_ins->dreg, len - 1);
- mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), end_index_reg, "ArgumentOutOfRangeException");
+ int len_reg = alloc_ireg (cfg);
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS (cfg, OP_LOADI4_MEMBASE, len_reg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), MONO_INST_INVARIANT_LOAD);
+ EMIT_NEW_BIALU (cfg, ins, OP_ISUB, end_index_reg, len_reg, index_ins->dreg);
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, end_index_reg, len);
+ MONO_EMIT_NEW_COND_EXC (cfg, LT, "ArgumentException");
/* Load the array slice into the simd reg */
- ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, TRUE);
+ ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, FALSE);
EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STOREX_MEMBASE, ldelema_ins->dreg, 0, val_vreg);
ins->klass = cmethod->klass;
return ins;