diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index fdd35d2dbb..6cd1862388 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -108,26 +108,28 @@ static int16_t u16_to_s16(uint16_t num) { static bool trans_MOVB_imm4_16(DisasContext* ctx, arg_MOVB_imm4_16* a) { uint32_t imm = get_imm4(ctx, a->imm) & 0xFF; - - tcg_gen_andi_i32(r[a->rd], r[a->rd], 0xFF00); - tcg_gen_ori_i32(r[a->rd], r[a->rd], imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], tcg_constant_i32(imm), 0, 8); return true; } static bool trans_MOVB_reg(DisasContext* ctx, arg_MOVB_reg* a) { - tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rs], 0, 4); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rs], 0, 8); return true; } static bool trans_MOVD_imm20(DisasContext* ctx, arg_MOVD_imm20* a) { tcg_gen_movi_i32(r[a->rd], a->imm); - tcg_gen_movi_i32(r[a->rd + 1], a->imm >> 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_movi_i32(r[a->rd + 1], a->imm >> 16); + } return true; } static bool trans_MOVD_imm32(DisasContext* ctx, arg_MOVD_imm32* a) { tcg_gen_movi_i32(r[a->rd], a->imm); - tcg_gen_movi_i32(r[a->rd + 1], a->imm >> 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_movi_i32(r[a->rd + 1], a->imm >> 16); + } return true; } @@ -135,47 +137,69 @@ static bool trans_MOVD_imm4_16(DisasContext* ctx, arg_MOVD_imm4_16* a) { uint32_t imm = u16_to_s16(get_imm4(ctx, a->imm)); tcg_gen_movi_i32(r[a->rd], imm); - tcg_gen_movi_i32(r[a->rd + 1], 0); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_movi_i32(r[a->rd + 1], 0); + } return true; } static bool trans_MOVD_reg(DisasContext* ctx, arg_MOVD_reg* a) { - tcg_gen_mov_i32(r[a->rd], r[a->rs]); - tcg_gen_mov_i32(r[a->rd+1], r[a->rs+1]); + if (a->rs < CR16C_FIRST_32B_REG && a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_mov_i32(r[a->rd], r[a->rs]); + tcg_gen_mov_i32(r[a->rd+1], r[a->rs+1]); + } + else if (a->rs >= CR16C_FIRST_32B_REG && a->rd >= CR16C_FIRST_32B_REG) { + tcg_gen_mov_i32(r[a->rd], r[a->rs]); + } + else if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rs], r[a->rs+1], 16, 16); + } + else { /* <=> a->rd < CR16C_FIRST_32B_REG */ + tcg_gen_mov_i32(r[a->rd], r[a->rs]); + tcg_gen_shri_i32(r[a->rd+1], r[a->rs], 16); + } return true; } static bool trans_MOVW_imm4_16(DisasContext* ctx, arg_MOVW_imm4_16* a) { uint32_t imm = get_imm4(ctx, a->imm) & 0xFFFF; - tcg_gen_movi_i32(r[a->rd], imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], tcg_constant_i32(imm), 0, 16); return true; } static bool trans_MOVW_reg(DisasContext* ctx, arg_MOVW_reg* a) { - tcg_gen_mov_i32(r[a->rd], r[a->rs]); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rs], 0, 16); return true; } static bool trans_MOVXB(DisasContext* ctx, arg_MOVXB* a) { - tcg_gen_ext8s_i32(r[a->rd], r[a->rs]); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_ext8s_i32(temp, r[a->rs]); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); return true; } static bool trans_MOVXW(DisasContext* ctx, arg_MOVXW* a) { tcg_gen_ext16s_i32(r[a->rd], r[a->rs]); - tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } return true; } static bool trans_MOVZB(DisasContext* ctx, arg_MOVZB* a) { - tcg_gen_ext8u_i32(r[a->rd], r[a->rs]); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_ext8u_i32(temp, r[a->rs]); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); return true; } static bool trans_MOVZW(DisasContext* ctx, arg_MOVZW* a) { - tcg_gen_mov_i32(r[a->rd], r[a->rs]); - tcg_gen_movi_i32(r[a->rd+1], 0); + tcg_gen_andi_i32(r[a->rd], r[a->rs], 0xFFFF); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_movi_i32(r[a->rd+1], 0); + } return true; } @@ -246,9 +270,9 @@ static bool gen_ADDB_reg(DisasContext* ctx, TCGv reg1, TCGv reg2, bool plus_carr static bool gen_ADDW_imm4_16(TCGv reg1, uint16_t imm, bool plus_carry) { TCGv temp = tcg_temp_new_i32(); - tcg_gen_andi_i32(reg1, reg1, 0xFFFF); + tcg_gen_andi_i32(temp, reg1, 0xFFFF); - tcg_gen_addi_i32(temp, reg1, imm); + tcg_gen_addi_i32(temp, temp, imm); if(plus_carry) { @@ -269,34 +293,37 @@ static bool gen_ADDW_imm4_16(TCGv reg1, uint16_t imm, bool plus_carry) { } tcg_gen_shri_i32(f_f, f_f, 15); - tcg_gen_mov_i32(reg1, temp); + tcg_gen_deposit_i32(reg1, reg1, temp, 0, 16); return true; } static bool gen_ADDW_reg(TCGv reg1, TCGv reg2, bool plus_carry) { TCGv tempf_f = tcg_temp_new_i32(); + TCGv temp_res = tcg_temp_new_i32(); tcg_gen_eqv_i32(tempf_f, reg1, reg2); - tcg_gen_andi_i32(reg1, reg1, 0xFFFF); + tcg_gen_andi_i32(temp_res, reg1, 0xFFFF); tcg_gen_andi_i32(reg2, reg2, 0xFFFF); - tcg_gen_add_i32(reg1, reg1, reg2); + tcg_gen_add_i32(temp_res, temp_res, reg2); if(plus_carry) { tcg_gen_andi_i32(f_c, f_c, 1); - tcg_gen_add_i32(reg1, reg1, f_c); + tcg_gen_add_i32(temp_res, temp_res, f_c); } /* Carry flag */ - tcg_gen_shri_i32(f_c, reg1, 16); + tcg_gen_shri_i32(f_c, temp_res, 16); /* Overflow flag */ - tcg_gen_xor_i32(f_f, reg1, reg2); + tcg_gen_xor_i32(f_f, temp_res, reg2); tcg_gen_and_i32(f_f, f_f, tempf_f); tcg_gen_shri_i32(f_f, f_f, 15); + tcg_gen_deposit_i32(reg1, reg1, temp_res, 0, 16); + return true; } @@ -327,53 +354,65 @@ static bool trans_ADDCW_reg(DisasContext *ctx, arg_ADDCW_reg *a) { return gen_ADDW_reg(r[a->rd], r[a->rs], true); } -static bool gen_ADDD_imm(TCGv regl, TCGv regh, uint32_t imm) { - TCGv_i64 temp = tcg_temp_new_i64(); +static bool gen_ADDD_imm(int regnl, uint32_t imm) { + TCGv_i64 temp_res = tcg_temp_new_i64(); + TCGv_i32 temp_h = tcg_temp_new_i32(); + + TCGv_i32 regl = r[regnl]; + TCGv_i32 regh = r[regnl+1]; /* Move param registers into 64 bit temporary */ - tcg_gen_shli_i32(regh, regh, 16); - tcg_gen_andi_i32(regl, regl, 0xFFFF); - tcg_gen_or_i32(regl, regh, regl); - tcg_gen_extu_i32_i64(temp, regl); + if (regnl < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(temp_h, regl, regh, 16, 16); + } + else { + tcg_gen_mov_i32(temp_h, regl); + } + tcg_gen_extu_i32_i64(temp_res, temp_h); - tcg_gen_addi_i64(temp, temp, imm); - tcg_gen_extrl_i64_i32(regl, temp); + tcg_gen_addi_i64(temp_res, temp_res, imm); + tcg_gen_extrl_i64_i32(regl, temp_res); /* Carry flag */ - tcg_gen_extrh_i64_i32(f_c, temp); + tcg_gen_extrh_i64_i32(f_c, temp_res); /* Overflow flag */ if (imm & 0x80000000) { - tcg_gen_andc_i32(f_f, regh, regl); + tcg_gen_andc_i32(f_f, temp_h, regl); } else { - tcg_gen_andc_i32(f_f, regl, regh); + tcg_gen_andc_i32(f_f, regl, temp_h); } tcg_gen_shri_i32(f_f, f_f, 31); - tcg_gen_shri_i32(regh, regl, 16); + if (regnl < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(regh, regl, 16); + } return true; } -static bool gen_ADDD_rp(TCGv_i32 rdl, TCGv_i32 rdh, TCGv_i32 rsl, TCGv_i32 rsh, bool plus_one) { +static bool gen_ADDD_rp(int rdn, TCGv_i32 rs, bool plus_one) { TCGv temp2_32 = tcg_temp_new_i32(); TCGv_i64 temp1 = tcg_temp_new_i64(); TCGv_i64 temp2 = tcg_temp_new_i64(); + + TCGv_i32 rdl = r[rdn]; + TCGv_i32 rdh = r[rdn + 1]; /* Move param registers into 64 bit temporaries */ - tcg_gen_shli_i32(temp2_32, rsh, 16); - tcg_gen_andi_i32(rsl, rsl, 0xFFFF); - tcg_gen_or_i32(temp2_32, temp2_32, rsl); + tcg_gen_extu_i32_i64(temp1, rs); + + if (rdn < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(temp2_32, rdl, rdh, 16, 16); + } + else { + tcg_gen_mov_i32(temp2_32, rdl); + } tcg_gen_extu_i32_i64(temp2, temp2_32); - tcg_gen_shli_i32(rdh, rdh, 16); - tcg_gen_andi_i32(rdl, rdl, 0xFFFF); - tcg_gen_or_i32(rdl, rdh, rdl); - tcg_gen_extu_i32_i64(temp1, rdl); - /* Prepare overflow flag */ - tcg_gen_xor_i32(f_f, rdl, temp2_32); + tcg_gen_xor_i32(f_f, temp2_32, rs); tcg_gen_add_i64(temp1, temp1, temp2); if(plus_one) { @@ -381,7 +420,9 @@ static bool gen_ADDD_rp(TCGv_i32 rdl, TCGv_i32 rdh, TCGv_i32 rsl, TCGv_i32 rsh, } tcg_gen_extrl_i64_i32(rdl, temp1); - tcg_gen_shri_i32(rdh, rdl, 16); + if (rdn < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(rdh, rdl, 16); + } /* Carry flag */ tcg_gen_extrh_i64_i32(f_c, temp1); @@ -395,20 +436,24 @@ static bool gen_ADDD_rp(TCGv_i32 rdl, TCGv_i32 rdh, TCGv_i32 rsl, TCGv_i32 rsh, } static bool trans_ADDD_imm20(DisasContext* ctx, arg_ADDD_imm20 *a) { - return gen_ADDD_imm(r[a->rd], r[a->rd+1], a->imm); + return gen_ADDD_imm(a->rd, a->imm); } static bool trans_ADDD_imm32(DisasContext *ctx, arg_ADDD_imm32 *a) { - return gen_ADDD_imm(r[a->rd], r[a->rd+1], a->imm); + return gen_ADDD_imm(a->rd, a->imm); } static bool trans_ADDD_imm4_16(DisasContext *ctx, arg_ADDD_imm4_16 *a) { uint32_t imm = u16_to_s16(get_imm4(ctx, a->imm)); - return gen_ADDD_imm(r[a->rd], r[a->rd+1], imm); + return gen_ADDD_imm(a->rd, imm); } static bool trans_ADDD_rp(DisasContext *ctx, arg_ADDD_rp *a) { - return gen_ADDD_rp(r[a->rd], r[a->rd+1], r[a->rs], r[a->rs+1], false); + if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs], r[a->rs], r[a->rs+1], 16, 16); + } + gen_ADDD_rp(a->rd, r[a->rs], false); + return true; } static bool trans_ADDUB_imm4_16(DisasContext *ctx, arg_ADDUB_imm4_16 *a) { @@ -432,14 +477,18 @@ static bool trans_ADDUB_reg(DisasContext *ctx, arg_ADDUB_reg *a) { static bool trans_ADDUW_imm4_16(DisasContext *ctx, arg_ADDUW_imm4_16 *a) { uint32_t imm = get_imm4(ctx, a->imm) & 0xFFFF; + TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_addi_i32(r[a->rd], r[a->rd], imm); + tcg_gen_addi_i32(temp, r[a->rd], imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); return true; } static bool trans_ADDUW_reg(DisasContext *ctx, arg_ADDUW_reg *a) { - tcg_gen_add_i32(r[a->rd], r[a->rd], r[a->rs]); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_add_i32(temp, r[a->rd], r[a->rs]); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); return true; } @@ -477,9 +526,10 @@ static bool trans_MACQW(DisasContext *ctx, arg_MACQW *a) { tcg_gen_movcond_i32(TCG_COND_TSTNE, temp_mul, temp_mul_sign, tcg_constant_i32(0x8000), temp_neg, temp_mul); /* Load destination register */ - tcg_gen_shli_i32(temp_dest, r[a->rd+1], 16); - tcg_gen_andi_i32(r[a->rd], r[a->rd], 0xFFFF); - tcg_gen_or_i32(temp_dest, temp_dest, r[a->rd]); + tcg_gen_mov_i32(temp_dest, r[a->rd]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(temp_dest, r[a->rd], r[a->rd+1], 16, 16); + } /* Convert dest to two's complement */ tcg_gen_andi_i32(temp_neg, temp_dest, 0x7FFFFFFF); @@ -504,8 +554,10 @@ static bool trans_MACQW(DisasContext *ctx, arg_MACQW *a) { tcg_gen_movcond_i32(TCG_COND_TSTNE, temp_of2, r[a->rd+1], tcg_constant_i32(0x8000), tcg_constant_i32(0xFFFFFFFF), tcg_constant_i32(0x7FFFFFFF)); tcg_gen_movcond_i32(TCG_COND_TSTNE, temp_dest, temp_of, tcg_constant_i32(0x80000000), temp_of2, temp_dest); - tcg_gen_andi_i32(r[a->rd], temp_dest, 0xFFFF); - tcg_gen_shri_i32(r[a->rd+1], temp_dest, 16); + tcg_gen_mov_i32(r[a->rd], temp_dest); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], temp_dest, 16); + } return true; } @@ -513,22 +565,25 @@ static bool trans_MACQW(DisasContext *ctx, arg_MACQW *a) { static bool trans_MACUW(DisasContext *ctx, arg_MACUW *a) { TCGv rdl = r[a->rd]; TCGv rdh = r[a->rd+1]; - TCGv temp = tcg_temp_new_i32(); + TCGv temp1 = tcg_temp_new_i32(); + TCGv temp2 = tcg_temp_new_i32(); /* Zero potential junk in higher bits */ - tcg_gen_andi_i32(r[a->rs1], r[a->rs1], 0xFFFF); - tcg_gen_andi_i32(r[a->rs2], r[a->rs2], 0xFFFF); + tcg_gen_andi_i32(temp1, r[a->rs1], 0xFFFF); + tcg_gen_andi_i32(temp2, r[a->rs2], 0xFFFF); - tcg_gen_mul_i32(temp, r[a->rs1], r[a->rs2]); + tcg_gen_mul_i32(temp1, temp1, temp2); - tcg_gen_shli_i32(rdh, rdh, 16); - tcg_gen_andi_i32(rdl, rdl, 0xFFFF); - tcg_gen_or_i32(rdl, rdl, rdh); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(rdl, rdl, rdh, 16, 16); + } - tcg_gen_add2_i32(rdl, temp, rdl, tcg_constant_i32(0), temp, tcg_constant_i32(0)); + tcg_gen_add2_i32(rdl, temp1, rdl, tcg_constant_i32(0), temp1, tcg_constant_i32(0)); - tcg_gen_movcond_i32(TCG_COND_NE, rdl, temp, tcg_constant_i32(0), tcg_constant_i32(0xFFFFFFFF), rdl); - tcg_gen_shri_i32(rdh, rdl, 16); + tcg_gen_movcond_i32(TCG_COND_NE, rdl, temp1, tcg_constant_i32(0), tcg_constant_i32(0xFFFFFFFF), rdl); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(rdh, rdl, 16); + } return true; } @@ -536,30 +591,33 @@ static bool trans_MACUW(DisasContext *ctx, arg_MACUW *a) { static bool trans_MACSW(DisasContext *ctx, arg_MACSW *a) { TCGv rdl = r[a->rd]; TCGv rdh = r[a->rd+1]; - TCGv temp = tcg_temp_new_i32(); + TCGv temp1 = tcg_temp_new_i32(); + TCGv temp2 = tcg_temp_new_i32(); TCGv temp_of = tcg_temp_new_i32(); - TCGv temp_of2 = tcg_temp_new_i32(); + TCGv temp_of2 = temp2; - /* Zero potential junk in higher bits */ - tcg_gen_ext16s_i32(r[a->rs1], r[a->rs1]); - tcg_gen_ext16s_i32(r[a->rs2], r[a->rs2]); + tcg_gen_ext16s_i32(temp1, r[a->rs1]); + tcg_gen_ext16s_i32(temp2, r[a->rs2]); - tcg_gen_mul_i32(temp, r[a->rs1], r[a->rs2]); + tcg_gen_mul_i32(temp1, temp1, temp2); - tcg_gen_shli_i32(rdh, rdh, 16); - tcg_gen_andi_i32(rdl, rdl, 0xFFFF); - tcg_gen_or_i32(rdl, rdl, rdh); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(rdl, rdl, rdh, 16, 16); + } - tcg_gen_eqv_i32(temp_of, rdl, temp); + tcg_gen_eqv_i32(temp_of, rdl, temp1); - tcg_gen_add_i32(rdl, rdl, temp); + tcg_gen_add_i32(rdl, rdl, temp1); - tcg_gen_xor_i32(temp_of2, rdl, temp); + tcg_gen_xor_i32(temp_of2, rdl, temp1); tcg_gen_and_i32(temp_of, temp_of, temp_of2); - tcg_gen_movcond_i32(TCG_COND_TSTNE, temp, temp, tcg_constant_i32(0x8000), tcg_constant_i32(0x80000000), tcg_constant_i32(0x7FFFFFFF)); - tcg_gen_movcond_i32(TCG_COND_TSTNE, rdl, temp_of, tcg_constant_i32(0x80000000), temp, rdl); - tcg_gen_shri_i32(rdh, rdl, 16); + tcg_gen_movcond_i32(TCG_COND_TSTNE, temp1, temp1, tcg_constant_i32(0x8000), tcg_constant_i32(0x80000000), tcg_constant_i32(0x7FFFFFFF)); + tcg_gen_movcond_i32(TCG_COND_TSTNE, rdl, temp_of, tcg_constant_i32(0x80000000), temp1, rdl); + + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(rdh, rdl, 16); + } return true; } @@ -588,11 +646,13 @@ static bool trans_MULB_reg(DisasContext *ctx, arg_MULB_reg *a) { } static bool trans_MULSB_reg(DisasContext *ctx, arg_MULSB_reg *a) { - TCGv_i32 temp = tcg_temp_new_i32(); + TCGv_i32 temp1 = tcg_temp_new_i32(); + TCGv_i32 temp2 = tcg_temp_new_i32(); - tcg_gen_ext8s_i32(r[a->rd], r[a->rd]); - tcg_gen_ext8s_i32(temp, r[a->rs]); - tcg_gen_mul_i32(r[a->rd], r[a->rd], temp); + tcg_gen_ext8s_i32(temp1, r[a->rd]); + tcg_gen_ext8s_i32(temp2, r[a->rs]); + tcg_gen_mul_i32(temp1, temp1, temp2); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp1, 0, 16); return true; } @@ -604,7 +664,9 @@ static bool trans_MULSW_reg(DisasContext *ctx, arg_MULSW_reg *a) { tcg_gen_ext16s_i32(rdl, rdl); tcg_gen_ext16s_i32(r[a->rs], r[a->rs]); tcg_gen_mul_i32(rdl, rdl, r[a->rs]); - tcg_gen_shri_i32(rdh, rdl, 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(rdh, rdl, 16); + } return true; } @@ -616,21 +678,27 @@ static bool trans_MULUW_reg(DisasContext *ctx, arg_MULUW_reg *a) { tcg_gen_andi_i32(rdl, rdl, 0xFFFF); tcg_gen_andi_i32(r[a->rs], r[a->rs], 0xFFFF); tcg_gen_mul_i32(rdl, rdl, r[a->rs]); - tcg_gen_shri_i32(rdh, rdl, 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(rdh, rdl, 16); + } return true; } static bool trans_MULW_imm4_16(DisasContext *ctx, arg_MULW_imm4_16 *a) { int32_t imm = get_imm4(ctx, a->imm); + TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_muli_i32(r[a->rd], r[a->rd], imm); + tcg_gen_muli_i32(temp, r[a->rd], imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); return true; } static bool trans_MULW_reg(DisasContext *ctx, arg_MULW_reg *a) { - tcg_gen_mul_i32(r[a->rd], r[a->rd], r[a->rs]); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_mul_i32(temp, r[a->rd], r[a->rs]); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); return true; } @@ -690,17 +758,18 @@ static bool trans_SUBCW_reg(DisasContext *ctx, arg_SUBCW_reg *a) { static bool trans_SUBD_reg(DisasContext *ctx, arg_SUBD_reg *a) { TCGv_i32 templ = tcg_temp_new_i32(); - TCGv_i32 temph = tcg_temp_new_i32(); - tcg_gen_xori_i32(templ, r[a->rs], 0xFFFF); - tcg_gen_xori_i32(temph, r[a->rs+1], 0xFFFF); - gen_ADDD_rp(r[a->rd], r[a->rd+1], templ, temph, true); + if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs], r[a->rs], r[a->rs+1], 16, 16); + } + tcg_gen_xori_i32(templ, r[a->rs], 0xFFFFFFFF); + gen_ADDD_rp(a->rd, templ, true); tcg_gen_xori_i32(f_c, f_c, 1); return true; } static bool trans_SUBD_imm32(DisasContext *ctx, arg_SUBD_imm32 *a) { uint32_t imm = (~a->imm) + 1; - gen_ADDD_imm(r[a->rd], r[a->rd+1], imm); + gen_ADDD_imm(a->rd, imm); tcg_gen_xori_i32(f_c, f_c, 1); return true; } @@ -744,8 +813,8 @@ static bool trans_CMPB_reg(DisasContext *ctx, arg_CMPB_reg *a) { TCGv_i32 temp1 = tcg_temp_new_i32(); TCGv_i32 temp2 = tcg_temp_new_i32(); - tcg_gen_ext8s_i32(temp1, r[a->rs1]); - tcg_gen_ext8s_i32(temp2, r[a->rs2]); + tcg_gen_ext8s_i32(temp1, r[a->rs2]); + tcg_gen_ext8s_i32(temp2, r[a->rs1]); gen_cmp(temp1, temp2); @@ -754,57 +823,58 @@ static bool trans_CMPB_reg(DisasContext *ctx, arg_CMPB_reg *a) { static bool trans_CMPD_imm4_16(DisasContext *ctx, arg_CMPD_imm4_16 *a) { int32_t imm = u16_to_s16(get_imm4(ctx, a->imm)); - TCGv_i32 temp_rs = tcg_temp_new_i32(); - tcg_gen_shli_i32(temp_rs, r[a->rs+1], 16); - tcg_gen_deposit_i32(temp_rs, temp_rs, r[a->rs], 0, 16); - - gen_cmp(tcg_constant_i32(imm), temp_rs); - - return true; -} - -static bool trans_CMPD_imm32(DisasContext *ctx, arg_CMPD_imm32 *a) { - int32_t imm = get_imm4(ctx, a->imm); - TCGv_i32 temp_rs = tcg_temp_new_i32(); - - tcg_gen_shli_i32(temp_rs, r[a->rd+1], 16); - tcg_gen_deposit_i32(temp_rs, temp_rs, r[a->rd], 0, 16); - - gen_cmp(tcg_constant_i32(imm), temp_rs); - - return true; -} - -static bool trans_CMPD_reg(DisasContext *ctx, arg_CMPD_reg *a) { - TCGv_i32 temp1 = tcg_temp_new_i32(); - TCGv_i32 temp2 = tcg_temp_new_i32(); - - tcg_gen_shli_i32(temp1, r[a->rs1+1], 16); - tcg_gen_deposit_i32(temp1, temp1, r[a->rs1], 0, 16); - tcg_gen_shli_i32(temp2, r[a->rs2], 16); - tcg_gen_deposit_i32(temp2, temp2, r[a->rs2], 0, 16); - - gen_cmp(temp1, temp2); - - return true; -} - -static bool trans_CMPW_imm4_16(DisasContext *ctx, arg_CMPW_imm4_16 *a) { - int32_t imm = u16_to_s16(get_imm4(ctx, a->imm)); - - tcg_gen_ext16s_i32(r[a->rs], r[a->rs]); + if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs], r[a->rs], r[a->rs+1], 16, 16); + } gen_cmp(tcg_constant_i32(imm), r[a->rs]); return true; } -static bool trans_CMPW_reg(DisasContext *ctx, arg_CMPW_reg *a) { - tcg_gen_ext16s_i32(r[a->rs1], r[a->rs1]); - tcg_gen_ext16s_i32(r[a->rs2], r[a->rs2]); +static bool trans_CMPD_imm32(DisasContext *ctx, arg_CMPD_imm32 *a) { + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } - gen_cmp(r[a->rs1], r[a->rs2]); + gen_cmp(tcg_constant_i32(a->imm), r[a->rd]); + + return true; +} + +static bool trans_CMPD_reg(DisasContext *ctx, arg_CMPD_reg *a) { + if (a->rs1 < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs1], r[a->rs1], r[a->rs1+1], 16, 16); + } + if (a->rs2 < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs2], r[a->rs2], r[a->rs2+1], 16, 16); + } + + gen_cmp(r[a->rs2], r[a->rs1]); + + return true; +} + +static bool trans_CMPW_imm4_16(DisasContext *ctx, arg_CMPW_imm4_16 *a) { + int32_t imm = u16_to_s16(get_imm4(ctx, a->imm)); + TCGv_i32 temp = tcg_temp_new_i32(); + + tcg_gen_ext16s_i32(temp, r[a->rs]); + + gen_cmp(tcg_constant_i32(imm), temp); + + return true; +} + +static bool trans_CMPW_reg(DisasContext *ctx, arg_CMPW_reg *a) { + TCGv_i32 temp1 = tcg_temp_new_i32(); + TCGv_i32 temp2 = tcg_temp_new_i32(); + + tcg_gen_ext16s_i32(temp1, r[a->rs1]); + tcg_gen_ext16s_i32(temp2, r[a->rs2]); + + gen_cmp(temp2, temp1); return true; } @@ -813,43 +883,61 @@ static bool trans_CMPW_reg(DisasContext *ctx, arg_CMPW_reg *a) { /* Logical and Boolean */ static bool trans_ANDB_imm4_16(DisasContext *ctx, arg_ANDB_imm4_16 *a) { - uint16_t imm = get_imm4(ctx, a->imm) | 0xFF00; + uint32_t imm = ((uint32_t)get_imm4(ctx, a->imm)) | 0xFFFFFF00; tcg_gen_andi_i32(r[a->rd], r[a->rd], imm); return true; } static bool trans_ANDB_reg(DisasContext *ctx, arg_ANDB_reg *a) { TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_ori_i32(temp, r[a->rs], 0xFF00); + tcg_gen_ori_i32(temp, r[a->rs], 0xFFFFFF00); tcg_gen_and_i32(r[a->rd], temp, r[a->rd]); return true; } static bool trans_ANDW_imm4_16(DisasContext *ctx, arg_ANDW_imm4_16 *a) { - uint16_t imm = get_imm4(ctx, a->imm); + uint32_t imm = ((uint32_t)get_imm4(ctx, a->imm) | 0xFFFF0000); tcg_gen_andi_i32(r[a->rd], r[a->rd], imm); return true; } static bool trans_ANDW_reg(DisasContext *ctx, arg_ANDW_reg *a) { - tcg_gen_and_i32(r[a->rd], r[a->rd], r[a->rs]); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_ori_i32(temp, r[a->rs], 0xFFFF0000); + tcg_gen_and_i32(r[a->rd], temp, r[a->rd]); return true; } static bool trans_ANDD_imm32(DisasContext *ctx, arg_ANDD_imm32 *a) { tcg_gen_andi_i32(r[a->rd], r[a->rd], a->imm); - tcg_gen_andi_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_andi_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); + } return true; } static bool trans_ANDD_rp(DisasContext *ctx, arg_ANDD_rp *a) { - tcg_gen_and_i32(r[a->rd], r[a->rd], r[a->rs]); - tcg_gen_and_i32(r[a->rd+1], r[a->rd+1], r[a->rs+1]); + if (a->rd < CR16C_FIRST_32B_REG && a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_and_i32(r[a->rd], r[a->rd], r[a->rs]); + tcg_gen_and_i32(r[a->rd+1], r[a->rd+1], r[a->rs+1]); + } + else { + if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs], r[a->rs], r[a->rs+1], 16, 16); + } + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } + tcg_gen_and_i32(r[a->rd], r[a->rd], r[a->rs]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } + } return true; } static bool trans_ORB_imm4_16(DisasContext *ctx, arg_ORB_imm4_16 *a) { - uint16_t imm = get_imm4(ctx, a->imm) & 0xFF; + uint16_t imm = ((uint32_t)get_imm4(ctx, a->imm)) & 0xFF; tcg_gen_ori_i32(r[a->rd], r[a->rd], imm); return true; } @@ -868,26 +956,44 @@ static bool trans_ORW_imm4_16(DisasContext *ctx, arg_ORW_imm4_16 *a) { } static bool trans_ORW_reg(DisasContext *ctx, arg_ORW_reg *a) { - tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rs]); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_andi_i32(temp, r[a->rs], 0xFFFF); + tcg_gen_or_i32(r[a->rd], r[a->rd], temp); return true; } static bool trans_ORD_imm32(DisasContext *ctx, arg_ORD_imm32 *a) { tcg_gen_ori_i32(r[a->rd], r[a->rd], a->imm); - tcg_gen_ori_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_ori_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); + } return true; } static bool trans_ORD_rp(DisasContext *ctx, arg_ORD_rp *a) { - tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rs]); - tcg_gen_or_i32(r[a->rd+1], r[a->rd+1], r[a->rs+1]); + if (a->rd < CR16C_FIRST_32B_REG && a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rs]); + tcg_gen_or_i32(r[a->rd+1], r[a->rd+1], r[a->rs+1]); + } + else { + if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs], r[a->rs], r[a->rs+1], 16, 16); + } + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } + tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rs]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } + } return true; } static bool trans_SCOND(DisasContext *ctx, arg_SCOND *a) { switch (a->imm) { case CR16C_COND_EQ: - tcg_gen_mov_i32(r[a->rd], f_z); + tcg_gen_andi_i32(r[a->rd], f_z, 1); break; case CR16C_COND_NE: tcg_gen_andc_i32(r[a->rd], tcg_constant_i32(1), f_z); @@ -949,25 +1055,43 @@ static bool trans_XORB_reg(DisasContext *ctx, arg_ORB_reg *a) { } static bool trans_XORW_imm4_16(DisasContext *ctx, arg_ORW_imm4_16 *a) { - uint16_t imm = get_imm4(ctx, a->imm); + uint16_t imm = get_imm4(ctx, a->imm) & 0xFFFF; tcg_gen_xori_i32(r[a->rd], r[a->rd], imm); return true; } static bool trans_XORW_reg(DisasContext *ctx, arg_ORW_reg *a) { - tcg_gen_xor_i32(r[a->rd], r[a->rd], r[a->rs]); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_andi_i32(temp, r[a->rs], 0xFFFF); + tcg_gen_xor_i32(r[a->rd], temp, r[a->rd]); return true; } static bool trans_XORD_imm32(DisasContext *ctx, arg_ORD_imm32 *a) { tcg_gen_xori_i32(r[a->rd], r[a->rd], a->imm); - tcg_gen_xori_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_xori_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); + } return true; } static bool trans_XORD_rp(DisasContext *ctx, arg_ORD_rp *a) { - tcg_gen_xor_i32(r[a->rd], r[a->rd], r[a->rs]); - tcg_gen_xor_i32(r[a->rd+1], r[a->rd+1], r[a->rs+1]); + if (a->rd < CR16C_FIRST_32B_REG && a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_xor_i32(r[a->rd], r[a->rd], r[a->rs]); + tcg_gen_xor_i32(r[a->rd+1], r[a->rd+1], r[a->rs+1]); + } + else { + if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rs], r[a->rs], r[a->rs+1], 16, 16); + } + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } + tcg_gen_xor_i32(r[a->rd], r[a->rd], r[a->rs]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } + } return true; } @@ -1014,13 +1138,15 @@ static bool trans_ASHUB_reg(DisasContext *ctx, arg_ASHUB_reg *a) { } static bool trans_ASHUD_imm_l(DisasContext *ctx, arg_ASHUD_imm_l *a) { - tcg_gen_ext16u_i32(r[a->rd], r[a->rd]); - tcg_gen_shli_i32(r[a->rd+1], r[a->rd+1], 16); - tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rd+1]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } tcg_gen_shli_i32(r[a->rd], r[a->rd], a->imm); - tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } return true; } @@ -1028,25 +1154,27 @@ static bool trans_ASHUD_imm_l(DisasContext *ctx, arg_ASHUD_imm_l *a) { static bool trans_ASHUD_imm_r(DisasContext *ctx, arg_ASHUD_imm_r *a) { int32_t imm = (~a->imm+1) & 0x1F; - tcg_gen_ext16u_i32(r[a->rd], r[a->rd]); - tcg_gen_shli_i32(r[a->rd+1], r[a->rd+1], 16); - tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rd+1]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } tcg_gen_sari_i32(r[a->rd], r[a->rd], imm); - tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } return true; } static bool trans_ASHUD_rp(DisasContext *ctx, arg_ASHUD_rp *a) { - TCGv_i32 temp_resl = r[a->rd+1]; + TCGv_i32 temp_resl = tcg_temp_new_i32(); TCGv_i32 temp_resr = r[a->rd]; TCGv_i32 temp_count = tcg_temp_new_i32(); - tcg_gen_ext16u_i32(r[a->rd], r[a->rd]); - tcg_gen_shli_i32(r[a->rd+1], r[a->rd+1], 16); - tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rd+1]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } tcg_gen_ext8s_i32(temp_count, r[a->rc]); tcg_gen_shl_i32(temp_resl, r[a->rd], temp_count); @@ -1056,37 +1184,48 @@ static bool trans_ASHUD_rp(DisasContext *ctx, arg_ASHUD_rp *a) { tcg_gen_movcond_i32(TCG_COND_GEU, r[a->rd], temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); - tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } return true; } static bool trans_ASHUW_imm_l(DisasContext *ctx, arg_ASHUW_imm_l *a) { - tcg_gen_shli_i32(r[a->rd], r[a->rd], a->imm); + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_shli_i32(temp, r[a->rd], a->imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); return true; } static bool trans_ASHUW_imm_r(DisasContext *ctx, arg_ASHUW_imm_r *a) { int16_t imm = (~a->imm+1) & 0xF; - tcg_gen_ext16s_i32(r[a->rd], r[a->rd]); - tcg_gen_sari_i32(r[a->rd], r[a->rd], imm); + TCGv_i32 temp = tcg_temp_new_i32(); + + tcg_gen_ext16s_i32(temp, r[a->rd]); + tcg_gen_sari_i32(temp, temp, imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); + return true; } static bool trans_ASHUW_reg(DisasContext *ctx, arg_ASHUW_reg *a) { + TCGv_i32 temp_src = tcg_temp_new_i32(); TCGv_i32 temp_resl = tcg_temp_new_i32(); - TCGv_i32 temp_resr = r[a->rd]; + TCGv_i32 temp_resr = temp_src; TCGv_i32 temp_count = tcg_temp_new_i32(); - tcg_gen_ext16s_i32(r[a->rd], r[a->rd]); + tcg_gen_ext16s_i32(temp_src, r[a->rd]); tcg_gen_ext8s_i32(temp_count, r[a->rc]); - tcg_gen_shl_i32(temp_resl, r[a->rd], temp_count); + tcg_gen_shl_i32(temp_resl, temp_src, temp_count); tcg_gen_neg_i32(temp_count, temp_count); - tcg_gen_sar_i32(temp_resr, r[a->rd], temp_count); + tcg_gen_sar_i32(temp_resr, temp_src, temp_count); - tcg_gen_movcond_i32(TCG_COND_GEU, r[a->rd], temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); + tcg_gen_movcond_i32(TCG_COND_GEU, temp_resl, temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); + + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp_resl, 0, 16); return true; } @@ -1125,25 +1264,27 @@ static bool trans_LSHB_reg(DisasContext *ctx, arg_LSHB_reg *a) { static bool trans_LSHD_imm_r(DisasContext *ctx, arg_LSHD_imm_r *a) { int16_t imm = ((~a->imm)+1) & 0x1F; - tcg_gen_ext16u_i32(r[a->rd], r[a->rd]); - tcg_gen_shli_i32(r[a->rd+1], r[a->rd+1], 16); - tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rd+1]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } tcg_gen_shri_i32(r[a->rd], r[a->rd], imm); - tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } return true; } static bool trans_LSHD_rp(DisasContext *ctx, arg_LSHD_rp *a) { - TCGv_i32 temp_resl = r[a->rd+1]; + TCGv_i32 temp_resl = tcg_temp_new_i32(); TCGv_i32 temp_resr = r[a->rd]; TCGv_i32 temp_count = tcg_temp_new_i32(); - tcg_gen_ext16u_i32(r[a->rd], r[a->rd]); - tcg_gen_shli_i32(r[a->rd+1], r[a->rd+1], 16); - tcg_gen_or_i32(r[a->rd], r[a->rd], r[a->rd+1]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); + } tcg_gen_ext8s_i32(temp_count, r[a->rc]); tcg_gen_shl_i32(temp_resl, r[a->rd], temp_count); @@ -1153,32 +1294,41 @@ static bool trans_LSHD_rp(DisasContext *ctx, arg_LSHD_rp *a) { tcg_gen_movcond_i32(TCG_COND_GEU, r[a->rd], temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); - tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(r[a->rd+1], r[a->rd], 16); + } return true; } static bool trans_LSHW_imm_r(DisasContext *ctx, arg_LSHW_imm_r *a) { int16_t imm = ((~a->imm)+1) & 0xF; - tcg_gen_ext16u_i32(r[a->rd], r[a->rd]); - tcg_gen_shri_i32(r[a->rd], r[a->rd], imm); + TCGv_i32 temp = tcg_temp_new_i32(); + + tcg_gen_ext16u_i32(temp, r[a->rd]); + tcg_gen_shri_i32(temp, temp, imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 16); + return true; } static bool trans_LSHW_reg(DisasContext *ctx, arg_LSHW_reg *a) { + TCGv_i32 temp_src = tcg_temp_new_i32(); TCGv_i32 temp_resl = tcg_temp_new_i32(); - TCGv_i32 temp_resr = r[a->rd]; + TCGv_i32 temp_resr = tcg_temp_new_i32(); TCGv_i32 temp_count = tcg_temp_new_i32(); - tcg_gen_ext16u_i32(r[a->rd], r[a->rd]); + tcg_gen_ext16u_i32(temp_src, r[a->rd]); tcg_gen_ext8s_i32(temp_count, r[a->rc]); - tcg_gen_shl_i32(temp_resl, r[a->rd], temp_count); + tcg_gen_shl_i32(temp_resl, temp_src, temp_count); tcg_gen_neg_i32(temp_count, temp_count); - tcg_gen_shr_i32(temp_resr, r[a->rd], temp_count); + tcg_gen_shr_i32(temp_resr, temp_src, temp_count); - tcg_gen_movcond_i32(TCG_COND_GEU, r[a->rd], temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); + tcg_gen_movcond_i32(TCG_COND_GEU, temp_resl, temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); + + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp_resl, 0, 16); return true; } @@ -1272,17 +1422,20 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { tcg_gen_and_i32(temp, f_z, f_n); tcg_gen_brcondi_i32(TCG_COND_NE, temp, 1, l); break; + case CR16C_COND_ALWAYS: + tcg_gen_br(l); + break; + default: + g_assert_not_reached(); } - tcg_gen_movi_i32(f_c, 1); tcg_gen_movi_i32(pc, ctx->base.pc_next); - tcg_gen_exit_tb(ctx->base.tb, 1); + tcg_gen_exit_tb(ctx->base.tb, 0); gen_set_label(l); - tcg_gen_movi_i32(f_f, 1); tcg_gen_movi_i32(pc, dest); - tcg_gen_exit_tb(ctx->base.tb, 0); + tcg_gen_exit_tb(ctx->base.tb, 1); return true; } @@ -1291,8 +1444,6 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { static void cr16c_tr_translate_insn(DisasContextBase *base, CPUState *cs) { DisasContext *ctx = container_of(base, DisasContext, base); - tcg_gen_movi_tl(pc, ctx->base.pc_next); - uint64_t insn = decode_load(ctx); if(!decode(ctx, insn)) { // TOOD: Illegal Instruction diff --git a/tests/tcg/cr16c/macros.inc b/tests/tcg/cr16c/macros.inc index 8483357a91..160c481e95 100644 --- a/tests/tcg/cr16c/macros.inc +++ b/tests/tcg/cr16c/macros.inc @@ -11,6 +11,8 @@ movw $0x0209, r9 movw $0x010A, r10 movw $0x000B, r11 + movd $0x12345678, (r12) + movd $0x87654321, (r13) .endm .macro EXPECT expected, in @@ -18,6 +20,11 @@ bne .fail .endm +.macro EXPECTD expected, in + cmpd $\expected, (\in) + bne .fail +.endm + .macro EXPECT_COND cond b\cond 1f br .fail diff --git a/tests/tcg/cr16c/test00-moves.S b/tests/tcg/cr16c/test00-moves.S index 8186324391..a22e24fef9 100644 --- a/tests/tcg/cr16c/test00-moves.S +++ b/tests/tcg/cr16c/test00-moves.S @@ -1,5 +1,3 @@ -/* TODO: 32 bit registers */ - #include "macros.inc" @@ -15,23 +13,38 @@ _start: movb $0x4e, r1 EXPECT 0x0B07, r0 EXPECT 0x0A4e, r1 + movb $0x09, r12 + EXPECTD 0x12345609, r12 + movb $0x14, r13 + EXPECTD 0x87654314, r13 RESET /*** MOVB reg ***/ movb r0, r1 EXPECT 0x0A00, r1 + movb r2, r12 + EXPECTD 0x12345602, r12 + movb r13, r3 + EXPECT 0x0821, r3 + RESET + movb r12, r13 + EXPECTD 0x87654378, r13 RESET /*** MOVD imm20 ***/ movd $0x10010, (r1,r0) EXPECT 0x0010, r0 EXPECT 0x0001, r1 + movd $0x10210, (r12) + EXPECTD 0x10210, r12 RESET /*** MOVD imm32 ***/ movd $0x110110, (r1,r0) EXPECT 0x0110, r0 EXPECT 0x0011, r1 + movd $0x112112, (r12) + EXPECTD 0x112112, r12 RESET /*** MOVD imm4_16 ***/ @@ -41,12 +54,28 @@ _start: EXPECT 0x0000, r1 EXPECT 0x004e, r2 EXPECT 0x0000, r3 + movd $0x09, (r12) + EXPECTD 0x09, r12 + movd $0x14, (r13) + EXPECTD 0x14, r13 RESET /*** MOVD reg ***/ movd (r1,r0), (r3,r2) EXPECT 0x0B00, r2 EXPECT 0x0A01, r3 + movd (r12), (r13) + EXPECTD 0x12345678, r13 + RESET + movd (r1,r0), (r12) + EXPECTD 0x0A010B00, r12 + RESET + movd (r12), (r1,r0) + EXPECT 0x5678, r0 + EXPECT 0x1234, r1 + RESET + movd (r12), (r13) + EXPECTD 0x12345678, r13 RESET /*** MOVW imm4_16 ***/ @@ -54,11 +83,22 @@ _start: movw $0x734e, r1 EXPECT 0x0007, r0 EXPECT 0x734e, r1 + movw $0x09, r12 + EXPECTD 0x12340009, r12 + movw $0x14, r13 + EXPECTD 0x87650014, r13 RESET /*** MOVW reg ***/ movw r0, r1 EXPECT 0x0B00, r1 + movw r2, r12 + EXPECTD 0x12340902, r12 + movw r13, r3 + EXPECT 0x4321, r3 + RESET + movw r12, r13 + EXPECTD 0x87655678, r13 RESET /*** MOVXB ***/ @@ -67,6 +107,24 @@ _start: movw $0x00FF, r2 movxb r2, r3 EXPECT -1, r3 + movxb r4, r12 + EXPECTD 0x12340004, r12 + movxb r13, r5 + EXPECT 0x0021, r5 + RESET + movxb r12, r13 + EXPECTD 0x87650078, r13 + RESET + movw $0x11FF, r4 + movxb r4, r12 + EXPECTD 0x1234FFFF, r12 + movd $0x87654380, (r13) + movxb r13, r5 + EXPECT -0x80, r5 + RESET + movd $0x123456FE, (r12) + movxb r12, r13 + EXPECTD 0x8765FFFE, r13 RESET /*** MOVXW ***/ @@ -77,6 +135,26 @@ _start: movxw r4, (r6,r5) EXPECT -1, r5 EXPECT -1, r6 + movxw r7, (r12) + EXPECTD 0x00000407, r12 + movxw r13, (r9,r8) + EXPECT 0x4321, r8 + EXPECT 0x0000, r9 + RESET + movxw r12, (r13) + EXPECTD 0x00005678, r13 + RESET + movw $-2, r7 + movxw r7, (r12) + EXPECTD -2, r12 + movd $0x1111FFFE, (r13) + movxw r13, (r9,r8) + EXPECT -2, r8 + EXPECT -1, r9 + RESET + movd $0x2222FFFC, (r12) + movxw r12, (r13) + EXPECTD -4, r13 RESET /*** MOVZB ***/ @@ -85,6 +163,24 @@ _start: movw $0x00FF, r2 movzb r2, r3 EXPECT 0x00FF, r3 + movzb r4, r12 + EXPECTD 0x12340004, r12 + movzb r13, r5 + EXPECT 0x0021, r5 + RESET + movzb r12, r13 + EXPECTD 0x87650078, r13 + RESET + movw $0x11FF, r4 + movzb r4, r12 + EXPECTD 0x123400FF, r12 + movd $0x87654380, (r13) + movzb r13, r5 + EXPECT 0x0080, r5 + RESET + movd $0x123456FE, (r12) + movzb r12, r13 + EXPECTD 0x876500FE, r13 RESET /*** MOVZW ***/ @@ -95,6 +191,27 @@ _start: movzw r4, (r6,r5) EXPECT -1, r5 EXPECT 0x0000, r6 + movzw r7, (r12) + EXPECTD 0x00000407, r12 + movzw r13, (r9,r8) + EXPECT 0x4321, r8 + EXPECT 0x0000, r9 + RESET + movzw r12, (r13) + EXPECTD 0x00005678, r13 + RESET + movw $-2, r7 + movzw r7, (r12) + EXPECTD 0x0000FFFE, r12 + movd $0x1111FFFE, (r13) + movzw r13, (r9,r8) + EXPECT -2, r8 + EXPECT 0, r9 + RESET + movd $0x2222FFFC, (r12) + movzw r12, (r13) + EXPECTD 0x0000FFFC, r13 + RESET ENDING FAIL_HANDLER diff --git a/tests/tcg/cr16c/test01-adds.S b/tests/tcg/cr16c/test01-adds.S index df3c262a05..80ed19b853 100644 --- a/tests/tcg/cr16c/test01-adds.S +++ b/tests/tcg/cr16c/test01-adds.S @@ -45,6 +45,13 @@ _start: addb $0x80, r10 EXPECT_COND fs EXPECT 0x0000, r10 + /* dword reg */ + addb $0x14, r12 + EXPECT_COND cc + EXPECTD 0x1234568C, r12 + addb $0xDF, r13 + EXPECT_COND cs + EXPECTD 0x87654300, r13 RESET /*** ADDB reg ***/ @@ -91,6 +98,15 @@ _start: addb r3, r4 EXPECT_COND fs EXPECT 0x0000, r4 + /* dword reg */ + movw $0x14, r0 + addb r0, r12 + EXPECT_COND cc + EXPECTD 0x1234568C, r12 + movw $0xDF, r0 + addb r0, r13 + EXPECT_COND cs + EXPECTD 0x87654300, r13 RESET /*** ADDCB imm4_16 ***/ @@ -119,6 +135,15 @@ _start: addcb $0x7B, r5 EXPECT_COND fs EXPECT 0x0680, r5 + /* dword reg */ + SETC + addcb $0x14, r12 + EXPECT_COND cc + EXPECTD 0x1234568D, r12 + CLEARC + addcb $0xDF, r13 + EXPECT_COND cs + EXPECTD 0x87654300, r13 RESET /*** ADDCB reg ***/ @@ -152,6 +177,18 @@ _start: EXPECT_COND fs EXPECT 0x0080, r4 RESET + /* dword reg */ + movw $0x14, r0 + SETC + addcb r0, r12 + EXPECT_COND cc + EXPECTD 0x1234568D, r12 + movw $0xDF, r0 + CLEARC + addcb r0, r13 + EXPECT_COND cs + EXPECTD 0x87654300, r13 + RESET /*** ADDW imm4_16 ***/ /* Basic case, no overflow, imm4 */ @@ -191,6 +228,13 @@ _start: addw $-0x8000, r10 EXPECT_COND fs EXPECT 0x0000, r10 + /* dword reg */ + addw $0x1414, r12 + EXPECT_COND cc + EXPECTD 0x12346A8C, r12 + addw $-0x4321, r13 /* 0xBCDF */ + EXPECT_COND cs + EXPECTD 0x87650000, r13 RESET /*** ADDW reg ***/ @@ -237,6 +281,15 @@ _start: addw r3, r4 EXPECT_COND fs EXPECT 0x0000, r4 + /* dword reg */ + movw $0x1414, r0 + addw r0, r12 + EXPECT_COND cc + EXPECTD 0x12346A8C, r12 + movw $-0x4321, r0 /* 0xBCDF */ + addw r0, r13 + EXPECT_COND cs + EXPECTD 0x87650000, r13 RESET /*** ADDCW imm4_16 ***/ @@ -266,6 +319,16 @@ _start: EXPECT_COND fs EXPECT -0x8000, r5 RESET + /* dword reg */ + SETC + addcw $0x1414, r12 + EXPECT_COND cc + EXPECTD 0x12346A8D, r12 + CLEARC + addcw $-0x4321, r13 /* 0xBCDF */ + EXPECT_COND cs + EXPECTD 0x87650000, r13 + RESET /*** ADDCW reg ***/ /* Basic 2 regs, no overflow */ @@ -297,6 +360,17 @@ _start: addcw r2, r4 EXPECT_COND fs EXPECT -0x8000, r4 + /* dword reg */ + movw $0x1414, r0 + SETC + addcw r0, r12 + EXPECT_COND cc + EXPECTD 0x12346A8D, r12 + movw $-0x4321, r0 /* 0xBCDF */ + CLEARC + addcw r0, r13 + EXPECT_COND cs + EXPECTD 0x87650000, r13 RESET /*** ADDD imm20 ***/ @@ -331,6 +405,13 @@ _start: EXPECT_COND fs EXPECT 0x010B, r10 EXPECT -0x8000, r11 + /* dword reg */ + addd $0x12221, (r12) + EXPECT_COND cc + EXPECTD 0x12357899, r12 + addd $0xABCDF, (r13) + EXPECT_COND cc + EXPECTD 0x87700000, r13 RESET /*** ADDD imm32 ***/ @@ -370,6 +451,13 @@ _start: addw $-0x8000, r10 EXPECT_COND fs EXPECT 0x0000, r10 + /* dword reg */ + addd $0x11111111, (r12) + EXPECT_COND cc + EXPECTD 0x23456789, r12 + addd $0xABCDF, (r13) + EXPECT_COND cc + EXPECTD 0x87700000, r13 RESET /*** ADDD imm16_4 ***/ @@ -424,6 +512,18 @@ _start: EXPECT -1, r4 EXPECT 0x7FFF, r5 RESET + /* dword reg */ + addb $0x14, r12 + EXPECT_COND cc + EXPECTD 0x1234568C, r12 + addb $0xDF, r13 + EXPECTD 0x87654300, r13 + EXPECT_COND cs + movd $-1, (r12) + addd $1, (r12) + EXPECT_COND cs + EXPECTD 0, r12 + RESET /*** ADDD rp ***/ /* Basic 2 rps, no overflow */ @@ -492,9 +592,17 @@ _start: EXPECT_COND fs EXPECT -3, r2 EXPECT 0x0001, r3 + /* dword reg */ + RESET + addd (r1,r0), (r12) + EXPECT_COND cc + EXPECTD 0x1C356178, r12 + addw $-0x4321, r13 /* 0xBCDF */ + EXPECT_COND cs + EXPECTD 0x87650000, r13 RESET - /*** ADDUB imm4_16 ***/ + /*** ADDUW imm4_16 ***/ /* Flags set */ /* Basic case, no overflow, imm4 */ SETC @@ -592,6 +700,15 @@ _start: adduw $-0x8000, r10 EXPECT_COND fc EXPECT 0x0000, r10 + /* dword reg */ + SETC + adduw $0x1414, r12 + EXPECT_COND cs + EXPECTD 0x12346A8C, r12 + CLEARF + adduw $-0x4321, r13 /* 0xBCDF */ + EXPECT_COND fc + EXPECTD 0x87650000, r13 RESET /*** ADDUB reg ***/ @@ -704,6 +821,17 @@ _start: addub r3, r4 EXPECT_COND fc EXPECT 0x0000, r4 + /* dword reg */ + movw $0x14, r0 + SETC + addub r0, r12 + EXPECT_COND cs + EXPECTD 0x1234568C, r12 + movw $0xDF, r0 + SETF + addub r0, r13 + EXPECT_COND fs + EXPECTD 0x87654300, r13 RESET /*** ADDUW imm4_16 ***/ @@ -804,6 +932,15 @@ _start: adduw $-0x8000, r10 EXPECT_COND fc EXPECT 0x0000, r10 + /* dword reg */ + SETC + adduw $0x1414, r12 + EXPECT_COND cs + EXPECTD 0x12346A8C, r12 + SETF + adduw $-0x4321, r13 /* 0xBCDF */ + EXPECT_COND fs + EXPECTD 0x87650000, r13 RESET /*** ADDUW reg ***/ @@ -916,6 +1053,17 @@ _start: adduw r3, r4 EXPECT_COND fc EXPECT 0x0000, r4 + /* dword reg */ + movw $0x1414, r0 + SETC + adduw r0, r12 + EXPECT_COND cs + EXPECTD 0x12346A8C, r12 + movw $-0x4321, r0 /* 0xBCDF */ + SETF + adduw r0, r13 + EXPECT_COND fs + EXPECTD 0x87650000, r13 RESET ENDING diff --git a/tests/tcg/cr16c/test02-muls.S b/tests/tcg/cr16c/test02-muls.S index e492b297e7..455ae7d7de 100644 --- a/tests/tcg/cr16c/test02-muls.S +++ b/tests/tcg/cr16c/test02-muls.S @@ -43,6 +43,14 @@ _start: macqw r1, r1, (r1,r0) EXPECT 0x0000, r0 EXPECT 0x6000, r1 + /* Dword reg */ + RESET + macqw r0, r1, (r12) + EXPECTD 0x13106C78, r12 + RESET + macqw r12, r13, (r3,r2) + EXPECT 0x23F2, r2 + EXPECT 0x355C, r3 RESET /*** MACUW ***/ @@ -66,6 +74,14 @@ _start: macuw r8, r8, (r9,r8) EXPECT 0x3348, r8 EXPECT 0x0212, r9 + /* Dword reg */ + RESET + macuw r0, r1, (r12) + EXPECTD 0x12A26178, r12 + RESET + macuw r12, r13, (r5,r4) + EXPECT -0x6B84, r4 /* 0x947C */ + EXPECT 0x1CB1, r5 RESET /*** MACSW ***/ @@ -119,6 +135,14 @@ _start: mulb $-1, r5 EXPECT 0x07F4, r4 EXPECT 0x06FB, r5 + /* Dword reg */ + RESET + macsw r0, r1, (r12) + EXPECTD 0x12A26178, r12 + movd $-5, (r12) + macsw r12, r13, (r5,r4) + EXPECT -0x48A1, r4 /* 0xB75F */ + EXPECT 0x0603, r5 RESET /*** MULB reg ***/ @@ -137,6 +161,14 @@ _start: /* Same reg */ mulb r4, r4 EXPECT 0x0710, r4 + /* Dword reg */ + mulb r12, r13 + EXPECTD 0x87654378, r13 + RESET + mulb r5, r12 + EXPECTD 0x12345658, r12 + mulb r13, r0 + EXPECT 0x0B00, r0 RESET /*** MULSB ***/ @@ -155,6 +187,14 @@ _start: /* Same reg */ mulsb r3, r3 EXPECT 0x0009, r3 + /* Dword reg */ + mulsb r12, r13 + EXPECTD 0x87650F78, r13 + RESET + mulsb r5, r12 + EXPECTD 0x12340258, r12 + mulsb r13, r0 + EXPECT 0x0000, r0 RESET /*** MULSW ***/ @@ -175,6 +215,15 @@ _start: mulsw r3, (r4,r3) EXPECT 0x3009, r3 EXPECT 0x0040, r4 + /* Dword reg */ + mulsw r12, (r13) + EXPECTD 0x16AC8D78, r13 + RESET + mulsw r5, (r12) + EXPECTD 0x02088058, r12 + mulsw r13, (r1,r0) + EXPECT 0x6B00, r0 + EXPECT 0x02E2, r1 RESET /*** MULUW ***/ @@ -195,6 +244,15 @@ _start: muluw r3, (r4,r3) EXPECT 0x3009, r3 EXPECT 0x0040, r4 + /* Dword reg */ + muluw r12, (r13) + EXPECTD 0x16AC8D78, r13 + RESET + muluw r5, (r12) + EXPECTD 0x02088058, r12 + muluw r13, (r1,r0) + EXPECT 0x6B00, r0 + EXPECT 0x02E2, r1 RESET /*** MULW imm4/16 ***/ @@ -213,6 +271,9 @@ _start: mulw $-1, r5 EXPECT -0x150C, r4 EXPECT -0x0605, r5 + /* Dword reg */ + mulw $16, r12 + EXPECTD 0x12346780, r12 RESET /*** MULW reg ***/ @@ -231,6 +292,14 @@ _start: /* Same reg */ mulw r4, r4 EXPECT 0x3810, r4 + /* Dword reg */ + mulw r12, r13 + EXPECTD 0x87658D78, r13 + RESET + mulw r5, r12 + EXPECTD 0x12348058, r12 + mulw r13, r0 + EXPECT 0x6B00, r0 RESET ENDING diff --git a/tests/tcg/cr16c/test03-subs.S b/tests/tcg/cr16c/test03-subs.S index 816d1a72c9..1eb560bd85 100644 --- a/tests/tcg/cr16c/test03-subs.S +++ b/tests/tcg/cr16c/test03-subs.S @@ -32,6 +32,9 @@ _start: subb $1, r3 EXPECT_COND fs EXPECT -0x0081, r3 + /* Dword reg */ + subb $0x5, r12 + EXPECTD 0x12345673, r12 RESET /*** SUBB reg ***/ @@ -62,6 +65,14 @@ _start: subb r1, r3 EXPECT_COND fs EXPECT -0x0081, r3 + /* Dword reg */ + subb r12, r12 + EXPECTD 0x12345600, r12 + subb r1, r13 + EXPECTD 0x87654320, r13 + RESET + subb r13, r9 + EXPECT 0x02E8, r9 RESET /*** SUBCB imm4/16 ***/ @@ -119,6 +130,13 @@ _start: subcb $1, r3 EXPECT_COND fs EXPECT -0x0081, r3 + /* Dword reg */ + SETC + subcb $0x5, r12 + EXPECTD 0x12345672, r12 + CLEARC + subcb $0x5, r13 + EXPECTD 0x8765431C, r13 RESET /*** SUBCB reg ***/ @@ -183,6 +201,28 @@ _start: EXPECT_COND fs EXPECT -0x0081, r3 RESET + /* Dword reg */ + SETC + subcb r12, r12 + EXPECTD 0x123456FF, r12 + CLEARC + subcb r13, r13 + EXPECTD 0x87654300, r13 + RESET + SETC + subcb r1, r12 + EXPECTD 0x12345676, r12 + CLEARC + subcb r1, r13 + EXPECTD 0x87654320, r13 + RESET + SETC + subcb r13, r9 + EXPECT 0x02E7, r9 + CLEARC + subcb r13, r8 + EXPECT 0x03E7, r8 + RESET /*** SUBCW imm4/16 ***/ /* Borrow not set */ @@ -241,6 +281,14 @@ _start: EXPECT_COND fs EXPECT 0x7FFF, r3 RESET + /* Dword reg */ + SETC + subcw $0x5554, r12 + EXPECTD 0x12340123, r12 + CLEARC + subcw $0x5444, r13 + EXPECTD 0x8765EEDD, r13 + RESET /*** SUBCW reg ***/ /* Borrow not set */ @@ -306,6 +354,28 @@ _start: EXPECT_COND fs EXPECT 0x7FFF, r3 RESET + /* Dword reg */ + SETC + subcw r12, r12 + EXPECTD 0x1234FFFF, r12 + CLEARC + subcw r13, r13 + EXPECTD 0x87650000, r13 + RESET + SETC + subcw r1, r12 + EXPECTD 0x12344C76, r12 + CLEARC + subcw r1, r13 + EXPECTD 0x87653920, r13 + RESET + SETC + subcw r13, r9 + EXPECT -0x4119, r9 /* 0xBEE7 */ + CLEARC + subcw r13, r8 + EXPECT -0x4019, r8 /* 0xBFE7 */ + RESET /*** SUBD reg ***/ /* pos no borrow */ @@ -350,6 +420,16 @@ _start: EXPECT -1, r5 EXPECT 0x7FFF, r6 RESET + /* Dword reg */ + subd (r12), (r12) + EXPECTD 0x00000000, r12 + subd (r2,r1), (r13) + EXPECTD 0x7E633920, r13 + RESET + subd (r13), (r9,r8) + EXPECT -0x4019, r8 /* 0xBFE7 */ + EXPECT 0x7AA3, r9 + RESET /*** SUBD imm32 ***/ /* pos no borrow */ @@ -387,6 +467,10 @@ _start: EXPECT -1, r5 EXPECT 0x7FFF, r6 RESET + /* Dword reg */ + subd $0x12222221, (r12) + EXPECTD 0x00123457, r12 + RESET /*** SUBW imm4/16 ***/ /* pos no borrow */ @@ -417,6 +501,19 @@ _start: EXPECT_COND fs EXPECT 0x7FFF, r3 RESET + /* Dword reg */ + subd $0x12222221, (r12) + EXPECTD 0x00123457, r12 + RESET + /* Dword reg */ + subw r12, r12 + EXPECTD 0x12340000, r12 + subw r1, r13 + EXPECTD 0x87653920, r13 + RESET + subw r13, r9 + EXPECT -0x4118, r9 /* 0xBEE8 */ + RESET /*** SUBW reg ***/ /* pos no borrow */ @@ -448,6 +545,15 @@ _start: EXPECT_COND fs EXPECT 0x7FFF, r3 RESET + /* Dword reg */ + subw r12, r12 + EXPECTD 0x12340000, r12 + subw r1, r13 + EXPECTD 0x87653920, r13 + RESET + subw r13, r9 + EXPECT -0x4118, r9 /* 0xBEE8 */ + RESET /*** Combined for 64 bit ***/ /* Positive value with brrows */ diff --git a/tests/tcg/cr16c/test04-cmps.S b/tests/tcg/cr16c/test04-cmps.S index 851d73bd43..817f0b840b 100644 --- a/tests/tcg/cr16c/test04-cmps.S +++ b/tests/tcg/cr16c/test04-cmps.S @@ -38,6 +38,10 @@ _start: cmpb $-2, r1 EXPECT_COND le EXPECT 0x00FF, r1 + /* Dword regs */ + cmpb $0x78, r12 + EXPECT_COND eq + EXPECTD 0x12345678, r12 RESET @@ -52,7 +56,7 @@ _start: EXPECT_COND gt cmpb r0, r1 EXPECT_COND le - cmpb r2, r1 + cmpb r4, r1 EXPECT_COND hi cmpb r0, r1 EXPECT_COND ls @@ -84,6 +88,12 @@ _start: cmpb r0, r0 EXPECT_COND eq EXPECT 0x0B00, r0 + /* Dword reg */ + movd $0x12345621, (r12) + cmpb r12, r13 + EXPECT_COND eq + EXPECTD 0x12345621, r12 + EXPECTD 0x87654321, r13 RESET @@ -121,6 +131,13 @@ _start: EXPECT_COND le EXPECT -1, r0 EXPECT -1, r1 + /* Dword reg */ + cmpd $0x12345678, (r12) + EXPECT_COND eq + cmpd $0x87654320, (r13) + EXPECT_COND lt + EXPECTD 0x12345678, r12 + EXPECTD 0x87654321, r13 RESET @@ -161,12 +178,21 @@ _start: EXPECT_COND le EXPECT -1, r0 EXPECT -1, r1 + /* Dword reg */ + movd $0x15, (r12) + movd $0x15, (r13) + cmpd $0x15, (r12) + EXPECT_COND eq + cmpd $0x14, (r13) + EXPECT_COND lt + EXPECTD 0x00000015, r12 + EXPECTD 0x00000015, r13 RESET /*** CMPD reg ***/ /* Unsigned */ - movw $0x0B00, r2 + movw $-1, r2 movw $0x0A01, r3 movw $-1, r0 /* Only comparing the lower half should fail */ cmpd (r3,r2), (r1,r0) @@ -177,13 +203,13 @@ _start: EXPECT_COND gt cmpd (r5,r4), (r1,r0) EXPECT_COND le - cmpd (r2,r1), (r4,r3) + cmpd (r5,r4), (r7,r6) EXPECT_COND hi - cmpd (r4,r3), (r2,r1) + cmpd (r7,r6), (r5,r4) EXPECT_COND ls EXPECT -1, r0 EXPECT 0x0A01, r1 - EXPECT 0x0B00, r2 + EXPECT -1, r2 EXPECT 0x0A01, r3 EXPECT 0x0704, r4 EXPECT 0x0605, r5 @@ -227,6 +253,14 @@ _start: EXPECT 0x0B00, r0 EXPECT 0x0A01, r1 EXPECT 0x0902, r2 + /* Dword reg */ + cmpd (r12), (r13) + EXPECT_COND hs + movd $0x12345678, (r13) + cmpd (r12), (r13) + EXPECT_COND eq + EXPECTD 0x12345678, r12 + EXPECTD 0x12345678, r13 RESET @@ -261,6 +295,13 @@ _start: cmpw $-2, r1 EXPECT_COND le EXPECT -1, r1 + /* Dword reg */ + cmpw $0x5678, r12 + EXPECT_COND eq + cmpw $0x4320, r13 + EXPECT_COND lt + EXPECTD 0x12345678, r12 + EXPECTD 0x87654321, r13 RESET @@ -307,6 +348,19 @@ _start: cmpw r0, r0 EXPECT_COND eq EXPECT 0x0B00, r0 + /* Dword reg */ + cmpw r12, r13 + EXPECT_COND hi + movw $0x4321, r0 + cmpw r0, r13 + EXPECT_COND eq + movw $0x5678, r1 + cmpw r1, r12 + EXPECT_COND eq + EXPECT 0x4321, r0 + EXPECT 0x5678, r1 + EXPECTD 0x12345678, r12 + EXPECTD 0x87654321, r13 RESET ENDING diff --git a/tests/tcg/cr16c/test05-logic.S b/tests/tcg/cr16c/test05-logic.S index e1b69621e6..a9cde1b29c 100644 --- a/tests/tcg/cr16c/test05-logic.S +++ b/tests/tcg/cr16c/test05-logic.S @@ -14,6 +14,8 @@ _start: EXPECT 0x0100, r10 andb $0x0055, r9 EXPECT 0x0201, r9 + andb $0b00011000, r12 + EXPECTD 0x12345618, r12 RESET @@ -25,6 +27,15 @@ _start: EXPECT 0x0A00, r1 andb r4, r7 EXPECT 0x0404, r7 + movd $0x22222222, (r12) + andb r12, r13 + EXPECTD 0x87654320, r13 + RESET + andb r10, r12 + EXPECTD 0x12345608, r12 + RESET + andb r12, r10 + EXPECT 0x0108, r10 RESET @@ -35,6 +46,8 @@ _start: EXPECT 0x0000, r10 andw $0x5555, r9 EXPECT 0x0001, r9 + andw $0x2222, r13 + EXPECTD 0x87650220, r13 RESET @@ -47,6 +60,14 @@ _start: EXPECT 0x0000, r1 andw r4, r7 EXPECT 0x0404, r7 + movd $0x22222222, (r12) + andw r12, r13 + EXPECTD 0x87650220, r13 + RESET + andw r4, r12 + EXPECTD 0x12340600, r12 + andw r13, r5 + EXPECT 0x0201, r5 RESET @@ -60,6 +81,8 @@ _start: andd $0x55555555, (r7,r6) EXPECT 0x0504, r6 EXPECT 0x0405, r7 + andd $0x22222222, (r12) + EXPECTD 0x02200220, r12 RESET @@ -77,6 +100,14 @@ _start: andd (r10,r9), (r8,r7) EXPECT 0x0001, r7 EXPECT 0x0108, r8 + andd (r12), (r13) + EXPECTD 0x02244220, r13 + RESET + andd (r12), (r1,r0) + EXPECT 0x0200, r0 + EXPECT 0x0200, r1 + andd (r3,r2), (r13) + EXPECTD 0x00010100, r13 RESET @@ -87,6 +118,8 @@ _start: EXPECT 0x01FF, r10 orb $0x0055, r9 EXPECT 0x025D, r9 + orb $0x22, r12 + EXPECTD 0x1234567A, r12 RESET @@ -99,6 +132,13 @@ _start: EXPECT 0x0AFF r1 orb r4, r7 EXPECT 0x0407, r7 + orb r12, r13 + EXPECTD 0x87654379, r13 + orb r9, r12 + EXPECTD 0x12345679, r12 + RESET + orb r12, r7 + EXPECT 0x047F, r7 RESET @@ -109,6 +149,8 @@ _start: EXPECT -1, r10 orw $0x5555, r9 EXPECT 0x575D, r9 + orw $0x2222, r12 + EXPECTD 0x1234767A, r12 RESET @@ -121,6 +163,15 @@ _start: EXPECT -1, r1 orw r4, r7 EXPECT 0x0707, r7 + orw r12, r13 + EXPECTD 0x87655779, r13 + orw r0, r12 + EXPECTD 0x12345F78, r12 + orw r12, r0 + EXPECT 0x5F78, r0 + RESET + orw r5, r13 + EXPECTD 0x87654725, r13 RESET @@ -134,6 +185,8 @@ _start: ord $0x55555555, (r7,r6) EXPECT 0x5557, r6 EXPECT 0x5557, r7 + ord $0x22222222, (r12) + EXPECTD 0x3236767A, r12 RESET @@ -152,6 +205,15 @@ _start: EXPECT 0x060F, r7 EXPECT 0x030A, r8 RESET + ord (r12), (r13) + EXPECTD 0x97755779, r13 + ord (r1,r0), (r12) + EXPECTD 0x1A355F78, r12 + RESET + ord (r12), (r1,r0) + EXPECT 0x5F78, r0 + EXPECT 0x1A35, r1 + RESET /*** XORB imm4/16 ***/ @@ -161,6 +223,8 @@ _start: EXPECT 0x01F5, r10 xorb $0x0055, r9 EXPECT 0x025C, r9 + xorb $0x22, r12 + EXPECTD 0x1234565A, r12 RESET @@ -173,6 +237,13 @@ _start: EXPECT 0x0AFE r1 xorb r4, r7 EXPECT 0x0403, r7 + xorb r12, r13 + EXPECTD 0x87654359, r13 + xorb r3, r12 + EXPECTD 0x1234567B, r12 + RESET + xorb r12, r4 + EXPECT 0x077C, r4 RESET @@ -183,6 +254,8 @@ _start: EXPECT -0x010B, r10 /* 0xFEF5 */ xorw $0x5555, r9 EXPECT 0x575C, r9 + xorw $0x3333, r12 + EXPECTD 0x1234654B, r12 RESET @@ -195,10 +268,17 @@ _start: EXPECT -0x0A02, r1 /* 0xF5FE */ xorw r4, r7 EXPECT 0x0303, r7 + xorw r12, r13 + EXPECTD 0x87651559, r13 + xorw r3, r12 + EXPECTD 0x12345E7B, r12 + RESET + xorw r12, r4 + EXPECT 0x517C, r4 RESET - /*** XORD imm4/16 ***/ + /*** XORD imm32 ***/ xord $0, (r11,r10) EXPECT 0x010A, r10 EXPECT 0x000B, r11 @@ -208,6 +288,8 @@ _start: xord $0x55555555, (r7,r6) EXPECT 0x5053, r6 EXPECT 0x5152, r7 + xord $0x33333333, (r12) + EXPECTD 0x2107654B, r12 RESET @@ -225,6 +307,14 @@ _start: xord (r10,r9), (r8,r7) EXPECT 0x060E, r7 EXPECT 0x0202, r8 + xord (r12), (r13) + EXPECTD 0x95511559, r13 + xord (r4,r3), (r12) + EXPECTD 0x15305E7B, r12 + RESET + xord (r12), (r4,r3) + EXPECT 0x5E7B, r3 + EXPECT 0x1530, r4 RESET diff --git a/tests/tcg/cr16c/test07-shifts.S b/tests/tcg/cr16c/test07-shifts.S index a85bc4224a..99786565a4 100644 --- a/tests/tcg/cr16c/test07-shifts.S +++ b/tests/tcg/cr16c/test07-shifts.S @@ -18,6 +18,10 @@ _start: movw $-1, r0 ashub $-2, r0 EXPECT -1, r0 + ashub $2, r12 + EXPECTD 0x123456E0, r12 + ashub $-2, r13 + EXPECTD 0x87654308, r13 RESET /*** ASHUD imm ***/ @@ -37,6 +41,10 @@ _start: ashud $-5, (r7,r6) EXPECT -1, r6 EXPECT -1, r7 + ashud $9, (r12) + EXPECTD 0x68ACF000, r12 + ashud $-9, (r13) + EXPECTD 0xFFC3B2A1, r13 RESET /*** ASHUW imm ***/ @@ -50,6 +58,10 @@ _start: movw $-1, r0 ashuw $-2, r0 EXPECT -1, r0 + ashuw $5, r12 + EXPECTD 0x1234CF00, r12 + ashuw $-5, r13 + EXPECTD 0x87650219, r13 RESET /*** ASHUB reg ***/ @@ -69,6 +81,9 @@ _start: ashub $-2, r0 EXPECT -1, r0 EXPECT -2, r2 + movw $3, r0 + ashub r0, r12 + EXPECTD 0x123456C0, r12 RESET /*** ASHUD rp ***/ @@ -93,6 +108,9 @@ _start: EXPECT -1, r9 EXPECT -1, r8 EXPECT -5, r10 + movw $9, r0 + ashud r0, (r12) + EXPECTD 0x68ACF000, r12 RESET /*** ASHUW reg ***/ @@ -112,6 +130,9 @@ _start: ashuw r5, r0 EXPECT -1, r0 EXPECT -2, r5 + movw $5, r0 + ashuw r0, r12 + EXPECTD 0x1234CF00, r12 RESET @@ -126,6 +147,10 @@ _start: movw $0x11FF, r0 lshb $-2, r0 EXPECT 0x113F, r0 + lshb $2, r12 + EXPECTD 0x123456E0, r12 + lshb $-2, r13 + EXPECTD 0x87654308, r13 RESET /*** LSHD imm ***/ @@ -145,6 +170,10 @@ _start: lshd $-5, (r7,r6) EXPECT -1, r6 EXPECT 0x07FF, r7 + lshd $9, (r12) + EXPECTD 0x68ACF000, r12 + lshd $-9, (r13) + EXPECTD 0x0043B2A1, r13 RESET /*** LSHW imm ***/ @@ -158,6 +187,10 @@ _start: movw $-1, r0 lshw $-2, r0 EXPECT 0x3FFF, r0 + lshw $5, r12 + EXPECTD 0x1234CF00, r12 + lshw $-5, r13 + EXPECTD 0x87650219, r13 RESET /*** LSHB reg ***/ @@ -177,6 +210,9 @@ _start: lshb $-2, r0 EXPECT 0x113F, r0 EXPECT -2, r2 + movw $3, r0 + lshb r0, r12 + EXPECTD 0x123456C0, r12 RESET /*** LSHD rp ***/ @@ -201,6 +237,9 @@ _start: EXPECT 0x07FF, r9 EXPECT -1, r8 EXPECT -5, r10 + movw $9, r0 + lshd r0, (r12) + EXPECTD 0x68ACF000, r12 RESET /*** LSHW reg ***/ @@ -220,6 +259,9 @@ _start: lshw r5, r0 EXPECT 0x3FFF, r0 EXPECT -2, r5 + movw $5, r0 + lshw r0, r12 + EXPECTD 0x1234CF00, r12 RESET