diff --git a/target/cr16c/insn.decode b/target/cr16c/insn.decode index b0c92e7196..625eca0402 100644 --- a/target/cr16c/insn.decode +++ b/target/cr16c/insn.decode @@ -89,7 +89,7 @@ ORW_imm4_16 0010 0110 .... .... @pa ORW_reg 0010 0111 .... .... @param44 ORD_imm32 0000 0000 0101 .... .... .... .... .... .... .... .... .... @param4_32 ORD_rp 0000 0000 0001 0100 1001 ---- .... .... @escape2_dc - +SCOND 0000 1000 .... .... @param44_imm XORB_imm4_16 0010 1000 .... .... @param44_imm XORB_reg 0010 1001 .... .... @param44 XORW_imm4_16 0010 1010 .... .... @param44_imm diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index 55dad4577c..502cbda079 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -725,12 +725,12 @@ static bool trans_SUBW_reg(DisasContext *ctx, arg_SUBW_reg *a) { static void gen_cmp(TCGv_i32 src1, TCGv_i32 src2) { tcg_gen_setcond_i32(TCG_COND_EQ, f_z, src1, src2); - tcg_gen_setcond_i32(TCG_COND_GT, f_n, src1, src2); - tcg_gen_setcond_i32(TCG_COND_GTU, f_l, src1, src2); + tcg_gen_setcond_i32(TCG_COND_GT, f_l, src1, src2); + tcg_gen_setcond_i32(TCG_COND_GTU, f_n, src1, src2); } static bool trans_CMPB_imm4_16(DisasContext *ctx, arg_CMPB_imm4_16 *a) { - int32_t imm = get_imm4(ctx, a->imm) & 0xFF; + int32_t imm = u16_to_s16(get_imm4(ctx, a->imm)); TCGv_i32 temp = tcg_temp_new_i32(); tcg_gen_ext8s_i32(temp, r[a->rs]); @@ -884,6 +884,57 @@ static bool trans_ORD_rp(DisasContext *ctx, arg_ORD_rp *a) { 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); + break; + case CR16C_COND_NE: + tcg_gen_andc_i32(r[a->rd], tcg_constant_i32(1), f_z); + break; + case CR16C_COND_CS: + tcg_gen_andi_i32(r[a->rd], f_c, 1); + break; + case CR16C_COND_CC: + tcg_gen_andc_i32(r[a->rd], tcg_constant_i32(1), f_c); + break; + case CR16C_COND_HI: + tcg_gen_mov_i32(r[a->rd], f_l); + break; + case CR16C_COND_LS: + tcg_gen_andc_i32(r[a->rd], tcg_constant_i32(1), f_l); + break; + case CR16C_COND_GT: + tcg_gen_mov_i32(r[a->rd], f_n); + break; + case CR16C_COND_LE: + tcg_gen_andc_i32(r[a->rd], tcg_constant_i32(1), f_n); + break; + case CR16C_COND_FS: + tcg_gen_andi_i32(r[a->rd], f_f, 1); + break; + case CR16C_COND_FC: + tcg_gen_andc_i32(r[a->rd], tcg_constant_i32(1), f_f); + break; + case CR16C_COND_LO: + tcg_gen_nor_i32(r[a->rd], f_z, f_l); + tcg_gen_andi_i32(r[a->rd], r[a->rd], 1); + break; + case CR16C_COND_HS: + tcg_gen_or_i32(r[a->rd], f_z, f_l); + break; + case CR16C_COND_LT: + tcg_gen_nor_i32(r[a->rd], f_z, f_n); + tcg_gen_andi_i32(r[a->rd], r[a->rd], 1); + break; + case CR16C_COND_GE: + tcg_gen_or_i32(r[a->rd], f_z, f_n); + break; + } + + return true; +} + static bool trans_XORB_imm4_16(DisasContext *ctx, arg_ORB_imm4_16 *a) { uint16_t imm = get_imm4(ctx, a->imm) & 0xFF; tcg_gen_xori_i32(r[a->rd], r[a->rd], imm); @@ -981,7 +1032,7 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { tcg_gen_brcondi_i32(TCG_COND_EQ, f_n, 1, l); break; case CR16C_COND_LE: - tcg_gen_brcondi_i32(TCG_COND_NE, f_l, 1, l); + tcg_gen_brcondi_i32(TCG_COND_NE, f_n, 1, l); break; case CR16C_COND_FS: tcg_gen_brcondi_i32(TCG_COND_EQ, f_f, 1, l); diff --git a/tests/tcg/cr16c/test06-scond.S b/tests/tcg/cr16c/test06-scond.S new file mode 100644 index 0000000000..457497f054 --- /dev/null +++ b/tests/tcg/cr16c/test06-scond.S @@ -0,0 +1,117 @@ +#include "macros.inc" + +.global _start + +.text +_start: + /* Initialize registers */ + RESET + + /* Equal */ + cmpb $0, r0 + seq r1 + EXPECT 1, r1 + cmpb $1, r0 + seq r2 + EXPECT 0, r2 + cmpb $0, r0 + sne r3 + EXPECT 0, r3 + cmpb $1, r0 + sne r4 + EXPECT 1, r4 + RESET + + /* Carry */ + SETC + scs r0 + EXPECT 1, r0 + CLEARC + scs r1 + EXPECT 0, r1 + SETC + scc r2 + EXPECT 0, r2 + CLEARC + scc r3 + EXPECT 1, r3 + RESET + + /* Higher */ + cmpb $1, r0 + shi r1 + EXPECT 1, r1 + cmpb $-1, r0 + shi r2 + EXPECT 0, r2 + cmpb $1, r0 + sls r3 + EXPECT 0, r3 + cmpb $-1, r0 + sls r4 + EXPECT 1, r4 + RESET + + /* Greater */ + cmpb $-1, r0 + sgt r1 + EXPECT 1, r1 + cmpb $0, r0 + sgt r2 + EXPECT 0, r2 + cmpb $-1, r0 + sle r3 + EXPECT 0, r3 + cmpb $0, r0 + sle r4 + EXPECT 1, r4 + RESET + + /* Flag */ + SETF + sfs r0 + EXPECT 1, r0 + CLEARF + sfs r1 + EXPECT 0, r1 + SETF + sfc r2 + EXPECT 0, r2 + CLEARF + sfc r3 + EXPECT 1, r3 + RESET + + /* Lower */ + cmpb $-1, r0 + slo r1 + EXPECT 1, r1 + cmpb $0, r0 + slo r2 + EXPECT 0, r2 + cmpb $-1, r0 + shs r3 + EXPECT 0, r3 + cmpb $0, r0 + shs r4 + EXPECT 1, r4 + RESET + + /* Lesser */ + cmpb $0, r1 + slt r2 + EXPECT 1, r2 + cmpb $1, r0 + slt r3 + EXPECT 0, r3 + cmpb $0, r1 + sge r4 + EXPECT 0, r4 + cmpb $1, r0 + sge r5 + EXPECT 1, r5 + RESET + + + ENDING + FAIL_HANDLER