break;
case OP_BOUNDS_CHECK:
MONO_EMIT_NULL_CHECK (cfg, ins->sreg1);
- if (COMPILE_LLVM (cfg))
- MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2, ins->flags & MONO_INST_FAULT);
- else
+ if (COMPILE_LLVM (cfg)) {
+ int index2_reg = alloc_preg (cfg);
+ MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index2_reg, ins->sreg2);
+ MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, index2_reg, ins->flags & MONO_INST_FAULT);
+ } else {
MONO_ARCH_EMIT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2);
+ }
break;
case OP_NEWARR:
if (cfg->opt & MONO_OPT_SHARED) {
#if SIZEOF_REGISTER == 8
/* The array reg is 64 bits but the index reg is only 32 */
if (COMPILE_LLVM (cfg)) {
- /* Not needed */
+ /*
+ * abcrem can't handle the OP_SEXT_I4, so add this after abcrem,
+ * during OP_BOUNDS_CHECK decomposition, and in the implementation
+ * of OP_X86_LEA for llvm.
+ */
index2_reg = index_reg;
} else {
index2_reg = alloc_preg (cfg);
case OP_X86_LEA: {
LLVMValueRef v1, v2;
+ rhs = LLVMBuildSExt (builder, convert (ctx, rhs, LLVMInt32Type ()), LLVMInt64Type (), "");
+
v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);