From 361b5a2c43c7b0b8b561f0da3ea4580a2a6beef4 Mon Sep 17 00:00:00 2001 From: Jonas Bewig Date: Wed, 30 Jul 2025 14:56:38 +0200 Subject: [PATCH] CR16C: tcg code cleanup --- hw/cr16c/sc14450.c | 2 +- target/cr16c/insn.decode | 460 ++++++------ target/cr16c/translate.c | 947 ++++++++---------------- tests/tcg/cr16c/Makefile.softmmu-target | 6 +- tests/tcg/cr16c/test01-adds.S | 4 +- 5 files changed, 563 insertions(+), 856 deletions(-) diff --git a/hw/cr16c/sc14450.c b/hw/cr16c/sc14450.c index 089e26332a..89888fe3a9 100644 --- a/hw/cr16c/sc14450.c +++ b/hw/cr16c/sc14450.c @@ -19,7 +19,7 @@ static void sc14450_realize(DeviceState* dev, Error** errp) object_initialize_child(OBJECT(dev), "cpu", &s->cpu, mc->cpu_type); object_property_set_bool(OBJECT(&s->cpu), "realized", true, &error_abort); - memory_region_init_rom(&s->flash, OBJECT(dev), "flash", mc->flash_size, &error_fatal); + memory_region_init_ram(&s->flash, OBJECT(dev), "flash", mc->flash_size, &error_fatal); memory_region_add_subregion(get_system_memory(), 0, &s->flash); } diff --git a/target/cr16c/insn.decode b/target/cr16c/insn.decode index be9567c9eb..ef141c199c 100644 --- a/target/cr16c/insn.decode +++ b/target/cr16c/insn.decode @@ -1,139 +1,181 @@ -%param84_dest 56:4 48:4 -%load_u16 !function=load_u16 +%u4_load_s16 52:4 !function=u4_load_s16 +%load_u16 !function=load_u16 -@escape2_opc .... .... .... .... .... rd:4 rs1:4 rs2:4 -@escape2_dc .... .... .... .... .... .... rs:4 rd:4 - -@param34 .... .... . imm:3 rd:4 - -@param4 .... .... .... imm:4 -@param4_20 .... .... rd:4 imm:20 - -@param44 .... .... rs:4 rd:4 -@param44_imm .... .... imm:4 rd:4 -@param44_cmp_imm .... .... imm:4 rs:4 -@param44_cmp .... .... rs2:4 rs1:4 -@param44_count .... .... rc:4 rd:4 - -@param54 .... ... imm:5 rd:4 -@param84 .... .... cond:4 .... dest=%param84_dest - -@param4_32 .... .... .... rd:4 imm:32 ### Moves ### -MOVB_imm4_16 0101 1000 .... .... @param44_imm -MOVB_reg 0101 1001 .... .... @param44 -MOVD_imm20 0000 0101 .... .... .... .... .... .... @param4_20 -MOVD_imm32 0000 0000 0111 .... .... .... .... .... .... .... .... .... @param4_32 -MOVD_imm4_16 0101 0100 .... .... @param44_imm -MOVD_reg 0101 0101 .... .... @param44 -MOVW_imm4_16 0101 1010 .... .... @param44_imm -MOVW_reg 0101 1011 .... .... @param44 -MOVXB 0101 1100 .... .... @param44 -MOVXW 0101 1110 .... .... @param44 -MOVZB 0101 1101 .... .... @param44 -MOVZW 0101 1111 .... .... @param44 + +&mov_imm rd imm width +&mov_reg rd rs width + +@mov_imm4 .... .... .... rd:4 imm=%u4_load_s16 &mov_imm +@mov_imm32 .... .... .... rd:4 imm:32 &mov_imm +@mov_imm20 .... .... rd:4 imm:20 &mov_imm +@mov_reg .... .... rs:4 rd:4 &mov_reg +@mov_d_xz .... .... rs:4 rd:4 + +MOV_imm 0101 1000 .... .... @mov_imm4 width=1 +MOV_reg 0101 1001 .... .... @mov_reg width=1 +MOV_imm 0000 0101 .... .... .... .... .... .... @mov_imm20 width=4 +MOV_imm 0000 0000 0111 .... .... .... .... .... .... .... .... .... @mov_imm32 width=4 +MOV_imm 0101 0100 .... .... @mov_imm4 width=4 +MOVD_reg 0101 0101 .... .... @mov_d_xz +MOV_imm 0101 1010 .... .... @mov_imm4 width=2 +MOV_reg 0101 1011 .... .... @mov_reg width=2 +MOVXB 0101 1100 .... .... @mov_d_xz +MOVXW 0101 1110 .... .... @mov_d_xz +MOVZB 0101 1101 .... .... @mov_d_xz +MOVZW 0101 1111 .... .... @mov_d_xz + ### Integer Arithmetic ### -ADDB_imm4_16 0011 0000 .... .... @param44_imm -ADDB_reg 0011 0001 .... .... @param44 -ADDCB_imm4_16 0011 0100 .... .... @param44_imm -ADDCB_reg 0011 0101 .... .... @param44 -ADDCW_imm4_16 0011 0110 .... .... @param44_imm -ADDCW_reg 0011 0111 .... .... @param44 -ADDD_imm20 0000 0100 .... .... .... .... .... .... @param4_20 -ADDD_imm32 0000 0000 0010 .... .... .... .... .... .... .... .... .... @param4_32 -ADDD_imm4_16 0110 0000 .... .... @param44_imm -ADDD_rp 0110 0001 .... .... @param44 -ADDUB_imm4_16 0010 1100 .... .... @param44_imm -ADDUB_reg 0010 1101 .... .... @param44 -ADDUW_imm4_16 0010 1110 .... .... @param44_imm -ADDUW_reg 0010 1111 .... .... @param44 -ADDW_imm4_16 0011 0010 .... .... @param44_imm -ADDW_reg 0011 0011 .... .... @param44 -MACQW 0000 0000 0001 0100 1101 .... .... .... @escape2_opc -MACUW 0000 0000 0001 0100 1110 .... .... .... @escape2_opc -MACSW 0000 0000 0001 0100 1111 .... .... .... @escape2_opc -MULB_imm4_16 0110 0100 .... .... @param44_imm -MULB_reg 0110 0101 .... .... @param44 -MULSB_reg 0000 1011 .... .... @param44 -MULSW_reg 0110 0010 .... .... @param44 -MULUW_reg 0110 0011 .... .... @param44 -MULW_imm4_16 0110 0110 .... .... @param44_imm -MULW_reg 0110 0111 .... .... @param44 -SUBB_imm4_16 0011 1000 .... .... @param44_imm -SUBB_reg 0011 1001 .... .... @param44 -SUBCB_imm4_16 0011 1100 .... .... @param44_imm -SUBCB_reg 0011 1101 .... .... @param44 -SUBCW_imm4_16 0011 1110 .... .... @param44_imm -SUBCW_reg 0011 1111 .... .... @param44 -SUBD_reg 0000 0000 0001 0100 1100 0000 .... .... @escape2_dc -SUBD_imm32 0000 0000 0011 .... .... .... .... .... .... .... .... .... @param4_32 -SUBW_imm4_16 0011 1010 .... .... @param44_imm -SUBW_reg 0011 1011 .... .... @param44 + +&arith_imm rd imm add_carry width +&arith_reg rd rs add_carry width +&mul_imm rd imm width + +@arith_imm .... .... .... rd:4 imm=%u4_load_s16 &arith_imm +@arith_imm_todo .... .... .... rd:4 imm=%u4_load_s16 +@arith_imm20 .... .... rd:4 imm:20 +@arith_imm32 .... .... .... rd:4 imm:s32 +@arith_reg .... .... rs:4 rd:4 &arith_reg +@addd_rp .... .... rs:4 rd:4 +@subd_rp .... .... .... .... .... .... rs:4 rd:4 +@mul_imm .... .... .... rd:4 imm=%u4_load_s16 &mul_imm +@mul_reg .... .... rs:4 rd:4 +@mac .... .... .... .... .... rd:4 rs1:4 rs2:4 + +ADD_imm 0011 0000 .... .... @arith_imm width=1 add_carry=0 +ADD_reg 0011 0001 .... .... @arith_reg width=1 add_carry=0 +ADD_imm 0011 0100 .... .... @arith_imm width=1 add_carry=1 +ADD_reg 0011 0101 .... .... @arith_reg width=1 add_carry=1 +ADD_imm 0011 0110 .... .... @arith_imm width=2 add_carry=1 +ADD_reg 0011 0111 .... .... @arith_reg width=2 add_carry=1 +ADDD_imm 0000 0100 .... .... .... .... .... .... @arith_imm20 +ADDD_imm 0000 0000 0010 .... .... .... .... .... .... .... .... .... @arith_imm32 +ADDD_imm 0110 0000 .... .... @arith_imm_todo +ADDD_rp 0110 0001 .... .... @addd_rp +ADDU_imm 0010 1100 .... .... @arith_imm width=1 add_carry=0 +ADDU_reg 0010 1101 .... .... @arith_reg width=1 add_carry=0 +ADDU_imm 0010 1110 .... .... @arith_imm width=2 add_carry=0 +ADDU_reg 0010 1111 .... .... @arith_reg width=2 add_carry=0 +ADD_imm 0011 0010 .... .... @arith_imm width=2 add_carry=0 +ADD_reg 0011 0011 .... .... @arith_reg width=2 add_carry=0 +SUB_imm 0011 1000 .... .... @arith_imm width=1 add_carry=0 +SUB_reg 0011 1001 .... .... @arith_reg width=1 add_carry=0 +SUB_imm 0011 1100 .... .... @arith_imm width=1 add_carry=1 +SUB_reg 0011 1101 .... .... @arith_reg width=1 add_carry=1 +SUB_imm 0011 1110 .... .... @arith_imm width=2 add_carry=1 +SUB_reg 0011 1111 .... .... @arith_reg width=2 add_carry=1 +SUBD_rp 0000 0000 0001 0100 1100 0000 .... .... @subd_rp +SUBD_imm 0000 0000 0011 .... .... .... .... .... .... .... .... .... @arith_imm32 +SUB_imm 0011 1010 .... .... @arith_imm width=2 add_carry=0 +SUB_reg 0011 1011 .... .... @arith_reg width=2 add_carry=0 +MUL_imm 0110 0100 .... .... @mul_imm width=1 +MULB_reg 0110 0101 .... .... @mul_reg +MULSB_reg 0000 1011 .... .... @mul_reg +MULSW_reg 0110 0010 .... .... @mul_reg +MULUW_reg 0110 0011 .... .... @mul_reg +MUL_imm 0110 0110 .... .... @mul_imm width=2 +MULW_reg 0110 0111 .... .... @mul_reg +MACQW 0000 0000 0001 0100 1101 .... .... .... @mac +MACUW 0000 0000 0001 0100 1110 .... .... .... @mac +MACSW 0000 0000 0001 0100 1111 .... .... .... @mac + ### Integer Comparison -CMPB_imm4_16 0101 0000 .... .... @param44_cmp_imm -CMPB_reg 0101 0001 .... .... @param44_cmp -CMPD_imm32 0000 0000 1001 .... .... .... .... .... .... .... .... .... @param4_32 -CMPD_imm4_16 0101 0110 .... .... @param44_cmp_imm -CMPD_reg 0101 0111 .... .... @param44_cmp -CMPW_imm4_16 0101 0010 .... .... @param44_cmp_imm -CMPW_reg 0101 0011 .... .... @param44_cmp +&cmp_imm rs imm width +&cmp_reg rs1 rs2 width + +@cmp_imm .... .... .... rs:4 &cmp_imm imm=%u4_load_s16 +@cmp_reg .... .... rs2:4 rs1:4 &cmp_reg +@cmp_imm32 .... .... .... rs:4 imm:s32 &cmp_imm +@cmpd_reg .... .... rs2:4 rs1:4 + +CMP_imm 0101 0000 .... .... @cmp_imm width=1 +CMP_reg 0101 0001 .... .... @cmp_reg width=1 +CMP_imm 0101 0010 .... .... @cmp_imm width=2 +CMP_reg 0101 0011 .... .... @cmp_reg width=2 +CMP_imm 0000 0000 1001 .... .... .... .... .... .... .... .... .... @cmp_imm32 width=4 +CMP_imm 0101 0110 .... .... @cmp_imm width=4 +CMPD_reg 0101 0111 .... .... @cmpd_reg + ### Logical and Boolean -ANDB_imm4_16 0010 0000 .... .... @param44_imm -ANDB_reg 0010 0001 .... .... @param44 -ANDW_imm4_16 0010 0010 .... .... @param44_imm -ANDW_reg 0010 0011 .... .... @param44 -ANDD_imm32 0000 0000 0100 .... .... .... .... .... .... .... .... .... @param4_32 -ANDD_rp 0000 0000 0001 0100 1011 ---- .... .... @escape2_dc -ORB_imm4_16 0010 0100 .... .... @param44_imm -ORB_reg 0010 0101 .... .... @param44 -ORW_imm4_16 0010 0110 .... .... @param44_imm -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 -XORW_reg 0010 1011 .... .... @param44 -XORD_imm32 0000 0000 0110 .... .... .... .... .... .... .... .... .... @param4_32 -XORD_rp 0000 0000 0001 0100 1010 ---- .... .... @escape2_dc +&logical_imm rd imm width +&logical_reg rd rs width + +@logical_imm .... .... .... rd:4 imm=%u4_load_s16 &logical_imm +@logical_reg .... .... rs:4 rd:4 &logical_reg +@logical_dword_rp .... .... .... .... .... .... rs:4 rd:4 + +AND_imm 0010 0000 .... .... @logical_imm width=1 +AND_reg 0010 0001 .... .... @logical_reg width=1 +AND_imm 0010 0010 .... .... @logical_imm width=2 +AND_reg 0010 0011 .... .... @logical_reg width=2 +ANDD_imm 0000 0000 0100 .... .... .... .... .... .... .... .... .... @arith_imm32 +ANDD_rp 0000 0000 0001 0100 1011 ---- .... .... @logical_dword_rp +OR_imm 0010 0100 .... .... @logical_imm width=1 +OR_reg 0010 0101 .... .... @logical_reg width=1 +OR_imm 0010 0110 .... .... @logical_imm width=2 +OR_reg 0010 0111 .... .... @logical_reg width=2 +ORD_imm 0000 0000 0101 .... .... .... .... .... .... .... .... .... @arith_imm32 +ORD_rp 0000 0000 0001 0100 1001 ---- .... .... @logical_dword_rp +XOR_imm 0010 1000 .... .... @logical_imm width=1 +XOR_reg 0010 1001 .... .... @logical_reg width=1 +XOR_imm 0010 1010 .... .... @logical_imm width=2 +XOR_reg 0010 1011 .... .... @logical_reg width=2 +XORD_imm 0000 0000 0110 .... .... .... .... .... .... .... .... .... @arith_imm32 +XORD_rp 0000 0000 0001 0100 1010 ---- .... .... @logical_dword_rp +SCOND 0000 1000 imm:4 rd:4 + ### Shifts -ASHUB_imm_l 0100 0000 0... .... @param34 -ASHUB_imm_r 0100 0000 1... .... @param34 -ASHUB_reg 0100 0001 .... .... @param44_count -ASHUD_imm_l 0100 110. .... .... @param54 -ASHUD_imm_r 0100 111. .... .... @param54 -ASHUD_rp 0100 1000 .... .... @param44_count -ASHUW_imm_l 0100 0010 .... .... @param44_imm -ASHUW_imm_r 0100 0011 .... .... @param44_imm -ASHUW_reg 0100 0101 .... .... @param44_count -LSHB_imm_r 0000 1001 1... .... @param34 -LSHB_reg 0100 0100 .... .... @param44_count -LSHD_imm_r 0100 101. .... .... @param54 -LSHD_rp 0100 0111 .... .... @param44_count -LSHW_imm_r 0100 1001 .... .... @param44_imm -LSHW_reg 0100 0110 .... .... @param44_count +&shift_imm rd imm width +&shift_reg rd rc width -### Jumps and Linkeage +@shift_imm3 .... .... . imm:3 rd:4 &shift_imm +@shift_imm4 .... .... imm:4 rd:4 &shift_imm +@shift_reg .... .... rc:4 rd:4 &shift_reg +@shiftd_rp .... .... rc:4 rd:4 +@shiftd_imm .... ... imm:5 rd:4 -BRCOND_disp8 0001 .... .... .... @param84 +ASHU_imm_l 0100 0000 0... .... @shift_imm3 width=1 +ASHU_imm_r 0100 0000 1... .... @shift_imm3 width=1 +ASHU_reg 0100 0001 .... .... @shift_reg width=1 +ASHU_imm_l 0100 0010 .... .... @shift_imm4 width=2 +ASHU_imm_r 0100 0011 .... .... @shift_imm4 width=2 +ASHU_reg 0100 0101 .... .... @shift_reg width=2 +ASHUD_imm_l 0100 110. .... .... @shiftd_imm +ASHUD_imm_r 0100 111. .... .... @shiftd_imm +ASHUD_rp 0100 1000 .... .... @shiftd_rp +LSH_imm_r 0000 1001 1... .... @shift_imm3 width=1 +LSH_reg 0100 0100 .... .... @shift_reg width=1 +LSH_imm_r 0100 1001 .... .... @shift_imm4 width=2 +LSH_reg 0100 0110 .... .... @shift_reg width=2 +LSHD_imm_r 0100 101. .... .... @shiftd_imm +LSHD_rp 0100 0111 .... .... @shiftd_rp + + +### Jumps and Linkeage ### + +%br_disp8 56:4 48:4 !function=get_disp8 + +@br_disp8 .... .... cond:4 .... disp=%br_disp8 + +BRCOND_disp8 0001 .... .... .... @br_disp8 + +EXCP 0000 0000 1100 id:4 -EXCP 0000 0000 1100 .... @param4 ### Load and Store ### %addr_abs20 32:20 !function=reloc_abs20 %addr_disp24 40:4 16:16 32:4 -&load rd ra dbase disp word_cnt -&load_rrp rd rrp disp word_cnt -&load_abs rd addr word_cnt -&load_ind_abs rd ri addr word_cnt +&load rd ra dbase disp width +&load_rrp rd rrp disp width +&load_abs rd addr width +&load_ind_abs rd ri addr width %load_disp20 40:4 16:s16 %load_disp14 40:6 46:2 52:2 32:4 @@ -151,60 +193,58 @@ EXCP 0000 0000 1100 .... @param4 #@load_disp14_rrp .... .... .... rrp:4 .... .... rd:4 .... disp=%load_disp14 &load_rrp { - LOAD_rrp 1011 1110 rd:4 rrp:4 word_cnt=1 disp=0 &load_rrp - LOAD 1011 1111 .... .... @load_disp16_reg word_cnt=1 dbase=1 disp=%load_u16 - LOAD 1011 .... .... .... @load_disp4_reg word_cnt=1 dbase=1 disp=%load_disp4 + LOAD_rrp 1011 1110 rd:4 rrp:4 width=1 disp=0 &load_rrp + LOAD 1011 1111 .... .... @load_disp16_reg width=1 dbase=1 disp=%load_u16 + LOAD 1011 .... .... .... @load_disp4_reg width=1 dbase=1 disp=%load_disp4 } UNIMPLEMENTED 1000 0110 01-- ---- ---- ---- ---- ---- # Unable to test, because of gnu assembler bug -LOAD 0000 0000 0001 0010 0100 .... .... .... .... .... .... .... word_cnt=1 dbase=0 @load_disp20_reg -LOAD 0000 0000 0001 1000 0100 .... .... .... .... .... .... .... word_cnt=1 dbase=0 @load_disp20_reg -LOAD 0000 0000 0001 0010 0101 .... .... .... .... .... .... .... word_cnt=1 dbase=1 @load_disp20_reg -LOAD 0000 0000 0001 1000 0101 .... .... .... .... .... .... .... word_cnt=1 dbase=1 @load_disp20_reg -LOAD_rrp 0000 0000 0001 0010 0110 .... .... .... .... .... .... .... word_cnt=1 @load_disp20_rrp -LOAD_abs 1000 1000 .... .... .... .... .... .... word_cnt=1 @load_abs20 -LOAD_ind_abs 1000 101. .... .... .... .... .... .... word_cnt=1 @load_ind_abs -LOAD_abs 0000 0000 0001 0010 0111 .... .... .... .... .... .... .... word_cnt=1 @load_abs24 +LOAD 0000 0000 0001 0010 0100 .... .... .... .... .... .... .... width=1 dbase=0 @load_disp20_reg +LOAD 0000 0000 0001 1000 0100 .... .... .... .... .... .... .... width=1 dbase=0 @load_disp20_reg +LOAD 0000 0000 0001 0010 0101 .... .... .... .... .... .... .... width=1 dbase=1 @load_disp20_reg +LOAD 0000 0000 0001 1000 0101 .... .... .... .... .... .... .... width=1 dbase=1 @load_disp20_reg +LOAD_rrp 0000 0000 0001 0010 0110 .... .... .... .... .... .... .... width=1 @load_disp20_rrp +LOAD_abs 1000 1000 .... .... .... .... .... .... width=1 @load_abs20 +LOAD_ind_abs 1000 101. .... .... .... .... .... .... width=1 @load_ind_abs +LOAD_abs 0000 0000 0001 0010 0111 .... .... .... .... .... .... .... width=1 @load_abs24 { - LOAD_rrp 1001 1110 rd:4 rrp:4 word_cnt=2 disp=0 &load_rrp - LOAD 1001 1111 .... .... @load_disp16_reg word_cnt=2 dbase=1 disp=%load_u16 - LOAD 1001 .... .... .... @load_disp4_reg word_cnt=2 dbase=1 disp=%load_disp4_shift + LOAD_rrp 1001 1110 rd:4 rrp:4 width=2 disp=0 &load_rrp + LOAD 1001 1111 .... .... @load_disp16_reg width=2 dbase=1 disp=%load_u16 + LOAD 1001 .... .... .... @load_disp4_reg width=2 dbase=1 disp=%load_disp4_shift } UNIMPLEMENTED 1000 0110 11-- ---- ---- ---- ---- ---- # Unable to test, because of gnu assembler bug -LOAD 0000 0000 0001 0010 1100 .... .... .... .... .... .... .... word_cnt=2 dbase=0 @load_disp20_reg -LOAD 0000 0000 0001 1000 1100 .... .... .... .... .... .... .... word_cnt=2 dbase=0 @load_disp20_reg -LOAD 0000 0000 0001 0010 1101 .... .... .... .... .... .... .... word_cnt=2 dbase=1 @load_disp20_reg -LOAD 0000 0000 0001 1000 1101 .... .... .... .... .... .... .... word_cnt=2 dbase=1 @load_disp20_reg -LOAD_rrp 0000 0000 0001 0010 1110 .... .... .... .... .... .... .... word_cnt=2 @load_disp20_rrp -LOAD_abs 1000 1001 .... .... .... .... .... .... word_cnt=2 @load_abs20 -LOAD_ind_abs 1000 111. .... .... .... .... .... .... word_cnt=2 @load_ind_abs -LOAD_abs 0000 0000 0001 0010 1111 .... .... .... .... .... .... .... word_cnt=2 @load_abs24 +LOAD 0000 0000 0001 0010 1100 .... .... .... .... .... .... .... width=2 dbase=0 @load_disp20_reg +LOAD 0000 0000 0001 1000 1100 .... .... .... .... .... .... .... width=2 dbase=0 @load_disp20_reg +LOAD 0000 0000 0001 0010 1101 .... .... .... .... .... .... .... width=2 dbase=1 @load_disp20_reg +LOAD 0000 0000 0001 1000 1101 .... .... .... .... .... .... .... width=2 dbase=1 @load_disp20_reg +LOAD_rrp 0000 0000 0001 0010 1110 .... .... .... .... .... .... .... width=2 @load_disp20_rrp +LOAD_abs 1000 1001 .... .... .... .... .... .... width=2 @load_abs20 +LOAD_ind_abs 1000 111. .... .... .... .... .... .... width=2 @load_ind_abs +LOAD_abs 0000 0000 0001 0010 1111 .... .... .... .... .... .... .... width=2 @load_abs24 { - LOAD_rrp 1010 1110 rd:4 rrp:4 word_cnt=4 disp=0 &load_rrp - LOAD 1010 1111 .... .... @load_disp16_reg word_cnt=4 dbase=1 disp=%load_u16 - LOAD 1010 .... .... .... @load_disp4_reg word_cnt=4 dbase=1 disp=%load_disp4_shift + LOAD_rrp 1010 1110 rd:4 rrp:4 width=4 disp=0 &load_rrp + LOAD 1010 1111 .... .... @load_disp16_reg width=4 dbase=1 disp=%load_u16 + LOAD 1010 .... .... .... @load_disp4_reg width=4 dbase=1 disp=%load_disp4_shift } UNIMPLEMENTED 1000 0110 10-- ---- ---- ---- ---- ---- # Unable to test, because of gnu assembler bug -LOAD 0000 0000 0001 0010 1000 .... .... .... .... .... .... .... word_cnt=4 dbase=0 @load_disp20_reg -LOAD 0000 0000 0001 1000 1000 .... .... .... .... .... .... .... word_cnt=4 dbase=0 @load_disp20_reg -LOAD 0000 0000 0001 0010 1001 .... .... .... .... .... .... .... word_cnt=4 dbase=1 @load_disp20_rp -LOAD 0000 0000 0001 1000 1001 .... .... .... .... .... .... .... word_cnt=4 dbase=1 @load_disp20_rp -LOAD_rrp 0000 0000 0001 0010 1010 .... .... .... .... .... .... .... word_cnt=4 @load_disp20_rrp -LOAD_abs 1000 0111 .... .... .... .... .... .... word_cnt=4 @load_abs20 -LOAD_ind_abs 1000 110. .... .... .... .... .... .... word_cnt=4 @load_ind_abs -LOAD_abs 0000 0000 0001 0010 1011 .... .... .... .... .... .... .... word_cnt=4 @load_abs24 +LOAD 0000 0000 0001 0010 1000 .... .... .... .... .... .... .... width=4 dbase=0 @load_disp20_reg +LOAD 0000 0000 0001 1000 1000 .... .... .... .... .... .... .... width=4 dbase=0 @load_disp20_reg +LOAD 0000 0000 0001 0010 1001 .... .... .... .... .... .... .... width=4 dbase=1 @load_disp20_rp +LOAD 0000 0000 0001 1000 1001 .... .... .... .... .... .... .... width=4 dbase=1 @load_disp20_rp +LOAD_rrp 0000 0000 0001 0010 1010 .... .... .... .... .... .... .... width=4 @load_disp20_rrp +LOAD_abs 1000 0111 .... .... .... .... .... .... width=4 @load_abs20 +LOAD_ind_abs 1000 110. .... .... .... .... .... .... width=4 @load_ind_abs +LOAD_abs 0000 0000 0001 0010 1011 .... .... .... .... .... .... .... width=4 @load_abs24 -&stor rs ra dbase disp word_cnt -&stor_rrp rs rrp disp word_cnt -&stor_abs rs addr word_cnt -&stor_ind_abs rs ri addr word_cnt +&stor rs ra dbase disp width +&stor_rrp rs rrp disp width +&stor_abs rs addr width +&stor_ind_abs rs ri addr width -&stor_imm imm ra dbase disp word_cnt -&stor_rrp_imm imm rrp disp word_cnt -&stor_abs_imm imm addr word_cnt -&stor_abs_rrp_imm imm ri addr word_cnt - -#&storm cnt pair +&stor_imm imm ra dbase disp width +&stor_rrp_imm imm rrp disp width +&stor_abs_imm imm addr width +&stor_abs_rrp_imm imm ri addr width %stor_disp20 40:s4 16:s16 %stor_disp14 40:6 46:2 52:2 32:4 @@ -231,65 +271,65 @@ LOAD_abs 0000 0000 0001 0010 1011 .... .... .... .... .... .... .... @stor_abs24_imm .... .... .... .... .... .... imm:4 .... .... .... .... .... addr=%addr_disp24 &stor_abs_imm { - STOR_rrp 1111 1110 rs:4 rrp:4 word_cnt=1 disp=0 &stor_rrp - STOR 1111 1111 .... .... @stor_disp16_reg word_cnt=1 dbase=1 disp=%load_u16 - STOR 1111 .... .... .... @stor_disp4_reg word_cnt=1 dbase=1 disp=%stor_disp4 + STOR_rrp 1111 1110 rs:4 rrp:4 width=1 disp=0 &stor_rrp + STOR 1111 1111 .... .... @stor_disp16_reg width=1 dbase=1 disp=%load_u16 + STOR 1111 .... .... .... @stor_disp4_reg width=1 dbase=1 disp=%stor_disp4 } UNIMPLEMENTED 1100 0110 01-- ---- ---- ---- ---- ---- # Unable to test, because of gnu assembler bug -STOR 0000 0000 0001 0011 0100 .... .... .... .... .... .... .... word_cnt=1 dbase=0 @stor_disp20_reg -STOR 0000 0000 0001 1001 0100 .... .... .... .... .... .... .... word_cnt=1 dbase=0 @stor_disp20_reg -STOR 0000 0000 0001 0011 0101 .... .... .... .... .... .... .... word_cnt=1 dbase=1 @stor_disp20_rp -STOR 0000 0000 0001 1001 0101 .... .... .... .... .... .... .... word_cnt=1 dbase=1 @stor_disp20_rp -STOR_rrp 0000 0000 0001 0011 0110 .... .... .... .... .... .... .... word_cnt=1 @stor_disp20_rrp -STOR_abs 1100 1000 .... .... .... .... .... .... word_cnt=1 @stor_abs20 -STOR_ind_abs 1100 101. .... .... .... .... .... .... word_cnt=1 @stor_ind_abs -STOR_abs 0000 0000 0001 0011 0111 .... .... .... .... .... .... .... word_cnt=1 @stor_abs24 -STOR_rrp_imm 1000 0110 00.. .... .... .... .... .... word_cnt=1 @stor_disp14_rrp_imm -STOR_imm 0000 0000 0001 0010 0000 .... .... .... .... .... .... .... word_cnt=1 dbase=0 @stor_disp20_reg_imm -STOR_imm 1000 0010 imm:4 ra:4 word_cnt=1 dbase=1 disp=0 &stor_imm -STOR_imm 1000 0011 .... .... word_cnt=1 dbase=0 disp=%load_u16 @stor_disp16_imm -STOR_imm 0000 0000 0001 0010 0001 .... .... .... .... .... .... .... word_cnt=1 dbase=1 @stor_disp20_rp_imm -STOR_rrp_imm 0000 0000 0001 0010 0010 .... .... .... .... .... .... .... word_cnt=1 @stor_disp20_rrp_imm -STOR_abs_imm 1000 0001 .... .... .... .... .... .... word_cnt=1 @stor_abs_imm -STOR_abs_rrp_imm 1000 010. .... .... .... .... .... .... word_cnt=1 @stor_abs_rrp_imm -STOR_abs_imm 0000 0000 0001 0010 0011 .... .... .... .... .... .... .... word_cnt=1 @stor_abs24_imm +STOR 0000 0000 0001 0011 0100 .... .... .... .... .... .... .... width=1 dbase=0 @stor_disp20_reg +STOR 0000 0000 0001 1001 0100 .... .... .... .... .... .... .... width=1 dbase=0 @stor_disp20_reg +STOR 0000 0000 0001 0011 0101 .... .... .... .... .... .... .... width=1 dbase=1 @stor_disp20_rp +STOR 0000 0000 0001 1001 0101 .... .... .... .... .... .... .... width=1 dbase=1 @stor_disp20_rp +STOR_rrp 0000 0000 0001 0011 0110 .... .... .... .... .... .... .... width=1 @stor_disp20_rrp +STOR_abs 1100 1000 .... .... .... .... .... .... width=1 @stor_abs20 +STOR_ind_abs 1100 101. .... .... .... .... .... .... width=1 @stor_ind_abs +STOR_abs 0000 0000 0001 0011 0111 .... .... .... .... .... .... .... width=1 @stor_abs24 +STOR_rrp_imm 1000 0110 00.. .... .... .... .... .... width=1 @stor_disp14_rrp_imm +STOR_imm 0000 0000 0001 0010 0000 .... .... .... .... .... .... .... width=1 dbase=0 @stor_disp20_reg_imm +STOR_imm 1000 0010 imm:4 ra:4 width=1 dbase=1 disp=0 &stor_imm +STOR_imm 1000 0011 .... .... width=1 dbase=0 disp=%load_u16 @stor_disp16_imm +STOR_imm 0000 0000 0001 0010 0001 .... .... .... .... .... .... .... width=1 dbase=1 @stor_disp20_rp_imm +STOR_rrp_imm 0000 0000 0001 0010 0010 .... .... .... .... .... .... .... width=1 @stor_disp20_rrp_imm +STOR_abs_imm 1000 0001 .... .... .... .... .... .... width=1 @stor_abs_imm +STOR_abs_rrp_imm 1000 010. .... .... .... .... .... .... width=1 @stor_abs_rrp_imm +STOR_abs_imm 0000 0000 0001 0010 0011 .... .... .... .... .... .... .... width=1 @stor_abs24_imm { - STOR_rrp 1101 1110 rs:4 rrp:4 word_cnt=2 disp=0 &stor_rrp - STOR 1101 1111 .... .... @stor_disp16_reg word_cnt=2 dbase=1 disp=%load_u16 - STOR 1101 .... .... .... @stor_disp4_reg word_cnt=2 dbase=1 disp=%stor_disp4 + STOR_rrp 1101 1110 rs:4 rrp:4 width=2 disp=0 &stor_rrp + STOR 1101 1111 .... .... @stor_disp16_reg width=2 dbase=1 disp=%load_u16 + STOR 1101 .... .... .... @stor_disp4_reg width=2 dbase=1 disp=%stor_disp4 } UNIMPLEMENTED 1100 0110 11-- ---- ---- ---- ---- ---- # Unable to test, because of gnu assembler bug -STOR 0000 0000 0001 0011 1100 .... .... .... .... .... .... .... word_cnt=2 dbase=0 @stor_disp20_reg -STOR 0000 0000 0001 1001 1100 .... .... .... .... .... .... .... word_cnt=2 dbase=0 @stor_disp20_reg -STOR 0000 0000 0001 0011 1101 .... .... .... .... .... .... .... word_cnt=2 dbase=1 @stor_disp20_rp -STOR 0000 0000 0001 1001 1101 .... .... .... .... .... .... .... word_cnt=2 dbase=1 @stor_disp20_rp -STOR_rrp 0000 0000 0001 0011 1110 .... .... .... .... .... .... .... word_cnt=2 @stor_disp20_rrp -STOR_abs 1100 1001 .... .... .... .... .... .... word_cnt=2 @stor_abs20 -STOR_ind_abs 1100 111. .... .... .... .... .... .... word_cnt=2 @stor_ind_abs -STOR_abs 0000 0000 0001 0011 1111 .... .... .... .... .... .... .... word_cnt=2 @stor_abs24 +STOR 0000 0000 0001 0011 1100 .... .... .... .... .... .... .... width=2 dbase=0 @stor_disp20_reg +STOR 0000 0000 0001 1001 1100 .... .... .... .... .... .... .... width=2 dbase=0 @stor_disp20_reg +STOR 0000 0000 0001 0011 1101 .... .... .... .... .... .... .... width=2 dbase=1 @stor_disp20_rp +STOR 0000 0000 0001 1001 1101 .... .... .... .... .... .... .... width=2 dbase=1 @stor_disp20_rp +STOR_rrp 0000 0000 0001 0011 1110 .... .... .... .... .... .... .... width=2 @stor_disp20_rrp +STOR_abs 1100 1001 .... .... .... .... .... .... width=2 @stor_abs20 +STOR_ind_abs 1100 111. .... .... .... .... .... .... width=2 @stor_ind_abs +STOR_abs 0000 0000 0001 0011 1111 .... .... .... .... .... .... .... width=2 @stor_abs24 { - STOR_rrp 1110 1110 rs:4 rrp:4 word_cnt=4 disp=0 &stor_rrp - STOR 1110 1111 .... .... @stor_disp16_reg word_cnt=4 dbase=1 disp=%load_u16 - STOR 1110 .... .... .... @stor_disp4_reg word_cnt=4 dbase=1 disp=%stor_disp4 + STOR_rrp 1110 1110 rs:4 rrp:4 width=4 disp=0 &stor_rrp + STOR 1110 1111 .... .... @stor_disp16_reg width=4 dbase=1 disp=%load_u16 + STOR 1110 .... .... .... @stor_disp4_reg width=4 dbase=1 disp=%stor_disp4 } UNIMPLEMENTED 1100 0110 10-- ---- ---- ---- ---- ---- # Unable to test, because of gnu assembler bug -STOR 0000 0000 0001 0011 1000 .... .... .... .... .... .... .... word_cnt=4 dbase=0 @stor_disp20_reg -STOR 0000 0000 0001 1001 1000 .... .... .... .... .... .... .... word_cnt=4 dbase=0 @stor_disp20_reg -STOR 0000 0000 0001 0011 1001 .... .... .... .... .... .... .... word_cnt=4 dbase=1 @stor_disp20_rp -STOR 0000 0000 0001 1001 1001 .... .... .... .... .... .... .... word_cnt=4 dbase=1 @stor_disp20_rp -STOR_rrp 0000 0000 0001 0011 1010 .... .... .... .... .... .... .... word_cnt=4 @stor_disp20_rrp -STOR_abs 1100 0111 .... .... .... .... .... .... word_cnt=4 @stor_abs20 -STOR_ind_abs 1100 110. .... .... .... .... .... .... word_cnt=4 @stor_ind_abs -STOR_abs 0000 0000 0001 0011 1011 .... .... .... .... .... .... .... word_cnt=4 @stor_abs24 -STOR_rrp_imm 1100 0110 00.. .... .... .... .... .... word_cnt=4 @stor_disp14_rrp_imm -STOR_imm 0000 0000 0001 0011 0000 .... .... .... .... .... .... .... word_cnt=4 dbase=0 @stor_disp20_reg_imm -STOR_imm 1100 0010 imm:4 ra:4 word_cnt=4 dbase=1 disp=0 &stor_imm -STOR_imm 1100 0011 .... .... word_cnt=4 dbase=0 disp=%load_u16 @stor_disp16_imm -STOR_imm 0000 0000 0001 0011 0001 .... .... .... .... .... .... .... word_cnt=4 dbase=1 @stor_disp20_rp_imm -STOR_rrp_imm 0000 0000 0001 0011 0010 .... .... .... .... .... .... .... word_cnt=4 @stor_disp20_rrp_imm -STOR_abs_imm 1100 0001 .... .... .... .... .... .... word_cnt=4 @stor_abs_imm -STOR_abs_rrp_imm 1100 010. .... .... .... .... .... .... word_cnt=4 @stor_abs_rrp_imm -STOR_abs_imm 0000 0000 0001 0011 0011 .... .... .... .... .... .... .... word_cnt=4 @stor_abs24_imm +STOR 0000 0000 0001 0011 1000 .... .... .... .... .... .... .... width=4 dbase=0 @stor_disp20_reg +STOR 0000 0000 0001 1001 1000 .... .... .... .... .... .... .... width=4 dbase=0 @stor_disp20_reg +STOR 0000 0000 0001 0011 1001 .... .... .... .... .... .... .... width=4 dbase=1 @stor_disp20_rp +STOR 0000 0000 0001 1001 1001 .... .... .... .... .... .... .... width=4 dbase=1 @stor_disp20_rp +STOR_rrp 0000 0000 0001 0011 1010 .... .... .... .... .... .... .... width=4 @stor_disp20_rrp +STOR_abs 1100 0111 .... .... .... .... .... .... width=4 @stor_abs20 +STOR_ind_abs 1100 110. .... .... .... .... .... .... width=4 @stor_ind_abs +STOR_abs 0000 0000 0001 0011 1011 .... .... .... .... .... .... .... width=4 @stor_abs24 +STOR_rrp_imm 1100 0110 00.. .... .... .... .... .... width=4 @stor_disp14_rrp_imm +STOR_imm 0000 0000 0001 0011 0000 .... .... .... .... .... .... .... width=4 dbase=0 @stor_disp20_reg_imm +STOR_imm 1100 0010 imm:4 ra:4 width=4 dbase=1 disp=0 &stor_imm +STOR_imm 1100 0011 .... .... width=4 dbase=0 disp=%load_u16 @stor_disp16_imm +STOR_imm 0000 0000 0001 0011 0001 .... .... .... .... .... .... .... width=4 dbase=1 @stor_disp20_rp_imm +STOR_rrp_imm 0000 0000 0001 0011 0010 .... .... .... .... .... .... .... width=4 @stor_disp20_rrp_imm +STOR_abs_imm 1100 0001 .... .... .... .... .... .... width=4 @stor_abs_imm +STOR_abs_rrp_imm 1100 010. .... .... .... .... .... .... width=4 @stor_abs_rrp_imm +STOR_abs_imm 0000 0000 0001 0011 0011 .... .... .... .... .... .... .... width=4 @stor_abs24_imm &ldstm cnt pair diff --git a/target/cr16c/translate.c b/target/cr16c/translate.c index 953b4351ab..064f7278e3 100644 --- a/target/cr16c/translate.c +++ b/target/cr16c/translate.c @@ -17,6 +17,7 @@ #include "exec/helper-info.c.inc" #undef HELPER_H +/* Representation of the condition encoding */ enum { CR16C_COND_EQ, CR16C_COND_NE, @@ -42,6 +43,7 @@ typedef struct DisasContext { } DisasContext; +/* Registers */ static TCGv pc; static TCGv sp; static TCGv f_n; @@ -81,6 +83,20 @@ static uint64_t decode_load_bytes(DisasContext *ctx, uint64_t insn, int i, int n } +/*** Instruction translations ***/ + +static int16_t u4_load_s16(DisasContext *ctx, int val) { + if (val == 0x9) { + return -1; + } + else if (val == 0xB) { + int16_t val_ld = cpu_ldsw_le_data(ctx->env, ctx->base.pc_next); + ctx->base.pc_next += 2; + return val_ld; + } + return val; +} + static uint16_t load_u16(DisasContext *ctx) { uint16_t imm = cpu_lduw_code(ctx->env, ctx->base.pc_next); ctx->base.pc_next += 2; @@ -91,6 +107,17 @@ static uint8_t get_disp4(DisasContext *ctx, uint8_t disp) { return disp << 1; } +static uint16_t get_disp8(DisasContext* ctx, uint8_t disp) { + if (disp == 0x80) { + uint16_t disp_esc = cpu_lduw_code(ctx->env, ctx->base.pc_next) >> 1; + ctx->base.pc_next += 2; + return disp_esc; + } + else { + return disp; + } +}; + static uint32_t reloc_abs20(DisasContext *ctx, uint32_t addr) { if (addr > 0xEFFFF) { addr |= 0xF00000; @@ -101,65 +128,18 @@ static uint32_t reloc_abs20(DisasContext *ctx, uint32_t addr) { // Include generated decodetree function declarations #include "decode-insn.c.inc" -static uint16_t get_imm4(DisasContext* ctx, uint8_t imm) { - if (imm == 11) { - uint16_t imm_esc = cpu_lduw_code(ctx->env, ctx->base.pc_next); - if (imm_esc << 15 == 1) { - imm_esc = -((~imm_esc)+1); - } - ctx->base.pc_next += 2; - return imm_esc; - } - else if (imm == 9) { - return -1; - } - else { - return imm; - } -} +/* Moves */ -static int16_t u16_to_s16(uint16_t num) { - if ((num >> 15) == 1) { - return -((~num)+1); - } - return 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_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, 8); - return true; -} - -static bool trans_MOVD_imm20(DisasContext* ctx, arg_MOVD_imm20* a) { - tcg_gen_movi_i32(r[a->rd], a->imm); - if (a->rd < CR16C_FIRST_32B_REG) { +static bool trans_MOV_imm(DisasContext* ctx, arg_MOV_imm* a) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], tcg_constant_i32(a->imm), 0, a->width * 8); + if (a->width == 4 && 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); - if (a->rd < CR16C_FIRST_32B_REG) { - tcg_gen_movi_i32(r[a->rd + 1], a->imm >> 16); - } - return true; -} - -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); - if (a->rd < CR16C_FIRST_32B_REG) { - tcg_gen_movi_i32(r[a->rd + 1], 0); - } - +static bool trans_MOV_reg(DisasContext* ctx, arg_MOV_reg* a) { + tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rs], 0, a->width * 8); return true; } @@ -181,17 +161,6 @@ static bool trans_MOVD_reg(DisasContext* ctx, arg_MOVD_reg* a) { 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_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_deposit_i32(r[a->rd], r[a->rd], r[a->rs], 0, 16); - return true; -} - static bool trans_MOVXB(DisasContext* ctx, arg_MOVXB* a) { TCGv_i32 temp = tcg_temp_new_i32(); tcg_gen_ext8s_i32(temp, r[a->rs]); @@ -225,36 +194,35 @@ static bool trans_MOVZW(DisasContext* ctx, arg_MOVZW* a) { /* Integer Arithmetic */ -static bool gen_ADDB_imm4_16(DisasContext* ctx, TCGv reg, uint16_t imm, bool plus_carry) { +static void gen_ADD_imm(TCGv_i32 rd, int32_t imm, bool add_carry, uint8_t width) { TCGv temp = tcg_temp_new(); - tcg_gen_andi_i32(temp, reg, 0xFF); - tcg_gen_addi_i32(temp, temp, imm); + tcg_gen_andi_i32(temp, rd, (1 << width * 8) - 1); + tcg_gen_addi_i32(temp, temp, imm & ((1 << width * 8) - 1)); - if(plus_carry) { + if(add_carry) { tcg_gen_andi_i32(f_c, f_c, 1); tcg_gen_add_i32(temp, temp, f_c); } /* Carry flag */ - tcg_gen_shri_i32(f_c, temp, 8); + tcg_gen_shri_i32(f_c, temp, width * 8); /* Overflow flag */ - tcg_gen_xor_i32(f_f, temp, reg); - if(imm & 0x80) { - tcg_gen_and_i32(f_f, f_f, reg); + tcg_gen_xor_i32(f_f, temp, rd); + if(imm < 0) { + tcg_gen_and_i32(f_f, f_f, rd); } else { - tcg_gen_andc_i32(f_f, f_f, reg); + tcg_gen_andc_i32(f_f, f_f, rd); } - tcg_gen_shri_i32(f_f, f_f, 7); + tcg_gen_shri_i32(f_f, f_f, width*8 - 1); - tcg_gen_deposit_i32(reg, reg, temp, 0, 8); - - return true; + tcg_gen_deposit_i32(rd, rd, temp, 0, width*8); } -static bool gen_ADDB_reg(DisasContext* ctx, TCGv reg1, TCGv reg2, bool plus_carry) { + +static void gen_ADD_reg(TCGv reg1, TCGv reg2, bool plus_carry, uint8_t width) { TCGv temp1 = tcg_temp_new_i32(); TCGv temp2 = tcg_temp_new_i32(); TCGv tempf_f = tcg_temp_new_i32(); @@ -263,8 +231,8 @@ static bool gen_ADDB_reg(DisasContext* ctx, TCGv reg1, TCGv reg2, bool plus_carr tcg_gen_eqv_i32(tempf_f, reg1, reg2); /* Clear potential top bits */ - tcg_gen_andi_i32(temp1, reg1, 0x00FF); - tcg_gen_andi_i32(temp2, reg2, 0x00FF); + tcg_gen_andi_i32(temp1, reg1, (1 << width * 8) - 1); + tcg_gen_andi_i32(temp2, reg2, (1 << width * 8) - 1); tcg_gen_add_i32(temp1, temp1, temp2); @@ -273,107 +241,18 @@ static bool gen_ADDB_reg(DisasContext* ctx, TCGv reg1, TCGv reg2, bool plus_carr tcg_gen_add_i32(temp1, temp1, f_c); } - tcg_gen_deposit_i32(reg1, reg1, temp1, 0, 8); + tcg_gen_deposit_i32(reg1, reg1, temp1, 0, width*8); /* Carry flag */ - tcg_gen_shri_i32(f_c, temp1, 8); + tcg_gen_shri_i32(f_c, temp1, width*8); /* Overflow flag */ tcg_gen_xor_i32(f_f, reg1, reg2); tcg_gen_and_i32(f_f, f_f, tempf_f); - tcg_gen_shri_i32(f_f, f_f, 7); - - return true; + tcg_gen_shri_i32(f_f, f_f, width*8-1); } -static bool gen_ADDW_imm4_16(TCGv reg1, uint16_t imm, bool plus_carry) { - TCGv temp = tcg_temp_new_i32(); - - tcg_gen_andi_i32(temp, reg1, 0xFFFF); - - tcg_gen_addi_i32(temp, temp, imm); - - - if(plus_carry) { - tcg_gen_andi_i32(f_c, f_c, 1); - tcg_gen_add_i32(temp, temp, f_c); - } - - /* Carry flag */ - tcg_gen_shri_i32(f_c, temp, 16); - - /* Overflow flag */ - tcg_gen_xor_i32(f_f, temp, reg1); - if(imm & 0x8000) { - tcg_gen_and_i32(f_f, f_f, reg1); - } - else { - tcg_gen_andc_i32(f_f, f_f, reg1); - } - tcg_gen_shri_i32(f_f, f_f, 15); - - 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(temp_res, reg1, 0xFFFF); - tcg_gen_andi_i32(reg2, reg2, 0xFFFF); - - 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(temp_res, temp_res, f_c); - } - - /* Carry flag */ - tcg_gen_shri_i32(f_c, temp_res, 16); - - /* Overflow flag */ - 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; -} - -static bool trans_ADDB_imm4_16(DisasContext *ctx, arg_ADDB_imm4_16 *a) { - uint32_t imm = get_imm4(ctx, a->imm) & 0xFF; - return gen_ADDB_imm4_16(ctx, r[a->rd], imm, false); -} - -static bool trans_ADDB_reg(DisasContext *ctx, arg_ADDB_reg *a) { - return gen_ADDB_reg(ctx, r[a->rd], r[a->rs], false); -} - -static bool trans_ADDCB_imm4_16(DisasContext *ctx, arg_ADDCB_imm4_16 *a) { - uint32_t imm = get_imm4(ctx, a->imm) & 0xFF; - return gen_ADDB_imm4_16(ctx, r[a->rd], imm, true); -} - -static bool trans_ADDCB_reg(DisasContext *ctx, arg_ADDCB_reg *a) { - return gen_ADDB_reg(ctx, r[a->rd], r[a->rs], true); -} - -static bool trans_ADDCW_imm4_16(DisasContext *ctx, arg_ADDCW_imm4_16 *a) { - uint32_t imm = get_imm4(ctx, a->imm) & 0xFFFF; - return gen_ADDW_imm4_16(r[a->rd], imm, true); -} - -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(int regnl, uint32_t imm) { +static void gen_ADDD_imm(int regnl, int32_t imm) { TCGv_i64 temp_res = tcg_temp_new_i64(); TCGv_i32 temp_h = tcg_temp_new_i32(); @@ -396,7 +275,7 @@ static bool gen_ADDD_imm(int regnl, uint32_t imm) { tcg_gen_extrh_i64_i32(f_c, temp_res); /* Overflow flag */ - if (imm & 0x80000000) { + if (imm < 0) { tcg_gen_andc_i32(f_f, temp_h, regl); } else { @@ -407,8 +286,6 @@ static bool gen_ADDD_imm(int regnl, uint32_t imm) { if (regnl < CR16C_FIRST_32B_REG) { tcg_gen_shri_i32(regh, regl, 16); } - - return true; } static bool gen_ADDD_rp(int rdn, TCGv_i32 rs, bool plus_one) { @@ -454,17 +331,19 @@ static bool gen_ADDD_rp(int rdn, TCGv_i32 rs, bool plus_one) { return true; } -static bool trans_ADDD_imm20(DisasContext* ctx, arg_ADDD_imm20 *a) { - return gen_ADDD_imm(a->rd, a->imm); +static bool trans_ADD_imm(DisasContext *ctx, arg_ADD_imm *a) { + gen_ADD_imm(r[a->rd], a->imm, a->add_carry, a->width); + return true; } -static bool trans_ADDD_imm32(DisasContext *ctx, arg_ADDD_imm32 *a) { - return gen_ADDD_imm(a->rd, a->imm); +static bool trans_ADD_reg(DisasContext *ctx, arg_ADD_reg *a) { + gen_ADD_reg(r[a->rd], r[a->rs], a->add_carry, a->width); + return true; } -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(a->rd, imm); +static bool trans_ADDD_imm(DisasContext *ctx, arg_ADDD_imm *a) { + gen_ADDD_imm(a->rd, a->imm); + return true; } static bool trans_ADDD_rp(DisasContext *ctx, arg_ADDD_rp *a) { @@ -475,52 +354,139 @@ static bool trans_ADDD_rp(DisasContext *ctx, arg_ADDD_rp *a) { return true; } -static bool trans_ADDUB_imm4_16(DisasContext *ctx, arg_ADDUB_imm4_16 *a) { +static bool trans_ADDU_imm(DisasContext *ctx, arg_ADDU_imm *a) { TCGv temp = tcg_temp_new_i32(); - uint16_t imm = a->imm; - tcg_gen_addi_i32(temp, r[a->rd], imm); - tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 8); + tcg_gen_addi_i32(temp, r[a->rd], a->imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, a->width*8); return true; } -static bool trans_ADDUB_reg(DisasContext *ctx, arg_ADDUB_reg *a) { +static bool trans_ADDU_reg(DisasContext *ctx, arg_ADDU_reg *a) { TCGv 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, 8); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, a->width*8); return true; } -static bool trans_ADDUW_imm4_16(DisasContext *ctx, arg_ADDUW_imm4_16 *a) { - uint32_t imm = get_imm4(ctx, a->imm) & 0xFFFF; + +static bool trans_MUL_imm(DisasContext *ctx, arg_MUL_imm *a) { TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_addi_i32(temp, r[a->rd], imm); + tcg_gen_andi_i32(temp, r[a->rd], (1 << (a->width*8)) - 1); + tcg_gen_muli_i32(temp, temp, a->imm); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, a->width*8); + + return true; +} + +static bool trans_MULB_reg(DisasContext *ctx, arg_MULB_reg *a) { + TCGv_i32 temp1 = tcg_temp_new_i32(); + TCGv_i32 temp2 = tcg_temp_new_i32(); + + tcg_gen_andi_i32(temp1, r[a->rd], 0xFF); + tcg_gen_andi_i32(temp2, r[a->rs], 0xFF); + tcg_gen_mul_i32(temp1, temp1, temp2); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp1, 0, 8); + + return true; +} + +static bool trans_MULSB_reg(DisasContext *ctx, arg_MULSB_reg *a) { + TCGv_i32 temp1 = tcg_temp_new_i32(); + TCGv_i32 temp2 = tcg_temp_new_i32(); + + 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; +} + +static bool trans_MULSW_reg(DisasContext *ctx, arg_MULSW_reg *a) { + TCGv_i32 rdl = r[a->rd]; + TCGv_i32 rdh = r[a->rd+1]; + + 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]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(rdh, rdl, 16); + } + + return true; +} + +static bool trans_MULUW_reg(DisasContext *ctx, arg_MULUW_reg *a) { + TCGv_i32 rdl = r[a->rd]; + TCGv_i32 rdh = r[a->rd+1]; + + 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]); + if (a->rd < CR16C_FIRST_32B_REG) { + tcg_gen_shri_i32(rdh, rdl, 16); + } + + return true; +} + +static bool trans_MULW_reg(DisasContext *ctx, arg_MULW_reg *a) { + 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; } -static bool trans_ADDUW_reg(DisasContext *ctx, arg_ADDUW_reg *a) { - 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); +static bool trans_SUB_imm(DisasContext *ctx, arg_SUB_imm *a) { + int32_t imm = -a->imm; + if (a->add_carry) { + imm--; + tcg_gen_xori_i32(f_c, f_c, 1); + } + + gen_ADD_imm(r[a->rd], imm, a->add_carry, a->width); + tcg_gen_xori_i32(f_c, f_c, 1); return true; } -static bool trans_ADDW_imm4_16(DisasContext *ctx, arg_ADDW_imm4_16 *a) { - uint32_t imm = get_imm4(ctx, a->imm) & 0xFFFF; - - return gen_ADDW_imm4_16(r[a->rd], imm, false); +static bool trans_SUB_reg(DisasContext *ctx, arg_SUB_reg *a) { + TCGv_i32 temp = tcg_temp_new_i32(); + if (a->add_carry) { + tcg_gen_xori_i32(f_c, f_c, 1); + tcg_gen_xori_i32(temp, r[a->rs], (1 << (a->width*8)) - 1); + } else { + tcg_gen_neg_i32(temp, r[a->rs]); + } + gen_ADD_reg(r[a->rd], temp, a->add_carry, a->width); + tcg_gen_xori_i32(f_c, f_c, 1); + return true; } -static bool trans_ADDW_reg(DisasContext *ctx, arg_ADDW_reg *a) { - return gen_ADDW_reg(r[a->rd], r[a->rs], false); +static bool trans_SUBD_rp(DisasContext *ctx, arg_SUBD_rp *a) { + TCGv_i32 templ = tcg_temp_new_i32(); + 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_imm(DisasContext *ctx, arg_SUBD_imm *a) { + gen_ADDD_imm(a->rd, -a->imm); + tcg_gen_xori_i32(f_c, f_c, 1); + return true; +} + + /* TODO: This is quite certainly a bad implementation */ static bool trans_MACQW(DisasContext *ctx, arg_MACQW *a) { TCGv temp_l = tcg_temp_new_i32(); @@ -641,173 +607,6 @@ static bool trans_MACSW(DisasContext *ctx, arg_MACSW *a) { return true; } -static bool trans_MULB_imm4_16(DisasContext *ctx, arg_MULB_imm4_16 *a) { - int32_t imm = (get_imm4(ctx, a->imm) << 24) >> 24; - TCGv_i32 temp = tcg_temp_new_i32(); - - tcg_gen_andi_i32(temp, r[a->rd], 0xFF); - tcg_gen_muli_i32(temp, temp, imm); - tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 8); - - return true; -} - -static bool trans_MULB_reg(DisasContext *ctx, arg_MULB_reg *a) { - TCGv_i32 temp1 = tcg_temp_new_i32(); - TCGv_i32 temp2 = tcg_temp_new_i32(); - - tcg_gen_andi_i32(temp1, r[a->rd], 0xFF); - tcg_gen_andi_i32(temp2, r[a->rs], 0xFF); - tcg_gen_mul_i32(temp1, temp1, temp2); - tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp1, 0, 8); - - return true; -} - -static bool trans_MULSB_reg(DisasContext *ctx, arg_MULSB_reg *a) { - TCGv_i32 temp1 = tcg_temp_new_i32(); - TCGv_i32 temp2 = tcg_temp_new_i32(); - - 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; -} - -static bool trans_MULSW_reg(DisasContext *ctx, arg_MULSW_reg *a) { - TCGv_i32 rdl = r[a->rd]; - TCGv_i32 rdh = r[a->rd+1]; - - 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]); - if (a->rd < CR16C_FIRST_32B_REG) { - tcg_gen_shri_i32(rdh, rdl, 16); - } - - return true; -} - -static bool trans_MULUW_reg(DisasContext *ctx, arg_MULUW_reg *a) { - TCGv_i32 rdl = r[a->rd]; - TCGv_i32 rdh = r[a->rd+1]; - - 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]); - 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(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) { - 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; -} - -static bool trans_SUBB_imm4_16(DisasContext *ctx, arg_SUBB_imm4_16 *a) { - uint32_t imm = ((~get_imm4(ctx, a->imm))+1) & 0xFF; - gen_ADDB_imm4_16(ctx, r[a->rd], imm, false); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBB_reg(DisasContext *ctx, arg_SUBB_reg *a) { - TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_neg_i32(temp, r[a->rs]); - gen_ADDB_reg(ctx, r[a->rd], temp, false); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBCB_imm4_16(DisasContext *ctx, arg_SUBCB_imm4_16 *a) { - uint32_t imm = ((~get_imm4(ctx, a->imm))) & 0xFF; - - tcg_gen_xori_i32(f_c, f_c, 1); - - gen_ADDB_imm4_16(ctx, r[a->rd], imm, true); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBCB_reg(DisasContext *ctx, arg_SUBCB_reg *a) { - TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_xori_i32(f_c, f_c, 1); - tcg_gen_xori_i32(temp, r[a->rs], 0xFF); - gen_ADDB_reg(ctx, r[a->rd], temp, true); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBCW_imm4_16(DisasContext *ctx, arg_SUBCW_imm4_16 *a) { - uint32_t imm = (~get_imm4(ctx, a->imm)); - - tcg_gen_xori_i32(f_c, f_c, 1); - - gen_ADDW_imm4_16(r[a->rd], imm, true); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBCW_reg(DisasContext *ctx, arg_SUBCW_reg *a) { - TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_xori_i32(f_c, f_c, 1); - tcg_gen_xori_i32(temp, r[a->rs], 0xFFFF); - gen_ADDW_reg(r[a->rd], temp, true); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBD_reg(DisasContext *ctx, arg_SUBD_reg *a) { - TCGv_i32 templ = tcg_temp_new_i32(); - 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(a->rd, imm); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBW_imm4_16(DisasContext *ctx, arg_SUBW_imm4_16 *a) { - uint32_t imm = (~get_imm4(ctx, a->imm))+1; - gen_ADDW_imm4_16(r[a->rd], imm, false); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - -static bool trans_SUBW_reg(DisasContext *ctx, arg_SUBW_reg *a) { - TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_neg_i32(temp, r[a->rs]); - gen_ADDW_reg(r[a->rd], temp, false); - tcg_gen_xori_i32(f_c, f_c, 1); - return true; -} - /* Integer Comparison */ @@ -817,47 +616,41 @@ static void gen_cmp(TCGv_i32 src1, TCGv_i32 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 = u16_to_s16(get_imm4(ctx, a->imm)); +static bool trans_CMP_imm(DisasContext *ctx, arg_CMP_imm *a) { TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_ext8s_i32(temp, r[a->rs]); + if (a->width == 1) { + tcg_gen_ext8s_i32(temp, r[a->rs]); + } + else if (a->width == 2) { + tcg_gen_ext16s_i32(temp, r[a->rs]); + } + else if (a->rs < CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(temp, r[a->rs], r[a->rs+1], 16, 16); + } + else { + tcg_gen_mov_i32(temp, r[a->rs]); + } - gen_cmp(tcg_constant_i32(imm), temp); + gen_cmp(tcg_constant_i32(a->imm), temp); return true; } -static bool trans_CMPB_reg(DisasContext *ctx, arg_CMPB_reg *a) { +static bool trans_CMP_reg(DisasContext *ctx, arg_CMP_reg *a) { TCGv_i32 temp1 = tcg_temp_new_i32(); TCGv_i32 temp2 = tcg_temp_new_i32(); - tcg_gen_ext8s_i32(temp1, r[a->rs2]); - tcg_gen_ext8s_i32(temp2, r[a->rs1]); - - gen_cmp(temp1, temp2); - - return true; -} - -static bool trans_CMPD_imm4_16(DisasContext *ctx, arg_CMPD_imm4_16 *a) { - int32_t imm = u16_to_s16(get_imm4(ctx, a->imm)); - - 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->width == 1) { + tcg_gen_ext8s_i32(temp1, r[a->rs1]); + tcg_gen_ext8s_i32(temp2, r[a->rs2]); + } + else if (a->width == 2) { + tcg_gen_ext16s_i32(temp1, r[a->rs1]); + tcg_gen_ext16s_i32(temp2, r[a->rs2]); } - gen_cmp(tcg_constant_i32(imm), r[a->rs]); - - return true; -} - -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(tcg_constant_i32(a->imm), r[a->rd]); + gen_cmp(temp2, temp1); return true; } @@ -875,59 +668,23 @@ static bool trans_CMPD_reg(DisasContext *ctx, arg_CMPD_reg *a) { 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; -} - /* Logical and Boolean */ -static bool trans_ANDB_imm4_16(DisasContext *ctx, arg_ANDB_imm4_16 *a) { - uint32_t imm = ((uint32_t)get_imm4(ctx, a->imm)) | 0xFFFFFF00; +static bool trans_AND_imm(DisasContext *ctx, arg_AND_imm *a) { + int32_t imm = (-(1 << (a->width*8))) | a->imm; tcg_gen_andi_i32(r[a->rd], r[a->rd], imm); return true; } -static bool trans_ANDB_reg(DisasContext *ctx, arg_ANDB_reg *a) { +static bool trans_AND_reg(DisasContext *ctx, arg_AND_reg *a) { TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_ori_i32(temp, r[a->rs], 0xFFFFFF00); + tcg_gen_ori_i32(temp, r[a->rs], -(1 << (a->width*8))); 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) { - 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) { - 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) { +static bool trans_ANDD_imm(DisasContext *ctx, arg_ANDD_imm *a) { tcg_gen_andi_i32(r[a->rd], r[a->rd], a->imm); if (a->rd < CR16C_FIRST_32B_REG) { tcg_gen_andi_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); @@ -955,33 +712,19 @@ static bool trans_ANDD_rp(DisasContext *ctx, arg_ANDD_rp *a) { return true; } -static bool trans_ORB_imm4_16(DisasContext *ctx, arg_ORB_imm4_16 *a) { - uint16_t imm = ((uint32_t)get_imm4(ctx, a->imm)) & 0xFF; - tcg_gen_ori_i32(r[a->rd], r[a->rd], imm); +static bool trans_OR_imm(DisasContext *ctx, arg_OR_imm *a) { + tcg_gen_ori_i32(r[a->rd], r[a->rd], a->imm & ((1 << (a->width*8)) - 1)); return true; } -static bool trans_ORB_reg(DisasContext *ctx, arg_ORB_reg *a) { +static bool trans_OR_reg(DisasContext *ctx, arg_OR_reg *a) { TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_andi_i32(temp, r[a->rs], 0xFF); + tcg_gen_andi_i32(temp, r[a->rs], (1 << (a->width*8)) - 1); tcg_gen_or_i32(r[a->rd], temp, r[a->rd]); return true; } -static bool trans_ORW_imm4_16(DisasContext *ctx, arg_ORW_imm4_16 *a) { - uint16_t imm = get_imm4(ctx, a->imm); - tcg_gen_ori_i32(r[a->rd], r[a->rd], imm); - return true; -} - -static bool trans_ORW_reg(DisasContext *ctx, arg_ORW_reg *a) { - 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) { +static bool trans_ORD_imm(DisasContext *ctx, arg_ORD_imm *a) { tcg_gen_ori_i32(r[a->rd], r[a->rd], a->imm); if (a->rd < CR16C_FIRST_32B_REG) { tcg_gen_ori_i32(r[a->rd+1], r[a->rd+1], a->imm >> 16); @@ -1009,6 +752,46 @@ static bool trans_ORD_rp(DisasContext *ctx, arg_ORD_rp *a) { return true; } +static bool trans_XOR_imm(DisasContext *ctx, arg_XOR_imm *a) { + tcg_gen_xori_i32(r[a->rd], r[a->rd], a->imm & ((1 << (a->width*8)) - 1)); + return true; +} + +static bool trans_XOR_reg(DisasContext *ctx, arg_XOR_reg *a) { + TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_andi_i32(temp, r[a->rs], (1 << (a->width*8)) - 1); + tcg_gen_xor_i32(r[a->rd], temp, r[a->rd]); + return true; +} + +static bool trans_XORD_imm(DisasContext *ctx, arg_XORD_imm *a) { + tcg_gen_xori_i32(r[a->rd], r[a->rd], a->imm); + 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_XORD_rp *a) { + 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; +} + static bool trans_SCOND(DisasContext *ctx, arg_SCOND *a) { switch (a->imm) { case CR16C_COND_EQ: @@ -1060,88 +843,45 @@ static bool trans_SCOND(DisasContext *ctx, arg_SCOND *a) { 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); - return true; -} - -static bool trans_XORB_reg(DisasContext *ctx, arg_ORB_reg *a) { - TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_andi_i32(temp, r[a->rs], 0xFF); - tcg_gen_xor_i32(r[a->rd], temp, r[a->rd]); - return true; -} - -static bool trans_XORW_imm4_16(DisasContext *ctx, arg_ORW_imm4_16 *a) { - 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) { - 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); - 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) { - 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; -} - /* Shifts */ -static bool trans_ASHUB_imm_l(DisasContext *ctx, arg_ASHUB_imm_l *a) { +static bool trans_ASHU_imm_l(DisasContext *ctx, arg_ASHU_imm_l *a) { 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, 8); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, a->width*8); return true; } -static bool trans_ASHUB_imm_r(DisasContext *ctx, arg_ASHUB_imm_r *a) { - int16_t imm = (~a->imm+1) & 0x7; +static bool trans_ASHU_imm_r(DisasContext *ctx, arg_ASHU_imm_r *a) { + int32_t imm = (-a->imm) & (a->width == 1 ? 0x7 : 0xF); TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_ext8s_i32(temp, r[a->rd]); + if (a->width == 1) { + tcg_gen_ext8s_i32(temp, r[a->rd]); + } + else { /* a->width == 2 */ + 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, 8); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, a->width*8); return true; } -static bool trans_ASHUB_reg(DisasContext *ctx, arg_ASHUB_reg *a) { +static bool trans_ASHU_reg(DisasContext *ctx, arg_ASHU_reg *a) { TCGv_i32 temp_dest = tcg_temp_new_i32(); TCGv_i32 temp_count = tcg_temp_new_i32(); TCGv_i32 temp_resl = tcg_temp_new_i32(); TCGv_i32 temp_resr = temp_dest; - tcg_gen_ext8s_i32(temp_dest, r[a->rd]); + if (a->width == 1) { + tcg_gen_ext8s_i32(temp_dest, r[a->rd]); + } + else { /* a->width == 2 */ + tcg_gen_ext16s_i32(temp_dest, r[a->rd]); + } tcg_gen_ext8s_i32(temp_count, r[a->rc]); tcg_gen_shl_i32(temp_resl, r[a->rd], temp_count); @@ -1151,7 +891,7 @@ static bool trans_ASHUB_reg(DisasContext *ctx, arg_ASHUB_reg *a) { tcg_gen_movcond_i32(TCG_COND_GEU, temp_dest, temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); - tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp_dest, 0, 8); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp_dest, 0, a->width*8); return true; } @@ -1210,62 +950,34 @@ static bool trans_ASHUD_rp(DisasContext *ctx, arg_ASHUD_rp *a) { return true; } -static bool trans_ASHUW_imm_l(DisasContext *ctx, arg_ASHUW_imm_l *a) { - 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; +static bool trans_LSH_imm_r(DisasContext *ctx, arg_LSH_imm_r *a) { + int32_t imm = (-a->imm) & (a->width == 1 ? 0x7 : 0xF); 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); + if (a->width == 1) { + tcg_gen_ext8u_i32(temp, r[a->rd]); + } + else { /* a->width == 2 */ + tcg_gen_ext16u_i32(temp, r[a->rd]); + } - 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 = temp_src; - TCGv_i32 temp_count = tcg_temp_new_i32(); - - tcg_gen_ext16s_i32(temp_src, r[a->rd]); - tcg_gen_ext8s_i32(temp_count, r[a->rc]); - - tcg_gen_shl_i32(temp_resl, temp_src, temp_count); - - tcg_gen_neg_i32(temp_count, temp_count); - tcg_gen_sar_i32(temp_resr, temp_src, temp_count); - - 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; -} - -static bool trans_LSHB_imm_r(DisasContext *ctx, arg_LSHB_imm_r *a) { - int16_t imm = (~a->imm+1) & 0x7; - TCGv_i32 temp = tcg_temp_new_i32(); - - tcg_gen_ext8u_i32(temp, r[a->rd]); tcg_gen_shri_i32(temp, temp, imm); - tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, 8); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp, 0, a->width*8); return true; } -static bool trans_LSHB_reg(DisasContext *ctx, arg_LSHB_reg *a) { +static bool trans_LSH_reg(DisasContext *ctx, arg_LSH_reg *a) { TCGv_i32 temp_dest = tcg_temp_new_i32(); TCGv_i32 temp_count = tcg_temp_new_i32(); TCGv_i32 temp_resl = tcg_temp_new_i32(); TCGv_i32 temp_resr = temp_dest; - tcg_gen_ext8u_i32(temp_dest, r[a->rd]); + if (a->width == 1) { + tcg_gen_ext8u_i32(temp_dest, r[a->rd]); + } + else { /* a->width == 2 */ + tcg_gen_ext16u_i32(temp_dest, r[a->rd]); + } tcg_gen_ext8s_i32(temp_count, r[a->rc]); tcg_gen_shl_i32(temp_resl, r[a->rd], temp_count); @@ -1275,13 +987,13 @@ static bool trans_LSHB_reg(DisasContext *ctx, arg_LSHB_reg *a) { tcg_gen_movcond_i32(TCG_COND_GEU, temp_dest, temp_count, tcg_constant_i32(0x80), temp_resl, temp_resr); - tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp_dest, 0, 8); + tcg_gen_deposit_i32(r[a->rd], r[a->rd], temp_dest, 0, a->width*8); return true; } static bool trans_LSHD_imm_r(DisasContext *ctx, arg_LSHD_imm_r *a) { - int16_t imm = ((~a->imm)+1) & 0x1F; + int16_t imm = (~a->imm+1) & 0x1F; if (a->rd < CR16C_FIRST_32B_REG) { tcg_gen_deposit_i32(r[a->rd], r[a->rd], r[a->rd+1], 16, 16); @@ -1320,37 +1032,6 @@ static bool trans_LSHD_rp(DisasContext *ctx, arg_LSHD_rp *a) { return true; } -static bool trans_LSHW_imm_r(DisasContext *ctx, arg_LSHW_imm_r *a) { - int16_t imm = ((~a->imm)+1) & 0xF; - 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 = tcg_temp_new_i32(); - TCGv_i32 temp_count = tcg_temp_new_i32(); - - tcg_gen_ext16u_i32(temp_src, r[a->rd]); - tcg_gen_ext8s_i32(temp_count, r[a->rc]); - - tcg_gen_shl_i32(temp_resl, temp_src, temp_count); - - tcg_gen_neg_i32(temp_count, temp_count); - tcg_gen_shr_i32(temp_resr, temp_src, temp_count); - - 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; -} /* Jumps and Linkage */ @@ -1363,23 +1044,11 @@ static bool trans_EXCP(DisasContext *ctx, arg_EXCP *a) { return true; } -static uint16_t get_disp8(DisasContext* ctx, uint8_t disp) { - if (disp == 0x80) { - uint16_t disp_esc = cpu_lduw_code(ctx->env, ctx->base.pc_next) >> 1; - ctx->base.pc_next += 2; - return disp_esc; - } - else { - return disp; - } -}; - static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { TCGLabel* l = gen_new_label(); TCGv temp; uint32_t pc_this = ctx->base.pc_next - 2; - uint16_t disp = get_disp8(ctx, a->dest); - uint32_t dest = pc_this + disp*2; + uint32_t dest = pc_this + a->disp*2; /* Flags may have higher bits set */ tcg_gen_andi_i32(f_n, f_n, 1); @@ -1462,7 +1131,6 @@ static bool trans_BRCOND_disp8(DisasContext* ctx, arg_BRCOND_disp8 *a) { /* Load and Store */ - static MemOp unsigned_op_by_width[] = {0, MO_UB, MO_UW, 0, MO_UL}; static void gen_compute_rrp_addr(TCGv_i32 dest, uint8_t rrp, uint32_t disp) { @@ -1488,12 +1156,12 @@ static void gen_compute_addr_disp(TCGv_i32 dest, int ra_id, int disp, bool dbase tcg_gen_addi_i32(dest, dest, disp); } -static void gen_move_dest(TCGv_i32 rs, int rd_id, int word_cnt) { - if (word_cnt <= 2 || rd_id >= CR16C_FIRST_32B_REG) { - tcg_gen_deposit_i32(r[rd_id], r[rd_id], rs, 0, word_cnt * 8); +static void gen_move_dest(TCGv_i32 rs, int rd_id, int width) { + if (width <= 2 || rd_id >= CR16C_FIRST_32B_REG) { + tcg_gen_deposit_i32(r[rd_id], r[rd_id], rs, 0, width * 8); } else { tcg_gen_mov_i32(r[rd_id], rs); - tcg_gen_extract_i32(r[rd_id+1], rs, 16, (word_cnt-2)*8); + tcg_gen_extract_i32(r[rd_id+1], rs, 16, (width-2)*8); } } @@ -1502,8 +1170,8 @@ static bool trans_LOAD(DisasContext *ctx, arg_LOAD *a) { TCGv_i32 temp = tcg_temp_new_i32(); gen_compute_addr_disp(temp, a->ra, a->disp, a->dbase); - tcg_gen_qemu_ld_i32(temp, temp, 0, unsigned_op_by_width[a->word_cnt]); - gen_move_dest(temp, a->rd, a->word_cnt); + tcg_gen_qemu_ld_i32(temp, temp, 0, unsigned_op_by_width[a->width]); + gen_move_dest(temp, a->rd, a->width); return true; } @@ -1511,8 +1179,8 @@ static bool trans_LOAD(DisasContext *ctx, arg_LOAD *a) { static bool trans_LOAD_abs(DisasContext *ctx, arg_LOAD_abs *a) { TCGv_i32 temp = tcg_temp_new_i32(); - tcg_gen_qemu_ld_i32(temp, tcg_constant_i32(a->addr), 0, unsigned_op_by_width[a->word_cnt]); - gen_move_dest(temp, a->rd, a->word_cnt); + tcg_gen_qemu_ld_i32(temp, tcg_constant_i32(a->addr), 0, unsigned_op_by_width[a->width]); + gen_move_dest(temp, a->rd, a->width); return true; } @@ -1521,8 +1189,8 @@ static bool trans_LOAD_rrp(DisasContext *ctx, arg_LOAD_rrp *a) { TCGv_i32 temp = tcg_temp_new_i32(); gen_compute_rrp_addr(temp, a->rrp, a->disp); - tcg_gen_qemu_ld_i32(temp, temp, 0, unsigned_op_by_width[a->word_cnt]); - gen_move_dest(temp, a->rd, a->word_cnt); + tcg_gen_qemu_ld_i32(temp, temp, 0, unsigned_op_by_width[a->width]); + gen_move_dest(temp, a->rd, a->width); return true; } @@ -1531,8 +1199,8 @@ static bool trans_LOAD_ind_abs(DisasContext *ctx, arg_LOAD_ind_abs *a) { TCGv_i32 temp = tcg_temp_new_i32(); tcg_gen_addi_i32(temp, r[12 + a->ri], a->addr); - tcg_gen_qemu_ld_i32(temp, temp, 0, unsigned_op_by_width[a->word_cnt]); - gen_move_dest(temp, a->rd, a->word_cnt); + tcg_gen_qemu_ld_i32(temp, temp, 0, unsigned_op_by_width[a->width]); + gen_move_dest(temp, a->rd, a->width); return true; } @@ -1553,8 +1221,8 @@ static bool trans_LOADM(DisasContext *ctx, arg_LOADM *a) { } -static void gen_combine_rp(int reg_id, int word_cnt) { - if (word_cnt == 4 && reg_id < CR16C_FIRST_32B_REG) { +static void gen_combine_rp(int reg_id, int width) { + if (width == 4 && reg_id < CR16C_FIRST_32B_REG) { tcg_gen_deposit_i32(r[reg_id], r[reg_id], r[reg_id+1], 16, 16); } } @@ -1563,8 +1231,8 @@ static bool trans_STOR(DisasContext *ctx, arg_STOR *a) { TCGv_i32 temp = tcg_temp_new_i32(); gen_compute_addr_disp(temp, a->ra, a->disp, a->dbase); - gen_combine_rp(a->rs, a->word_cnt); - tcg_gen_qemu_st_i32(r[a->rs], temp, 0, unsigned_op_by_width[a->word_cnt]); + gen_combine_rp(a->rs, a->width); + tcg_gen_qemu_st_i32(r[a->rs], temp, 0, unsigned_op_by_width[a->width]); return true; } @@ -1573,15 +1241,15 @@ static bool trans_STOR_rrp(DisasContext *ctx, arg_STOR_rrp *a) { TCGv_i32 temp = tcg_temp_new_i32(); gen_compute_rrp_addr(temp, a->rrp, a->disp); - gen_combine_rp(a->rs, a->word_cnt); - tcg_gen_qemu_st_i32(r[a->rs], temp, 0, unsigned_op_by_width[a->word_cnt]); + gen_combine_rp(a->rs, a->width); + tcg_gen_qemu_st_i32(r[a->rs], temp, 0, unsigned_op_by_width[a->width]); return true; } static bool trans_STOR_abs(DisasContext *ctx, arg_STOR_abs *a) { - gen_combine_rp(a->rs, a->word_cnt); - tcg_gen_qemu_st_i32(r[a->rs], tcg_constant_i32(a->addr), 0, unsigned_op_by_width[a->word_cnt]); + gen_combine_rp(a->rs, a->width); + tcg_gen_qemu_st_i32(r[a->rs], tcg_constant_i32(a->addr), 0, unsigned_op_by_width[a->width]); return true; } @@ -1589,14 +1257,14 @@ static bool trans_STOR_ind_abs(DisasContext *ctx, arg_STOR_ind_abs *a) { TCGv_i32 temp = tcg_temp_new_i32(); tcg_gen_addi_i32(temp, r[12 + a->ri], a->addr); - gen_combine_rp(a->rs, a->word_cnt); - tcg_gen_qemu_st_i32(r[a->rs], temp, 0, unsigned_op_by_width[a->word_cnt]); + gen_combine_rp(a->rs, a->width); + tcg_gen_qemu_st_i32(r[a->rs], temp, 0, unsigned_op_by_width[a->width]); return true; } static bool trans_STOR_abs_imm(DisasContext *ctx, arg_STOR_abs_imm *a) { - tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), tcg_constant_i32(a->addr), 0, unsigned_op_by_width[a->word_cnt]); + tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), tcg_constant_i32(a->addr), 0, unsigned_op_by_width[a->width]); return true; } @@ -1604,7 +1272,7 @@ static bool trans_STOR_imm(DisasContext *ctx, arg_STOR_imm *a) { TCGv_i32 temp = tcg_temp_new_i32(); gen_compute_addr_disp(temp, a->ra, a->disp, a->dbase); - tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), temp, 0, unsigned_op_by_width[a->word_cnt]); + tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), temp, 0, unsigned_op_by_width[a->width]); return true; } @@ -1613,7 +1281,7 @@ static bool trans_STOR_rrp_imm(DisasContext *ctx, arg_STOR_rrp_imm *a) { TCGv_i32 temp = tcg_temp_new_i32(); gen_compute_rrp_addr(temp, a->rrp, a->disp); - tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), temp, 0, unsigned_op_by_width[a->word_cnt]); + tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), temp, 0, unsigned_op_by_width[a->width]); return true; } @@ -1622,7 +1290,7 @@ static bool trans_STOR_abs_rrp_imm(DisasContext *ctx, arg_STOR_abs_rrp_imm *a) { TCGv_i32 temp = tcg_temp_new_i32(); tcg_gen_addi_i32(temp, r[12 + a->ri], a->addr); - tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), temp, 0, unsigned_op_by_width[a->word_cnt]); + tcg_gen_qemu_st_i32(tcg_constant_i32(a->imm), temp, 0, unsigned_op_by_width[a->width]); return true; } @@ -1647,7 +1315,6 @@ static bool trans_STORM(DisasContext *ctx, arg_STORM *a) { } - /* Some instructions aren't implemented yet, eg. because of some binutils that make them hard to verify and we'll fix first */ static bool trans_UNIMPLEMENTED(DisasContext *ctx, arg_UNIMPLEMENTED *a) { gen_helper_raise_unimplemented_instruction(); @@ -1656,6 +1323,8 @@ static bool trans_UNIMPLEMENTED(DisasContext *ctx, arg_UNIMPLEMENTED *a) { } +/*** Translation hooks ****/ + static void cr16c_tr_translate_insn(DisasContextBase *base, CPUState *cs) { DisasContext *ctx = container_of(base, DisasContext, base); diff --git a/tests/tcg/cr16c/Makefile.softmmu-target b/tests/tcg/cr16c/Makefile.softmmu-target index fa9fac3b72..899dc114df 100644 --- a/tests/tcg/cr16c/Makefile.softmmu-target +++ b/tests/tcg/cr16c/Makefile.softmmu-target @@ -16,10 +16,8 @@ QEMU_OPTS+=-M sc14450board -nographic $(EXTFLAGS) -bios LDFLAGS = -nostdlib -static %: %.S macros.inc Makefile.softmmu-target - $(CC) $(EXTRA_CFLAGS) $< -o $@.elf $(LDFLAGS) - # TODO: There seems to be a linker bug with the binary format for cr16 - # For now we extract the text section with a hardcoded objcopy command name :/ - cr16-unknown-elf-objcopy --dump-section .text=$@ $@.elf /dev/null + $(CC) $(EXTRA_CFLAGS) $< -o $@.elf -O0 $(LDFLAGS) + $$($(CC) -print-prog-name=objcopy) -O binary $@.elf $@ # We don't support the multiarch system tests yet undefine MULTIARCH_TESTS diff --git a/tests/tcg/cr16c/test01-adds.S b/tests/tcg/cr16c/test01-adds.S index 80ed19b853..549aa303f1 100644 --- a/tests/tcg/cr16c/test01-adds.S +++ b/tests/tcg/cr16c/test01-adds.S @@ -38,11 +38,11 @@ _start: EXPECT 0x0387, r8 /* Unsigned and signed overflow */ movw $0x80, r10 - addb $0x80, r10 + addb $-0x80, r10 EXPECT_COND cs EXPECT 0x0000, r10 movw $0x80, r10 - addb $0x80, r10 + addb $-0x80, r10 EXPECT_COND fs EXPECT 0x0000, r10 /* dword reg */