return (int)res;
}
+
+ public static int test_0_lrem_imm_2 ()
+ {
+ long x = 245345634L;
+ return (int)(x % 2L);
+ }
+
+ public static int test_1_lrem_imm_2 ()
+ {
+ long x = 24534553245L;
+ return (int)(x % 2L);
+ }
+
+ public static int test_1_lrem_imm_2_neg ()
+ {
+ long x = -24534553245L;
+ return -(int)(x % 2L);
+ }
+
+ public static int test_13_lrem_imm_32 ()
+ {
+ long x = 17389L;
+ return (int)(x % 32L);
+ }
+
+ public static int test_27_lrem_imm_32_neg ()
+ {
+ long x = -2435323L;
+ return -(int)(x % 32L);
+ }
+
+ public static int test_5_lrem_imm_large ()
+ {
+ long x = 0x1000000005L;
+ return (int)(x % 0x40000000L);
+ }
+
+ public static int test_5_lrem_imm_too_large ()
+ {
+ long x = 0x1000000005L;
+ return (int)(x % 0x80000000L);
+ }
}
case OP_IREM_UN_IMM:
mono_decompose_op_imm (cfg, bb, ins);
break;
+ case OP_LREM_IMM:
case OP_IREM_IMM:
/* Keep the opcode if we can implement it efficiently */
- if (!((ins->inst_imm > 0) && (mono_is_power_of_two (ins->inst_imm) != -1)))
+ if (!(amd64_is_imm32 (ins->inst_imm) && (ins->inst_imm > 0) && (mono_is_power_of_two (ins->inst_imm) != -1)))
mono_decompose_op_imm (cfg, bb, ins);
break;
case OP_COMPARE_IMM:
amd64_div_reg (code, ins->sreg2, FALSE);
}
break;
+ case OP_LREM_IMM: {
+ int power = mono_is_power_of_two (ins->inst_imm);
+
+ g_assert (ins->sreg1 == AMD64_RAX);
+ g_assert (ins->dreg == AMD64_RAX);
+ g_assert (power >= 0);
+
+ if (power == 0) {
+ amd64_mov_reg_imm (code, ins->dreg, 0);
+ break;
+ }
+
+ /* Based on gcc code */
+
+ /* Add compensation for negative dividents */
+ amd64_mov_reg_reg_size (code, AMD64_RDX, AMD64_RAX, 8);
+ if (power > 1)
+ amd64_shift_reg_imm_size (code, X86_SAR, AMD64_RDX, 63, 8);
+ amd64_shift_reg_imm_size (code, X86_SHR, AMD64_RDX, 64 - power, 8);
+ amd64_alu_reg_reg_size (code, X86_ADD, AMD64_RAX, AMD64_RDX, 8);
+ /* Compute remainder */
+ amd64_alu_reg_imm_size (code, X86_AND, AMD64_RAX, (1 << power) - 1, 8);
+ /* Remove compensation */
+ amd64_alu_reg_reg_size (code, X86_SUB, AMD64_RAX, AMD64_RDX, 8);
+ break;
+ }
case OP_IDIV:
case OP_IREM:
#if defined( __native_client_codegen__ )