* [Qemu-devel] [PATCH 0/5] Initial Blackfin support (linux-user only)
@ 2013-06-17 7:13 Mike Frysinger
2013-06-17 7:13 ` [Qemu-devel] [PATCH 1/5] Blackfin: add disassembler support Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
0 siblings, 2 replies; 10+ messages in thread
From: Mike Frysinger @ 2013-06-17 7:13 UTC (permalink / raw)
To: qemu-devel
I've cleaned up the code and removed all the debugging bits. This passes
a good number of tests (both the ones included here as well as the ones
included with binutils/gcc/etc...), and as long as you stay away from the
DSP related insns, your experience should be pretty good. If you do need
DSP insns, then you should probably stick with the GNU sim for now.
The port started off against a much older version, so I might have missed
some stuff that needs to be done for the latest master branch.
Mike Frysinger (5):
Blackfin: add disassembler support
Blackfin: initial port
Blackfin: add linux-user support
Blackfin: add test suite
linux-user: add support for Blackfin syscalls
MAINTAINERS | 5 +
configure | 8 +
cpu-exec.c | 5 +-
default-configs/bfin-linux-user.mak | 1 +
disas.c | 9 +
disas/Makefile.objs | 1 +
disas/bfin.c | 4791 +++++++++++++++++++++++++++
gdbstub.c | 103 +
include/disas/bfd.h | 3 +
include/elf.h | 6 +
linux-user/bfin/syscall.h | 59 +
linux-user/bfin/syscall_nr.h | 389 +++
linux-user/bfin/target_flat.h | 92 +
linux-user/bfin/target_sigcontext.h | 61 +
linux-user/bfin/target_signal.h | 31 +
linux-user/bfin/termbits.h | 227 ++
linux-user/elfload.c | 47 +
linux-user/main.c | 160 +
linux-user/qemu.h | 4 +
linux-user/signal.c | 225 ++
linux-user/strace.list | 9 +
linux-user/syscall.c | 77 +-
linux-user/syscall_defs.h | 65 +-
linux-user/target_ucontext.h | 14 +
qapi-schema.json | 9 +-
scripts/qemu-binfmt-conf.sh | 4 +
target-bfin/Makefile.objs | 3 +
target-bfin/README | 32 +
target-bfin/TODO | 25 +
target-bfin/bfin-sim.c | 3666 ++++++++++++++++++++
target-bfin/bfin-tdep.h | 94 +
target-bfin/cpu-qom.h | 61 +
target-bfin/cpu.c | 55 +
target-bfin/cpu.h | 236 ++
target-bfin/helper.c | 37 +
target-bfin/helper.h | 23 +
target-bfin/linux-fixed-code.h | 23 +
target-bfin/op_helper.c | 229 ++
target-bfin/opcode/bfin.h | 1754 ++++++++++
target-bfin/translate.c | 1347 ++++++++
tests/tcg/Makefile | 4 +
tests/tcg/bfin/.gitignore | 2 +
tests/tcg/bfin/10272_small.s | 51 +
tests/tcg/bfin/10436.s | 39 +
tests/tcg/bfin/10622.s | 21 +
tests/tcg/bfin/10742.s | 17 +
tests/tcg/bfin/10799.s | 55 +
tests/tcg/bfin/7641.s | 38 +
tests/tcg/bfin/Makefile | 80 +
tests/tcg/bfin/a0.s | 17 +
tests/tcg/bfin/a1.s | 29 +
tests/tcg/bfin/a10.s | 163 +
tests/tcg/bfin/a2.s | 179 +
tests/tcg/bfin/a24.s | 12 +
tests/tcg/bfin/a25.s | 28 +
tests/tcg/bfin/a26.s | 72 +
tests/tcg/bfin/a3.s | 313 ++
tests/tcg/bfin/a4.s | 36 +
tests/tcg/bfin/a7.s | 179 +
tests/tcg/bfin/a8.s | 41 +
tests/tcg/bfin/a9.s | 205 ++
tests/tcg/bfin/abs-2.S | 42 +
tests/tcg/bfin/abs-3.S | 42 +
tests/tcg/bfin/abs.S | 42 +
tests/tcg/bfin/acc-rot.s | 129 +
tests/tcg/bfin/acp5_19.s | 12 +
tests/tcg/bfin/add_imm7.s | 38 +
tests/tcg/bfin/algnbug1.s | 38 +
tests/tcg/bfin/algnbug2.s | 69 +
tests/tcg/bfin/b0.S | 51 +
tests/tcg/bfin/b1.s | 12 +
tests/tcg/bfin/b2.S | 26 +
tests/tcg/bfin/brcc.s | 164 +
tests/tcg/bfin/brevadd.s | 20 +
tests/tcg/bfin/byteunpack.s | 45 +
tests/tcg/bfin/c_alu2op_arith_r_sft.s | 226 ++
tests/tcg/bfin/c_alu2op_conv_b.s | 211 ++
tests/tcg/bfin/c_alu2op_conv_h.s | 211 ++
tests/tcg/bfin/c_alu2op_conv_mix.s | 186 ++
tests/tcg/bfin/c_alu2op_conv_neg.s | 211 ++
tests/tcg/bfin/c_alu2op_conv_toggle.s | 211 ++
tests/tcg/bfin/c_alu2op_conv_xb.s | 211 ++
tests/tcg/bfin/c_alu2op_conv_xh.s | 212 ++
tests/tcg/bfin/c_alu2op_divq.s | 220 ++
tests/tcg/bfin/c_alu2op_divs.s | 220 ++
tests/tcg/bfin/c_alu2op_log_l_sft.s | 220 ++
tests/tcg/bfin/c_alu2op_log_r_sft.s | 217 ++
tests/tcg/bfin/c_alu2op_shadd_1.s | 209 ++
tests/tcg/bfin/c_alu2op_shadd_2.s | 209 ++
tests/tcg/bfin/c_br_preg_killed_ac.s | 82 +
tests/tcg/bfin/c_br_preg_killed_ex1.s | 85 +
tests/tcg/bfin/c_br_preg_stall_ac.s | 75 +
tests/tcg/bfin/c_br_preg_stall_ex1.s | 70 +
tests/tcg/bfin/c_brcc_bp1.s | 45 +
tests/tcg/bfin/c_brcc_bp2.s | 45 +
tests/tcg/bfin/c_brcc_bp3.s | 47 +
tests/tcg/bfin/c_brcc_bp4.s | 46 +
tests/tcg/bfin/c_brcc_brf_bp.s | 46 +
tests/tcg/bfin/c_brcc_brf_brt_bp.s | 47 +
tests/tcg/bfin/c_brcc_brf_brt_nbp.s | 46 +
tests/tcg/bfin/c_brcc_brf_fbkwd.s | 46 +
tests/tcg/bfin/c_brcc_brf_nbp.s | 45 +
tests/tcg/bfin/c_brcc_brt_bp.s | 46 +
tests/tcg/bfin/c_brcc_brt_nbp.s | 45 +
tests/tcg/bfin/c_calla_ljump.s | 31 +
tests/tcg/bfin/c_calla_subr.s | 28 +
tests/tcg/bfin/c_cc2dreg.s | 56 +
tests/tcg/bfin/c_cc2stat_cc_ac.S | 240 ++
tests/tcg/bfin/c_cc2stat_cc_an.s | 243 ++
tests/tcg/bfin/c_cc2stat_cc_aq.s | 243 ++
tests/tcg/bfin/c_cc2stat_cc_av0.S | 241 ++
tests/tcg/bfin/c_cc2stat_cc_av1.S | 240 ++
tests/tcg/bfin/c_cc2stat_cc_az.s | 243 ++
tests/tcg/bfin/c_cc_flag_ccmv_depend.S | 82 +
tests/tcg/bfin/c_cc_flagdreg_mvbrsft.s | 87 +
tests/tcg/bfin/c_cc_regmvlogi_mvbrsft.s | 83 +
tests/tcg/bfin/c_ccflag_dr_dr.s | 299 ++
tests/tcg/bfin/c_ccflag_dr_dr_uu.s | 299 ++
tests/tcg/bfin/c_ccflag_dr_imm3.s | 224 ++
tests/tcg/bfin/c_ccflag_dr_imm3_uu.s | 221 ++
tests/tcg/bfin/c_ccflag_pr_imm3.s | 539 +++
tests/tcg/bfin/c_ccflag_pr_imm3_uu.s | 238 ++
tests/tcg/bfin/c_ccflag_pr_pr.s | 262 ++
tests/tcg/bfin/c_ccflag_pr_pr_uu.s | 212 ++
tests/tcg/bfin/c_ccmv_cc_dr_dr.s | 124 +
tests/tcg/bfin/c_ccmv_cc_dr_pr.s | 61 +
tests/tcg/bfin/c_ccmv_cc_pr_pr.s | 111 +
tests/tcg/bfin/c_ccmv_ncc_dr_dr.s | 123 +
tests/tcg/bfin/c_ccmv_ncc_dr_pr.s | 60 +
tests/tcg/bfin/c_ccmv_ncc_pr_pr.s | 111 +
tests/tcg/bfin/c_comp3op_dr_and_dr.s | 412 +++
tests/tcg/bfin/c_comp3op_dr_minus_dr.s | 412 +++
tests/tcg/bfin/c_comp3op_dr_mix.s | 237 ++
tests/tcg/bfin/c_comp3op_dr_or_dr.s | 412 +++
tests/tcg/bfin/c_comp3op_dr_plus_dr.s | 412 +++
tests/tcg/bfin/c_comp3op_dr_xor_dr.s | 412 +++
tests/tcg/bfin/c_comp3op_pr_plus_pr_sh1.s | 302 ++
tests/tcg/bfin/c_comp3op_pr_plus_pr_sh2.s | 302 ++
tests/tcg/bfin/c_compi2opd_dr_add_i7_n.s | 164 +
tests/tcg/bfin/c_compi2opd_dr_add_i7_p.s | 147 +
tests/tcg/bfin/c_compi2opd_dr_eq_i7_n.s | 166 +
tests/tcg/bfin/c_compi2opd_dr_eq_i7_p.s | 147 +
tests/tcg/bfin/c_compi2opd_flags.S | 600 ++++
tests/tcg/bfin/c_compi2opd_flags_2.S | 600 ++++
tests/tcg/bfin/c_compi2opp_pr_add_i7_n.s | 149 +
tests/tcg/bfin/c_compi2opp_pr_add_i7_p.s | 116 +
tests/tcg/bfin/c_compi2opp_pr_eq_i7_n.s | 161 +
tests/tcg/bfin/c_compi2opp_pr_eq_i7_p.s | 131 +
tests/tcg/bfin/c_dagmodik_lnz_imgebl.s | 290 ++
tests/tcg/bfin/c_dagmodik_lnz_imltbl.s | 289 ++
tests/tcg/bfin/c_dagmodik_lz_inc_dec.s | 140 +
tests/tcg/bfin/c_dagmodim_lnz_imgebl.s | 108 +
tests/tcg/bfin/c_dagmodim_lnz_imltbl.s | 109 +
tests/tcg/bfin/c_dagmodim_lz_inc_dec.s | 98 +
tests/tcg/bfin/c_dsp32alu_a_neg_a.s | 34 +
tests/tcg/bfin/c_dsp32alu_aa_absabs.s | 35 +
tests/tcg/bfin/c_dsp32alu_aa_negneg.s | 35 +
tests/tcg/bfin/c_dsp32alu_abs.s | 62 +
tests/tcg/bfin/c_dsp32alu_absabs.s | 62 +
tests/tcg/bfin/c_dsp32alu_awx.s | 54 +
tests/tcg/bfin/c_dsp32alu_bytepack.s | 77 +
tests/tcg/bfin/c_dsp32alu_byteunpack.s | 113 +
tests/tcg/bfin/c_dsp32alu_disalnexcpt.s | 255 ++
tests/tcg/bfin/c_dsp32alu_max.s | 261 ++
tests/tcg/bfin/c_dsp32alu_maxmax.s | 261 ++
tests/tcg/bfin/c_dsp32alu_min.s | 261 ++
tests/tcg/bfin/c_dsp32alu_minmin.s | 261 ++
tests/tcg/bfin/c_dsp32alu_rr_lph_a1a0.s | 33 +
tests/tcg/bfin/c_dsp32alu_search.s | 74 +
tests/tcg/bfin/c_dsp32alu_sgn.s | 39 +
tests/tcg/bfin/c_dsp32mac_a1a0.s | 255 ++
tests/tcg/bfin/c_dsp32mac_pair_a0.s | 129 +
tests/tcg/bfin/c_dsp32mac_pair_a0_i.s | 247 ++
tests/tcg/bfin/c_dsp32mac_pair_a0_m.s | 129 +
tests/tcg/bfin/c_dsp32mac_pair_a1.s | 127 +
tests/tcg/bfin/c_dsp32mac_pair_a1_i.s | 243 ++
tests/tcg/bfin/c_dsp32mac_pair_a1_m.s | 127 +
tests/tcg/bfin/c_dsp32mult_pair_m.s | 178 +
tests/tcg/bfin/c_dsp32mult_pair_m_i.s | 178 +
tests/tcg/bfin/c_dsp32mult_pair_m_u.s | 178 +
tests/tcg/bfin/c_dsp32shift_a0alr.s | 77 +
tests/tcg/bfin/c_dsp32shift_af.s | 186 ++
tests/tcg/bfin/c_dsp32shift_ahalf_ln.s | 423 +++
tests/tcg/bfin/c_dsp32shift_ahalf_lp.s | 423 +++
tests/tcg/bfin/c_dsp32shift_ahalf_rn.s | 423 +++
tests/tcg/bfin/c_dsp32shift_ahalf_rn_s.s | 424 +++
tests/tcg/bfin/c_dsp32shift_ahalf_rp.s | 423 +++
tests/tcg/bfin/c_dsp32shift_ahalf_rp_s.s | 423 +++
tests/tcg/bfin/c_dsp32shift_align16.s | 210 ++
tests/tcg/bfin/c_dsp32shift_align24.s | 210 ++
tests/tcg/bfin/c_dsp32shift_align8.s | 210 ++
tests/tcg/bfin/c_dsp32shift_fdepx.s | 210 ++
tests/tcg/bfin/c_dsp32shift_fextx.s | 210 ++
tests/tcg/bfin/c_dsp32shift_lf.s | 422 +++
tests/tcg/bfin/c_dsp32shift_lhalf_ln.s | 422 +++
tests/tcg/bfin/c_dsp32shift_lhalf_lp.s | 422 +++
tests/tcg/bfin/c_dsp32shift_lhalf_rn.s | 425 +++
tests/tcg/bfin/c_dsp32shift_lhalf_rp.s | 423 +++
tests/tcg/bfin/c_dsp32shift_ones.s | 214 ++
tests/tcg/bfin/c_dsp32shift_pack.s | 411 +++
tests/tcg/bfin/c_dsp32shift_rot.s | 427 +++
tests/tcg/bfin/c_dsp32shift_rot_mix.s | 375 +++
tests/tcg/bfin/c_dsp32shift_signbits_r.s | 214 ++
tests/tcg/bfin/c_dsp32shift_signbits_rh.s | 214 ++
tests/tcg/bfin/c_dsp32shift_signbits_rl.s | 210 ++
tests/tcg/bfin/c_dsp32shift_vmax.s | 113 +
tests/tcg/bfin/c_dsp32shift_vmaxvmax.s | 113 +
tests/tcg/bfin/c_dsp32shiftim_a0alr.s | 213 ++
tests/tcg/bfin/c_dsp32shiftim_af.s | 63 +
tests/tcg/bfin/c_dsp32shiftim_af_s.s | 37 +
tests/tcg/bfin/c_dsp32shiftim_ahalf_ln.s | 406 +++
tests/tcg/bfin/c_dsp32shiftim_ahalf_lp.s | 418 +++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rn.s | 418 +++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rn_s.s | 418 +++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rp.s | 420 +++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rp_s.s | 422 +++
tests/tcg/bfin/c_dsp32shiftim_ahh.s | 65 +
tests/tcg/bfin/c_dsp32shiftim_amix.s | 124 +
tests/tcg/bfin/c_dsp32shiftim_lf.s | 63 +
tests/tcg/bfin/c_dsp32shiftim_lhalf_ln.s | 401 +++
tests/tcg/bfin/c_dsp32shiftim_lhalf_lp.s | 418 +++
tests/tcg/bfin/c_dsp32shiftim_lhalf_rn.s | 424 +++
tests/tcg/bfin/c_dsp32shiftim_lhalf_rp.s | 421 +++
tests/tcg/bfin/c_dsp32shiftim_lhh.s | 65 +
tests/tcg/bfin/c_dsp32shiftim_lmix.s | 138 +
tests/tcg/bfin/c_dsp32shiftim_rot.s | 62 +
tests/tcg/bfin/c_dspldst_ld_dr_i.s | 168 +
tests/tcg/bfin/c_dspldst_ld_dr_ipp.s | 348 ++
tests/tcg/bfin/c_dspldst_ld_dr_ippm.s | 328 ++
tests/tcg/bfin/c_dspldst_ld_drhi_i.s | 168 +
tests/tcg/bfin/c_dspldst_ld_drhi_ipp.s | 364 ++
tests/tcg/bfin/c_dspldst_ld_drlo_i.s | 164 +
tests/tcg/bfin/c_dspldst_ld_drlo_ipp.s | 355 ++
tests/tcg/bfin/c_dspldst_st_dr_i.s | 185 ++
tests/tcg/bfin/c_dspldst_st_dr_ipp.s | 326 ++
tests/tcg/bfin/c_dspldst_st_dr_ippm.s | 279 ++
tests/tcg/bfin/c_dspldst_st_drhi_i.s | 161 +
tests/tcg/bfin/c_dspldst_st_drhi_ipp.s | 355 ++
tests/tcg/bfin/c_dspldst_st_drlo_i.s | 163 +
tests/tcg/bfin/c_dspldst_st_drlo_ipp.s | 351 ++
tests/tcg/bfin/c_ldimmhalf_dreg.s | 60 +
tests/tcg/bfin/c_ldimmhalf_drhi.s | 85 +
tests/tcg/bfin/c_ldimmhalf_drlo.s | 89 +
tests/tcg/bfin/c_ldimmhalf_h_dr.s | 82 +
tests/tcg/bfin/c_ldimmhalf_h_ibml.s | 165 +
tests/tcg/bfin/c_ldimmhalf_h_pr.s | 74 +
tests/tcg/bfin/c_ldimmhalf_l_dr.s | 82 +
tests/tcg/bfin/c_ldimmhalf_l_ibml.s | 165 +
tests/tcg/bfin/c_ldimmhalf_l_pr.s | 76 +
tests/tcg/bfin/c_ldimmhalf_lz_dr.s | 81 +
tests/tcg/bfin/c_ldimmhalf_lz_ibml.s | 168 +
tests/tcg/bfin/c_ldimmhalf_lz_pr.s | 72 +
tests/tcg/bfin/c_ldimmhalf_lzhi_dr.s | 113 +
tests/tcg/bfin/c_ldimmhalf_lzhi_ibml.s | 216 ++
tests/tcg/bfin/c_ldimmhalf_lzhi_pr.s | 102 +
tests/tcg/bfin/c_ldimmhalf_pibml.s | 212 ++
tests/tcg/bfin/c_ldst_ld_d_p.s | 372 +++
tests/tcg/bfin/c_ldst_ld_d_p_b.s | 353 ++
tests/tcg/bfin/c_ldst_ld_d_p_h.s | 351 ++
tests/tcg/bfin/c_ldst_ld_d_p_mm.s | 417 +++
tests/tcg/bfin/c_ldst_ld_d_p_mm_b.s | 353 ++
tests/tcg/bfin/c_ldst_ld_d_p_mm_h.s | 330 ++
tests/tcg/bfin/c_ldst_ld_d_p_mm_xb.s | 341 ++
tests/tcg/bfin/c_ldst_ld_d_p_mm_xh.s | 355 ++
tests/tcg/bfin/c_ldst_ld_d_p_pp.s | 371 +++
tests/tcg/bfin/c_ldst_ld_d_p_pp_b.s | 324 ++
tests/tcg/bfin/c_ldst_ld_d_p_pp_h.s | 350 ++
tests/tcg/bfin/c_ldst_ld_d_p_pp_xb.s | 355 ++
tests/tcg/bfin/c_ldst_ld_d_p_pp_xh.s | 333 ++
tests/tcg/bfin/c_ldst_ld_d_p_ppmm_hbx.s | 656 ++++
tests/tcg/bfin/c_ldst_ld_d_p_xb.s | 326 ++
tests/tcg/bfin/c_ldst_ld_d_p_xh.s | 354 ++
tests/tcg/bfin/c_ldst_ld_p_p.s | 327 ++
tests/tcg/bfin/c_ldst_ld_p_p_mm.s | 406 +++
tests/tcg/bfin/c_ldst_ld_p_p_pp.s | 335 ++
tests/tcg/bfin/c_ldst_st_p_d.s | 299 ++
tests/tcg/bfin/c_ldst_st_p_d_b.s | 300 ++
tests/tcg/bfin/c_ldst_st_p_d_h.s | 280 ++
tests/tcg/bfin/c_ldst_st_p_d_mm.s | 601 ++++
tests/tcg/bfin/c_ldst_st_p_d_mm_b.s | 498 +++
tests/tcg/bfin/c_ldst_st_p_d_mm_h.s | 554 ++++
tests/tcg/bfin/c_ldst_st_p_d_pp.s | 804 +++++
tests/tcg/bfin/c_ldst_st_p_d_pp_b.s | 455 +++
tests/tcg/bfin/c_ldst_st_p_d_pp_h.s | 457 +++
tests/tcg/bfin/c_ldst_st_p_p.s | 128 +
tests/tcg/bfin/c_ldst_st_p_p_mm.s | 428 +++
tests/tcg/bfin/c_ldst_st_p_p_pp.s | 397 +++
tests/tcg/bfin/c_ldstidxl_ld_dr_b.s | 554 ++++
tests/tcg/bfin/c_ldstidxl_ld_dr_h.s | 595 ++++
tests/tcg/bfin/c_ldstidxl_ld_dr_xb.s | 594 ++++
tests/tcg/bfin/c_ldstidxl_ld_dr_xh.s | 595 ++++
tests/tcg/bfin/c_ldstidxl_ld_dreg.s | 554 ++++
tests/tcg/bfin/c_ldstidxl_ld_preg.s | 672 ++++
tests/tcg/bfin/c_ldstidxl_st_dr_b.s | 612 ++++
tests/tcg/bfin/c_ldstidxl_st_dr_h.s | 609 ++++
tests/tcg/bfin/c_ldstidxl_st_dreg.s | 780 +++++
tests/tcg/bfin/c_ldstidxl_st_preg.s | 709 ++++
tests/tcg/bfin/c_ldstii_ld_dr_h.s | 541 +++
tests/tcg/bfin/c_ldstii_ld_dr_xh.s | 541 +++
tests/tcg/bfin/c_ldstii_ld_dreg.s | 540 +++
tests/tcg/bfin/c_ldstii_ld_preg.s | 564 ++++
tests/tcg/bfin/c_ldstii_st_dr_h.s | 605 ++++
tests/tcg/bfin/c_ldstii_st_dreg.s | 640 ++++
tests/tcg/bfin/c_ldstii_st_preg.s | 603 ++++
tests/tcg/bfin/c_ldstiifp_ld_dreg.s | 528 +++
tests/tcg/bfin/c_ldstiifp_ld_preg.s | 511 +++
tests/tcg/bfin/c_ldstiifp_st_dreg.s | 641 ++++
tests/tcg/bfin/c_ldstiifp_st_preg.s | 618 ++++
tests/tcg/bfin/c_ldstpmod_ld_dr_hi.s | 411 +++
tests/tcg/bfin/c_ldstpmod_ld_dr_lo.s | 410 +++
tests/tcg/bfin/c_ldstpmod_ld_dreg.s | 462 +++
tests/tcg/bfin/c_ldstpmod_ld_h_xh.s | 458 +++
tests/tcg/bfin/c_ldstpmod_ld_lohi.s | 462 +++
tests/tcg/bfin/c_ldstpmod_st_dr_hi.s | 400 +++
tests/tcg/bfin/c_ldstpmod_st_dr_lo.s | 401 +++
tests/tcg/bfin/c_ldstpmod_st_dreg.s | 623 ++++
tests/tcg/bfin/c_ldstpmod_st_lohi.s | 625 ++++
tests/tcg/bfin/c_linkage.s | 60 +
tests/tcg/bfin/c_logi2op_alshft_mix.s | 143 +
tests/tcg/bfin/c_logi2op_arith_shft.s | 223 ++
tests/tcg/bfin/c_logi2op_bitclr.s | 92 +
tests/tcg/bfin/c_logi2op_bitset.s | 92 +
tests/tcg/bfin/c_logi2op_bittgl.s | 165 +
tests/tcg/bfin/c_logi2op_bittst.s | 583 ++++
tests/tcg/bfin/c_logi2op_log_l_shft.s | 222 ++
tests/tcg/bfin/c_logi2op_log_l_shft_astat.S | 82 +
tests/tcg/bfin/c_logi2op_log_r_shft.s | 222 ++
tests/tcg/bfin/c_logi2op_log_r_shft_astat.S | 82 +
tests/tcg/bfin/c_logi2op_nbittst.s | 584 ++++
tests/tcg/bfin/c_loopsetup_nested.s | 166 +
tests/tcg/bfin/c_loopsetup_nested_bot.s | 165 +
tests/tcg/bfin/c_loopsetup_nested_prelc.s | 184 +
tests/tcg/bfin/c_loopsetup_nested_top.s | 166 +
tests/tcg/bfin/c_loopsetup_overlap.s | 167 +
tests/tcg/bfin/c_loopsetup_preg_div2_lc0.s | 95 +
tests/tcg/bfin/c_loopsetup_preg_div2_lc1.s | 94 +
tests/tcg/bfin/c_loopsetup_preg_lc0.s | 95 +
tests/tcg/bfin/c_loopsetup_preg_lc1.s | 93 +
tests/tcg/bfin/c_loopsetup_prelc.s | 145 +
tests/tcg/bfin/c_loopsetup_topbotcntr.s | 110 +
tests/tcg/bfin/c_progctrl_call_pcpr.s | 63 +
tests/tcg/bfin/c_progctrl_call_pr.s | 32 +
tests/tcg/bfin/c_progctrl_jump_pcpr.s | 58 +
tests/tcg/bfin/c_progctrl_jump_pr.s | 56 +
tests/tcg/bfin/c_progctrl_nop.s | 55 +
tests/tcg/bfin/c_progctrl_rts.s | 36 +
tests/tcg/bfin/c_ptr2op_pr_neg_pr.s | 163 +
tests/tcg/bfin/c_ptr2op_pr_sft_2_1.s | 162 +
tests/tcg/bfin/c_ptr2op_pr_shadd_1_2.s | 167 +
tests/tcg/bfin/c_pushpopmultiple_dp.s | 213 ++
tests/tcg/bfin/c_pushpopmultiple_dp_pair.s | 203 ++
tests/tcg/bfin/c_pushpopmultiple_dreg.s | 173 +
tests/tcg/bfin/c_pushpopmultiple_preg.s | 83 +
tests/tcg/bfin/c_regmv_acc_acc.s | 125 +
tests/tcg/bfin/c_regmv_dag_lz_dep.s | 148 +
tests/tcg/bfin/c_regmv_dr_acc_acc.s | 191 ++
tests/tcg/bfin/c_regmv_dr_dep_nostall.s | 245 ++
tests/tcg/bfin/c_regmv_dr_dr.s | 209 ++
tests/tcg/bfin/c_regmv_dr_imlb.s | 539 +++
tests/tcg/bfin/c_regmv_dr_pr.s | 107 +
tests/tcg/bfin/c_regmv_imlb_dep_nostall.s | 664 ++++
tests/tcg/bfin/c_regmv_imlb_dep_stall.s | 335 ++
tests/tcg/bfin/c_regmv_imlb_dr.s | 313 ++
tests/tcg/bfin/c_regmv_imlb_imlb.s | 925 ++++++
tests/tcg/bfin/c_regmv_imlb_pr.s | 302 ++
tests/tcg/bfin/c_regmv_pr_dep_nostall.s | 280 ++
tests/tcg/bfin/c_regmv_pr_dep_stall.s | 237 ++
tests/tcg/bfin/c_regmv_pr_dr.s | 147 +
tests/tcg/bfin/c_regmv_pr_imlb.s | 382 +++
tests/tcg/bfin/c_regmv_pr_pr.s | 95 +
tests/tcg/bfin/c_ujump.s | 52 +
tests/tcg/bfin/cc-astat-bits.s | 101 +
tests/tcg/bfin/cc1.s | 26 +
tests/tcg/bfin/cir.s | 20 +
tests/tcg/bfin/cir1.s | 84 +
tests/tcg/bfin/cmpdreg.S | 40 +
tests/tcg/bfin/compare.s | 15 +
tests/tcg/bfin/d0.s | 31 +
tests/tcg/bfin/d1.s | 17 +
tests/tcg/bfin/d2.s | 56 +
tests/tcg/bfin/div0.s | 37 +
tests/tcg/bfin/divq.s | 1322 ++++++++
tests/tcg/bfin/dotproduct.s | 304 ++
tests/tcg/bfin/dotproduct2.s | 299 ++
tests/tcg/bfin/dsp_d0.s | 31 +
tests/tcg/bfin/dsp_d1.s | 117 +
tests/tcg/bfin/edn_snafu.s | 45 +
tests/tcg/bfin/events.s | 44 +
tests/tcg/bfin/fact.s | 47 +
tests/tcg/bfin/fsm.s | 57 +
tests/tcg/bfin/greg2.s | 18 +
tests/tcg/bfin/hwloop-branch-in.s | 99 +
tests/tcg/bfin/hwloop-branch-out.s | 129 +
tests/tcg/bfin/hwloop-lt-bits.s | 25 +
tests/tcg/bfin/hwloop-nested.s | 33 +
tests/tcg/bfin/i0.s | 57 +
tests/tcg/bfin/issue113.s | 18 +
tests/tcg/bfin/issue126.s | 19 +
tests/tcg/bfin/issue129.s | 36 +
tests/tcg/bfin/issue144.s | 31 +
tests/tcg/bfin/issue83.s | 93 +
tests/tcg/bfin/issue89.s | 30 +
tests/tcg/bfin/l0.s | 137 +
tests/tcg/bfin/l0shift.s | 13 +
tests/tcg/bfin/l2_loop.s | 28 +
tests/tcg/bfin/link-2.s | 24 +
tests/tcg/bfin/link.s | 67 +
tests/tcg/bfin/load.s | 239 ++
tests/tcg/bfin/logic.s | 64 +
tests/tcg/bfin/loop_snafu.s | 28 +
tests/tcg/bfin/loop_strncpy.s | 76 +
tests/tcg/bfin/lp0.s | 17 +
tests/tcg/bfin/lp1.s | 16 +
tests/tcg/bfin/lsetup.s | 109 +
tests/tcg/bfin/m0boundary.s | 46 +
tests/tcg/bfin/m17.s | 74 +
tests/tcg/bfin/max_min_flags.s | 275 ++
tests/tcg/bfin/mem3.s | 42 +
tests/tcg/bfin/move.s | 36 +
tests/tcg/bfin/neg.S | 42 +
tests/tcg/bfin/nshift.s | 33 +
tests/tcg/bfin/pr.s | 81 +
tests/tcg/bfin/push-pop-multiple.s | 169 +
tests/tcg/bfin/push-pop.s | 78 +
tests/tcg/bfin/pushpopreg_1.s | 292 ++
tests/tcg/bfin/s0.s | 12 +
tests/tcg/bfin/s1.s | 25 +
tests/tcg/bfin/s10.s | 77 +
tests/tcg/bfin/s15.s | 149 +
tests/tcg/bfin/s16.s | 170 +
tests/tcg/bfin/s17.s | 46 +
tests/tcg/bfin/s2.s | 47 +
tests/tcg/bfin/s20.s | 25 +
tests/tcg/bfin/s21.s | 298 ++
tests/tcg/bfin/s4.s | 214 ++
tests/tcg/bfin/s5.s | 107 +
tests/tcg/bfin/s6.s | 83 +
tests/tcg/bfin/s7.s | 83 +
tests/tcg/bfin/s8.s | 55 +
tests/tcg/bfin/s9.s | 134 +
tests/tcg/bfin/se_kills2.S | 148 +
tests/tcg/bfin/se_rets_hazard.s | 55 +
tests/tcg/bfin/sign.s | 27 +
tests/tcg/bfin/simple0.s | 10 +
tests/tcg/bfin/stk.s | 78 +
tests/tcg/bfin/stk2.s | 107 +
tests/tcg/bfin/stk3.s | 106 +
tests/tcg/bfin/stk4.s | 110 +
tests/tcg/bfin/stk5.s | 34 +
tests/tcg/bfin/stk6.s | 58 +
tests/tcg/bfin/tar10622.s | 20 +
tests/tcg/bfin/test.h | 134 +
tests/tcg/bfin/testset.s | 73 +
tests/tcg/bfin/testset2.s | 37 +
tests/tcg/bfin/testutils.inc | 258 ++
tests/tcg/bfin/vec-abs.S | 42 +
tests/tcg/bfin/vecadd.s | 65 +
tests/tcg/bfin/vit_max.s | 57 +
tests/tcg/bfin/wtf.s | 26 +
tests/tcg/bfin/zcall.s | 44 +
460 files changed, 101757 insertions(+), 8 deletions(-)
create mode 100644 default-configs/bfin-linux-user.mak
create mode 100644 disas/bfin.c
create mode 100644 linux-user/bfin/syscall.h
create mode 100644 linux-user/bfin/syscall_nr.h
create mode 100644 linux-user/bfin/target_flat.h
create mode 100644 linux-user/bfin/target_sigcontext.h
create mode 100644 linux-user/bfin/target_signal.h
create mode 100644 linux-user/bfin/termbits.h
create mode 100644 linux-user/target_ucontext.h
create mode 100644 target-bfin/Makefile.objs
create mode 100644 target-bfin/README
create mode 100644 target-bfin/TODO
create mode 100644 target-bfin/bfin-sim.c
create mode 100644 target-bfin/bfin-tdep.h
create mode 100644 target-bfin/cpu-qom.h
create mode 100644 target-bfin/cpu.c
create mode 100644 target-bfin/cpu.h
create mode 100644 target-bfin/helper.c
create mode 100644 target-bfin/helper.h
create mode 100644 target-bfin/linux-fixed-code.h
create mode 100644 target-bfin/op_helper.c
create mode 100644 target-bfin/opcode/bfin.h
create mode 100644 target-bfin/translate.c
create mode 100644 tests/tcg/bfin/.gitignore
create mode 100644 tests/tcg/bfin/10272_small.s
create mode 100644 tests/tcg/bfin/10436.s
create mode 100644 tests/tcg/bfin/10622.s
create mode 100644 tests/tcg/bfin/10742.s
create mode 100644 tests/tcg/bfin/10799.s
create mode 100644 tests/tcg/bfin/7641.s
create mode 100644 tests/tcg/bfin/Makefile
create mode 100644 tests/tcg/bfin/a0.s
create mode 100644 tests/tcg/bfin/a1.s
create mode 100644 tests/tcg/bfin/a10.s
create mode 100644 tests/tcg/bfin/a2.s
create mode 100644 tests/tcg/bfin/a24.s
create mode 100644 tests/tcg/bfin/a25.s
create mode 100644 tests/tcg/bfin/a26.s
create mode 100644 tests/tcg/bfin/a3.s
create mode 100644 tests/tcg/bfin/a4.s
create mode 100644 tests/tcg/bfin/a7.s
create mode 100644 tests/tcg/bfin/a8.s
create mode 100644 tests/tcg/bfin/a9.s
create mode 100644 tests/tcg/bfin/abs-2.S
create mode 100644 tests/tcg/bfin/abs-3.S
create mode 100644 tests/tcg/bfin/abs.S
create mode 100644 tests/tcg/bfin/acc-rot.s
create mode 100644 tests/tcg/bfin/acp5_19.s
create mode 100644 tests/tcg/bfin/add_imm7.s
create mode 100644 tests/tcg/bfin/algnbug1.s
create mode 100644 tests/tcg/bfin/algnbug2.s
create mode 100644 tests/tcg/bfin/b0.S
create mode 100644 tests/tcg/bfin/b1.s
create mode 100644 tests/tcg/bfin/b2.S
create mode 100644 tests/tcg/bfin/brcc.s
create mode 100644 tests/tcg/bfin/brevadd.s
create mode 100644 tests/tcg/bfin/byteunpack.s
create mode 100644 tests/tcg/bfin/c_alu2op_arith_r_sft.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_b.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_h.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_mix.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_neg.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_toggle.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_xb.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_xh.s
create mode 100644 tests/tcg/bfin/c_alu2op_divq.s
create mode 100644 tests/tcg/bfin/c_alu2op_divs.s
create mode 100644 tests/tcg/bfin/c_alu2op_log_l_sft.s
create mode 100644 tests/tcg/bfin/c_alu2op_log_r_sft.s
create mode 100644 tests/tcg/bfin/c_alu2op_shadd_1.s
create mode 100644 tests/tcg/bfin/c_alu2op_shadd_2.s
create mode 100644 tests/tcg/bfin/c_br_preg_killed_ac.s
create mode 100644 tests/tcg/bfin/c_br_preg_killed_ex1.s
create mode 100644 tests/tcg/bfin/c_br_preg_stall_ac.s
create mode 100644 tests/tcg/bfin/c_br_preg_stall_ex1.s
create mode 100644 tests/tcg/bfin/c_brcc_bp1.s
create mode 100644 tests/tcg/bfin/c_brcc_bp2.s
create mode 100644 tests/tcg/bfin/c_brcc_bp3.s
create mode 100644 tests/tcg/bfin/c_brcc_bp4.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_bp.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_brt_bp.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_brt_nbp.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_fbkwd.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_nbp.s
create mode 100644 tests/tcg/bfin/c_brcc_brt_bp.s
create mode 100644 tests/tcg/bfin/c_brcc_brt_nbp.s
create mode 100644 tests/tcg/bfin/c_calla_ljump.s
create mode 100644 tests/tcg/bfin/c_calla_subr.s
create mode 100644 tests/tcg/bfin/c_cc2dreg.s
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_ac.S
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_an.s
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_aq.s
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_av0.S
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_av1.S
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_az.s
create mode 100644 tests/tcg/bfin/c_cc_flag_ccmv_depend.S
create mode 100644 tests/tcg/bfin/c_cc_flagdreg_mvbrsft.s
create mode 100644 tests/tcg/bfin/c_cc_regmvlogi_mvbrsft.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_dr.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_dr_uu.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_imm3.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_imm3_uu.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_imm3.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_imm3_uu.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_pr.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_pr_uu.s
create mode 100644 tests/tcg/bfin/c_ccmv_cc_dr_dr.s
create mode 100644 tests/tcg/bfin/c_ccmv_cc_dr_pr.s
create mode 100644 tests/tcg/bfin/c_ccmv_cc_pr_pr.s
create mode 100644 tests/tcg/bfin/c_ccmv_ncc_dr_dr.s
create mode 100644 tests/tcg/bfin/c_ccmv_ncc_dr_pr.s
create mode 100644 tests/tcg/bfin/c_ccmv_ncc_pr_pr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_and_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_minus_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_mix.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_or_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_plus_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_xor_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_pr_plus_pr_sh1.s
create mode 100644 tests/tcg/bfin/c_comp3op_pr_plus_pr_sh2.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_add_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_add_i7_p.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_eq_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_eq_i7_p.s
create mode 100644 tests/tcg/bfin/c_compi2opd_flags.S
create mode 100644 tests/tcg/bfin/c_compi2opd_flags_2.S
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_add_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_add_i7_p.s
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_eq_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_eq_i7_p.s
create mode 100644 tests/tcg/bfin/c_dagmodik_lnz_imgebl.s
create mode 100644 tests/tcg/bfin/c_dagmodik_lnz_imltbl.s
create mode 100644 tests/tcg/bfin/c_dagmodik_lz_inc_dec.s
create mode 100644 tests/tcg/bfin/c_dagmodim_lnz_imgebl.s
create mode 100644 tests/tcg/bfin/c_dagmodim_lnz_imltbl.s
create mode 100644 tests/tcg/bfin/c_dagmodim_lz_inc_dec.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_a_neg_a.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_aa_absabs.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_aa_negneg.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_abs.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_absabs.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_awx.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_bytepack.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_byteunpack.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_disalnexcpt.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_max.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_maxmax.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_min.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_minmin.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_rr_lph_a1a0.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_search.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_sgn.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_a1a0.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a0.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a0_i.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a0_m.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a1.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a1_i.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a1_m.s
create mode 100644 tests/tcg/bfin/c_dsp32mult_pair_m.s
create mode 100644 tests/tcg/bfin/c_dsp32mult_pair_m_i.s
create mode 100644 tests/tcg/bfin/c_dsp32mult_pair_m_u.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_a0alr.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_af.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rn_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rp_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_align16.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_align24.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_align8.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_fdepx.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_fextx.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lf.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ones.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_pack.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_rot.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_rot_mix.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_signbits_r.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_signbits_rh.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_signbits_rl.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_vmax.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_vmaxvmax.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_a0alr.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_af.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_af_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rn_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rp_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahh.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_amix.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lf.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhh.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lmix.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_rot.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_dr_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_dr_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_dr_ippm.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drhi_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drhi_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drlo_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drlo_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_dr_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_dr_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_dr_ippm.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drhi_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drhi_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drlo_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drlo_ipp.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_dreg.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_drhi.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_drlo.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_h_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_h_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_h_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_l_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_l_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_l_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lz_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lz_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lz_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lzhi_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lzhi_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lzhi_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_pibml.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_b.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_h.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_b.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_h.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_xb.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_xh.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_b.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_h.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_xb.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_xh.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_ppmm_hbx.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_xb.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_xh.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_p_p.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_p_p_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_p_p_pp.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_b.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_h.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_mm_b.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_mm_h.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_pp.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_pp_b.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_pp_h.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_p.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_p_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_p_pp.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_b.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_xb.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_xh.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_preg.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_dr_b.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_preg.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_dr_xh.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_preg.s
create mode 100644 tests/tcg/bfin/c_ldstii_st_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstii_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstii_st_preg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_ld_preg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_st_preg.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_dr_hi.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_dr_lo.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_h_xh.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_lohi.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_dr_hi.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_dr_lo.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_lohi.s
create mode 100644 tests/tcg/bfin/c_linkage.s
create mode 100644 tests/tcg/bfin/c_logi2op_alshft_mix.s
create mode 100644 tests/tcg/bfin/c_logi2op_arith_shft.s
create mode 100644 tests/tcg/bfin/c_logi2op_bitclr.s
create mode 100644 tests/tcg/bfin/c_logi2op_bitset.s
create mode 100644 tests/tcg/bfin/c_logi2op_bittgl.s
create mode 100644 tests/tcg/bfin/c_logi2op_bittst.s
create mode 100644 tests/tcg/bfin/c_logi2op_log_l_shft.s
create mode 100644 tests/tcg/bfin/c_logi2op_log_l_shft_astat.S
create mode 100644 tests/tcg/bfin/c_logi2op_log_r_shft.s
create mode 100644 tests/tcg/bfin/c_logi2op_log_r_shft_astat.S
create mode 100644 tests/tcg/bfin/c_logi2op_nbittst.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested_bot.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested_prelc.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested_top.s
create mode 100644 tests/tcg/bfin/c_loopsetup_overlap.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_div2_lc0.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_div2_lc1.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_lc0.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_lc1.s
create mode 100644 tests/tcg/bfin/c_loopsetup_prelc.s
create mode 100644 tests/tcg/bfin/c_loopsetup_topbotcntr.s
create mode 100644 tests/tcg/bfin/c_progctrl_call_pcpr.s
create mode 100644 tests/tcg/bfin/c_progctrl_call_pr.s
create mode 100644 tests/tcg/bfin/c_progctrl_jump_pcpr.s
create mode 100644 tests/tcg/bfin/c_progctrl_jump_pr.s
create mode 100644 tests/tcg/bfin/c_progctrl_nop.s
create mode 100644 tests/tcg/bfin/c_progctrl_rts.s
create mode 100644 tests/tcg/bfin/c_ptr2op_pr_neg_pr.s
create mode 100644 tests/tcg/bfin/c_ptr2op_pr_sft_2_1.s
create mode 100644 tests/tcg/bfin/c_ptr2op_pr_shadd_1_2.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_dp.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_dp_pair.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_dreg.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_preg.s
create mode 100644 tests/tcg/bfin/c_regmv_acc_acc.s
create mode 100644 tests/tcg/bfin/c_regmv_dag_lz_dep.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_acc_acc.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_dep_nostall.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_dr.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_imlb.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_pr.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_dep_nostall.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_dep_stall.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_dr.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_imlb.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_pr.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_dep_nostall.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_dep_stall.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_dr.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_imlb.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_pr.s
create mode 100644 tests/tcg/bfin/c_ujump.s
create mode 100644 tests/tcg/bfin/cc-astat-bits.s
create mode 100644 tests/tcg/bfin/cc1.s
create mode 100644 tests/tcg/bfin/cir.s
create mode 100644 tests/tcg/bfin/cir1.s
create mode 100644 tests/tcg/bfin/cmpdreg.S
create mode 100644 tests/tcg/bfin/compare.s
create mode 100644 tests/tcg/bfin/d0.s
create mode 100644 tests/tcg/bfin/d1.s
create mode 100644 tests/tcg/bfin/d2.s
create mode 100644 tests/tcg/bfin/div0.s
create mode 100644 tests/tcg/bfin/divq.s
create mode 100644 tests/tcg/bfin/dotproduct.s
create mode 100644 tests/tcg/bfin/dotproduct2.s
create mode 100644 tests/tcg/bfin/dsp_d0.s
create mode 100644 tests/tcg/bfin/dsp_d1.s
create mode 100644 tests/tcg/bfin/edn_snafu.s
create mode 100644 tests/tcg/bfin/events.s
create mode 100644 tests/tcg/bfin/fact.s
create mode 100644 tests/tcg/bfin/fsm.s
create mode 100644 tests/tcg/bfin/greg2.s
create mode 100644 tests/tcg/bfin/hwloop-branch-in.s
create mode 100644 tests/tcg/bfin/hwloop-branch-out.s
create mode 100644 tests/tcg/bfin/hwloop-lt-bits.s
create mode 100644 tests/tcg/bfin/hwloop-nested.s
create mode 100644 tests/tcg/bfin/i0.s
create mode 100644 tests/tcg/bfin/issue113.s
create mode 100644 tests/tcg/bfin/issue126.s
create mode 100644 tests/tcg/bfin/issue129.s
create mode 100644 tests/tcg/bfin/issue144.s
create mode 100644 tests/tcg/bfin/issue83.s
create mode 100644 tests/tcg/bfin/issue89.s
create mode 100644 tests/tcg/bfin/l0.s
create mode 100644 tests/tcg/bfin/l0shift.s
create mode 100644 tests/tcg/bfin/l2_loop.s
create mode 100644 tests/tcg/bfin/link-2.s
create mode 100644 tests/tcg/bfin/link.s
create mode 100644 tests/tcg/bfin/load.s
create mode 100644 tests/tcg/bfin/logic.s
create mode 100644 tests/tcg/bfin/loop_snafu.s
create mode 100644 tests/tcg/bfin/loop_strncpy.s
create mode 100644 tests/tcg/bfin/lp0.s
create mode 100644 tests/tcg/bfin/lp1.s
create mode 100644 tests/tcg/bfin/lsetup.s
create mode 100644 tests/tcg/bfin/m0boundary.s
create mode 100644 tests/tcg/bfin/m17.s
create mode 100644 tests/tcg/bfin/max_min_flags.s
create mode 100644 tests/tcg/bfin/mem3.s
create mode 100644 tests/tcg/bfin/move.s
create mode 100644 tests/tcg/bfin/neg.S
create mode 100644 tests/tcg/bfin/nshift.s
create mode 100644 tests/tcg/bfin/pr.s
create mode 100644 tests/tcg/bfin/push-pop-multiple.s
create mode 100644 tests/tcg/bfin/push-pop.s
create mode 100644 tests/tcg/bfin/pushpopreg_1.s
create mode 100644 tests/tcg/bfin/s0.s
create mode 100644 tests/tcg/bfin/s1.s
create mode 100644 tests/tcg/bfin/s10.s
create mode 100644 tests/tcg/bfin/s15.s
create mode 100644 tests/tcg/bfin/s16.s
create mode 100644 tests/tcg/bfin/s17.s
create mode 100644 tests/tcg/bfin/s2.s
create mode 100644 tests/tcg/bfin/s20.s
create mode 100644 tests/tcg/bfin/s21.s
create mode 100644 tests/tcg/bfin/s4.s
create mode 100644 tests/tcg/bfin/s5.s
create mode 100644 tests/tcg/bfin/s6.s
create mode 100644 tests/tcg/bfin/s7.s
create mode 100644 tests/tcg/bfin/s8.s
create mode 100644 tests/tcg/bfin/s9.s
create mode 100644 tests/tcg/bfin/se_kills2.S
create mode 100644 tests/tcg/bfin/se_rets_hazard.s
create mode 100644 tests/tcg/bfin/sign.s
create mode 100644 tests/tcg/bfin/simple0.s
create mode 100644 tests/tcg/bfin/stk.s
create mode 100644 tests/tcg/bfin/stk2.s
create mode 100644 tests/tcg/bfin/stk3.s
create mode 100644 tests/tcg/bfin/stk4.s
create mode 100644 tests/tcg/bfin/stk5.s
create mode 100644 tests/tcg/bfin/stk6.s
create mode 100644 tests/tcg/bfin/tar10622.s
create mode 100644 tests/tcg/bfin/test.h
create mode 100644 tests/tcg/bfin/testset.s
create mode 100644 tests/tcg/bfin/testset2.s
create mode 100644 tests/tcg/bfin/testutils.inc
create mode 100644 tests/tcg/bfin/vec-abs.S
create mode 100644 tests/tcg/bfin/vecadd.s
create mode 100644 tests/tcg/bfin/vit_max.s
create mode 100644 tests/tcg/bfin/wtf.s
create mode 100644 tests/tcg/bfin/zcall.s
--
1.8.2.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 1/5] Blackfin: add disassembler support
2013-06-17 7:13 [Qemu-devel] [PATCH 0/5] Initial Blackfin support (linux-user only) Mike Frysinger
@ 2013-06-17 7:13 ` Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
1 sibling, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2013-06-17 7:13 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
configure | 4 +
disas.c | 9 +
disas/Makefile.objs | 1 +
disas/bfin.c | 4791 +++++++++++++++++++++++++++++++++++++++++++++
include/disas/bfd.h | 3 +
target-bfin/opcode/bfin.h | 1754 +++++++++++++++++
6 files changed, 6562 insertions(+)
create mode 100644 disas/bfin.c
create mode 100644 target-bfin/opcode/bfin.h
diff --git a/configure b/configure
index 60b0811..bc7a9c0 100755
--- a/configure
+++ b/configure
@@ -4331,6 +4331,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
echo "CONFIG_ARM_DIS=y" >> $config_target_mak
echo "CONFIG_ARM_DIS=y" >> config-all-disas.mak
;;
+ bfin)
+ echo "CONFIG_BFIN_DIS=y" >> $config_target_mak
+ echo "CONFIG_BFIN_DIS=y" >> config-all-disas.mak
+ ;;
cris)
echo "CONFIG_CRIS_DIS=y" >> $config_target_mak
echo "CONFIG_CRIS_DIS=y" >> config-all-disas.mak
diff --git a/disas.c b/disas.c
index e51127e..3748a30 100644
--- a/disas.c
+++ b/disas.c
@@ -208,6 +208,9 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
s.info.endian = BFD_ENDIAN_BIG;
#endif
}
+#elif defined(TARGET_BFIN)
+ s.info.mach = bfd_mach_bfin;
+ print_insn = print_insn_bfin;
#elif defined(TARGET_SPARC)
print_insn = print_insn_sparc;
#ifdef TARGET_SPARC64
@@ -335,6 +338,9 @@ void disas(FILE *out, void *code, unsigned long size)
s.info.mach = bfd_mach_sparc_v9b;
#elif defined(__arm__)
print_insn = print_insn_arm;
+#elif defined(__bfin__)
+ s.info.mach = bfd_mach_bfin;
+ print_insn = print_insn_bfin;
#elif defined(__MIPSEB__)
print_insn = print_insn_big_mips;
#elif defined(__MIPSEL__)
@@ -439,6 +445,9 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
print_insn = print_insn_i386;
#elif defined(TARGET_ARM)
print_insn = print_insn_arm;
+#elif defined(TARGET_BFIN)
+ s.info.mach = bfd_mach_bfin;
+ print_insn = print_insn_bfin;
#elif defined(TARGET_ALPHA)
print_insn = print_insn_alpha;
#elif defined(TARGET_SPARC)
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 3b1e77a..3f190c6 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -1,5 +1,6 @@
common-obj-$(CONFIG_ALPHA_DIS) += alpha.o
common-obj-$(CONFIG_ARM_DIS) += arm.o
+common-obj-$(CONFIG_BFIN_DIS) += bfin.o
common-obj-$(CONFIG_CRIS_DIS) += cris.o
common-obj-$(CONFIG_HPPA_DIS) += hppa.o
common-obj-$(CONFIG_I386_DIS) += i386.o
diff --git a/disas/bfin.c b/disas/bfin.c
new file mode 100644
index 0000000..bdf9eba
--- /dev/null
+++ b/disas/bfin.c
@@ -0,0 +1,4791 @@
+/* Disassemble ADI Blackfin Instructions.
+ Copyright 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "disas/bfd.h"
+#include "target-bfin/opcode/bfin.h"
+
+#ifndef PRINTF
+#define PRINTF printf
+#endif
+
+#ifndef EXIT
+#define EXIT exit
+#endif
+
+typedef long TIword;
+
+#define HOST_LONG_WORD_SIZE (sizeof (long) * 8)
+#define XFIELD(w,p,s) (((w) & ((1 << (s)) - 1) << (p)) >> (p))
+#define SIGNEXTEND(v, n) ((v << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))
+#define MASKBITS(val, bits) (val & ((1 << bits) - 1))
+
+typedef unsigned int bu32;
+
+static char comment = 0;
+static char parallel = 0;
+
+typedef enum
+{
+ c_0, c_1, c_4, c_2, c_uimm2, c_uimm3, c_imm3, c_pcrel4,
+ c_imm4, c_uimm4s4, c_uimm4s4d, c_uimm4, c_uimm4s2, c_negimm5s4, c_imm5, c_imm5d, c_uimm5, c_imm6,
+ c_imm7, c_imm7d, c_imm8, c_uimm8, c_pcrel8, c_uimm8s4, c_pcrel8s4, c_lppcrel10, c_pcrel10,
+ c_pcrel12, c_imm16s4, c_luimm16, c_imm16, c_imm16d, c_huimm16, c_rimm16, c_imm16s2, c_uimm16s4,
+ c_uimm16s4d, c_uimm16, c_pcrel24, c_uimm32, c_imm32, c_huimm32, c_huimm32e,
+} const_forms_t;
+
+static const struct
+{
+ const char *name;
+ const int nbits;
+ const char reloc;
+ const char issigned;
+ const char pcrel;
+ const char scale;
+ const char offset;
+ const char negative;
+ const char positive;
+ const char decimal;
+ const char leading;
+ const char exact;
+} constant_formats[] =
+{
+ { "0", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "1", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "4", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "2", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm2", 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm3", 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm3", 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel4", 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "imm4", 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm4s4", 4, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0},
+ { "uimm4s4d", 4, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0},
+ { "uimm4", 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm4s2", 4, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},
+ { "negimm5s4", 5, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0},
+ { "imm5", 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm5d", 5, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
+ { "uimm5", 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm6", 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm7", 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm7d", 7, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "imm8", 8, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm8", 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel8", 8, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm8s4", 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "pcrel8s4", 8, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
+ { "lppcrel10", 10, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "pcrel10", 10, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "pcrel12", 12, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "imm16s4", 16, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "luimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16", 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16d", 16, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "huimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "rimm16", 16, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16s2", 16, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm16s4", 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "uimm16s4d", 16, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0},
+ { "uimm16", 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel24", 24, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm32", 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm32", 32, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "huimm32", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "huimm32e", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+};
+
+static const char *
+fmtconst (const_forms_t cf, TIword x, bfd_vma pc, disassemble_info *outf)
+{
+ static char buf[60];
+
+ if (constant_formats[cf].reloc)
+ {
+ bfd_vma ea = (((constant_formats[cf].pcrel ? SIGNEXTEND (x, constant_formats[cf].nbits)
+ : x) + constant_formats[cf].offset) << constant_formats[cf].scale);
+ if (constant_formats[cf].pcrel)
+ ea += pc;
+
+ /* truncate to 32-bits for proper symbol lookup/matching */
+ ea = (bu32)ea;
+
+ if (outf->symbol_at_address_func (ea, outf) || !constant_formats[cf].exact)
+ {
+ outf->print_address_func (ea, outf);
+ return "";
+ }
+ else
+ {
+ sprintf (buf, "%#lx", x);
+ return buf;
+ }
+ }
+
+ /* Negative constants have an implied sign bit. */
+ if (constant_formats[cf].negative)
+ {
+ int nb = constant_formats[cf].nbits + 1;
+
+ x = x | (1 << constant_formats[cf].nbits);
+ x = SIGNEXTEND (x, nb);
+ }
+ else
+ x = constant_formats[cf].issigned ? SIGNEXTEND (x, constant_formats[cf].nbits) : x;
+
+ if (constant_formats[cf].offset)
+ x += constant_formats[cf].offset;
+
+ if (constant_formats[cf].scale)
+ x <<= constant_formats[cf].scale;
+
+ if (constant_formats[cf].decimal)
+ sprintf (buf, "%*li", constant_formats[cf].leading, x);
+ else
+ {
+ if (constant_formats[cf].issigned && x < 0)
+ sprintf (buf, "-0x%x", abs (x));
+ else
+ sprintf (buf, "0x%lx", x);
+ }
+
+ return buf;
+}
+
+static bu32
+fmtconst_val (const_forms_t cf, unsigned int x, unsigned int pc)
+{
+ if (0 && constant_formats[cf].reloc)
+ {
+ bu32 ea = (((constant_formats[cf].pcrel
+ ? SIGNEXTEND (x, constant_formats[cf].nbits)
+ : x) + constant_formats[cf].offset)
+ << constant_formats[cf].scale);
+ if (constant_formats[cf].pcrel)
+ ea += pc;
+
+ return ea;
+ }
+
+ /* Negative constants have an implied sign bit. */
+ if (constant_formats[cf].negative)
+ {
+ int nb = constant_formats[cf].nbits + 1;
+ x = x | (1 << constant_formats[cf].nbits);
+ x = SIGNEXTEND (x, nb);
+ }
+ else if (constant_formats[cf].issigned)
+ x = SIGNEXTEND (x, constant_formats[cf].nbits);
+
+ x += constant_formats[cf].offset;
+ x <<= constant_formats[cf].scale;
+
+ return x;
+}
+
+enum machine_registers
+{
+ REG_RL0, REG_RL1, REG_RL2, REG_RL3, REG_RL4, REG_RL5, REG_RL6, REG_RL7,
+ REG_RH0, REG_RH1, REG_RH2, REG_RH3, REG_RH4, REG_RH5, REG_RH6, REG_RH7,
+ REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_R1_0, REG_R3_2, REG_R5_4, REG_R7_6, REG_P0, REG_P1, REG_P2, REG_P3,
+ REG_P4, REG_P5, REG_SP, REG_FP, REG_A0x, REG_A1x, REG_A0w, REG_A1w,
+ REG_A0, REG_A1, REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1,
+ REG_M2, REG_M3, REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1,
+ REG_L2, REG_L3,
+ REG_AZ, REG_AN, REG_AC0, REG_AC1, REG_AV0, REG_AV1, REG_AV0S, REG_AV1S,
+ REG_AQ, REG_V, REG_VS,
+ REG_sftreset, REG_omode, REG_excause, REG_emucause, REG_idle_req, REG_hwerrcause, REG_CC, REG_LC0,
+ REG_LC1, REG_ASTAT, REG_RETS, REG_LT0, REG_LB0, REG_LT1, REG_LB1,
+ REG_CYCLES, REG_CYCLES2, REG_USP, REG_SEQSTAT, REG_SYSCFG, REG_RETI, REG_RETX, REG_RETN,
+ REG_RETE, REG_EMUDAT, REG_BR0, REG_BR1, REG_BR2, REG_BR3, REG_BR4, REG_BR5, REG_BR6,
+ REG_BR7, REG_PL0, REG_PL1, REG_PL2, REG_PL3, REG_PL4, REG_PL5, REG_SLP, REG_FLP,
+ REG_PH0, REG_PH1, REG_PH2, REG_PH3, REG_PH4, REG_PH5, REG_SHP, REG_FHP,
+ REG_IL0, REG_IL1, REG_IL2, REG_IL3, REG_ML0, REG_ML1, REG_ML2, REG_ML3,
+ REG_BL0, REG_BL1, REG_BL2, REG_BL3, REG_LL0, REG_LL1, REG_LL2, REG_LL3,
+ REG_IH0, REG_IH1, REG_IH2, REG_IH3, REG_MH0, REG_MH1, REG_MH2, REG_MH3,
+ REG_BH0, REG_BH1, REG_BH2, REG_BH3, REG_LH0, REG_LH1, REG_LH2, REG_LH3,
+ REG_AC0_COPY, REG_V_COPY, REG_RND_MOD,
+ REG_LASTREG,
+};
+
+enum reg_class
+{
+ rc_dregs_lo, rc_dregs_hi, rc_dregs, rc_dregs_pair, rc_pregs, rc_spfp, rc_dregs_hilo, rc_accum_ext,
+ rc_accum_word, rc_accum, rc_iregs, rc_mregs, rc_bregs, rc_lregs, rc_dpregs, rc_gregs,
+ rc_regs, rc_statbits, rc_ignore_bits, rc_ccstat, rc_counters, rc_dregs2_sysregs1, rc_open, rc_sysregs2,
+ rc_sysregs3, rc_allregs,
+ LIM_REG_CLASSES
+};
+
+static const char * const reg_names[] =
+{
+ "R0.L", "R1.L", "R2.L", "R3.L", "R4.L", "R5.L", "R6.L", "R7.L",
+ "R0.H", "R1.H", "R2.H", "R3.H", "R4.H", "R5.H", "R6.H", "R7.H",
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
+ "R1:0", "R3:2", "R5:4", "R7:6", "P0", "P1", "P2", "P3",
+ "P4", "P5", "SP", "FP", "A0.X", "A1.X", "A0.W", "A1.W",
+ "A0", "A1", "I0", "I1", "I2", "I3", "M0", "M1",
+ "M2", "M3", "B0", "B1", "B2", "B3", "L0", "L1",
+ "L2", "L3",
+ "AZ", "AN", "AC0", "AC1", "AV0", "AV1", "AV0S", "AV1S",
+ "AQ", "V", "VS",
+ "sftreset", "omode", "excause", "emucause", "idle_req", "hwerrcause", "CC", "LC0",
+ "LC1", "ASTAT", "RETS", "LT0", "LB0", "LT1", "LB1",
+ "CYCLES", "CYCLES2", "USP", "SEQSTAT", "SYSCFG", "RETI", "RETX", "RETN",
+ "RETE", "EMUDAT",
+ "R0.B", "R1.B", "R2.B", "R3.B", "R4.B", "R5.B", "R6.B", "R7.B",
+ "P0.L", "P1.L", "P2.L", "P3.L", "P4.L", "P5.L", "SP.L", "FP.L",
+ "P0.H", "P1.H", "P2.H", "P3.H", "P4.H", "P5.H", "SP.H", "FP.H",
+ "I0.L", "I1.L", "I2.L", "I3.L", "M0.L", "M1.L", "M2.L", "M3.L",
+ "B0.L", "B1.L", "B2.L", "B3.L", "L0.L", "L1.L", "L2.L", "L3.L",
+ "I0.H", "I1.H", "I2.H", "I3.H", "M0.H", "M1.H", "M2.H", "M3.H",
+ "B0.H", "B1.H", "B2.H", "B3.H", "L0.H", "L1.H", "L2.H", "L3.H",
+ "AC0_COPY", "V_COPY", "RND_MOD",
+ "LASTREG",
+ 0
+};
+
+#define REGNAME(x) ((x) < REG_LASTREG ? (reg_names[x]) : "...... Illegal register .......")
+
+/* RL(0..7). */
+static const enum machine_registers decode_dregs_lo[] =
+{
+ REG_RL0, REG_RL1, REG_RL2, REG_RL3, REG_RL4, REG_RL5, REG_RL6, REG_RL7,
+};
+
+#define dregs_lo(x) REGNAME (decode_dregs_lo[(x) & 7])
+
+/* RH(0..7). */
+static const enum machine_registers decode_dregs_hi[] =
+{
+ REG_RH0, REG_RH1, REG_RH2, REG_RH3, REG_RH4, REG_RH5, REG_RH6, REG_RH7,
+};
+
+#define dregs_hi(x) REGNAME (decode_dregs_hi[(x) & 7])
+
+/* R(0..7). */
+static const enum machine_registers decode_dregs[] =
+{
+ REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+};
+
+#define dregs(x) REGNAME (decode_dregs[(x) & 7])
+
+/* R BYTE(0..7). */
+static const enum machine_registers decode_dregs_byte[] =
+{
+ REG_BR0, REG_BR1, REG_BR2, REG_BR3, REG_BR4, REG_BR5, REG_BR6, REG_BR7,
+};
+
+#define dregs_byte(x) REGNAME (decode_dregs_byte[(x) & 7])
+
+/* P(0..5) SP FP. */
+static const enum machine_registers decode_pregs[] =
+{
+ REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
+};
+
+#define pregs(x) REGNAME (decode_pregs[(x) & 7])
+#define spfp(x) REGNAME (decode_spfp[(x) & 1])
+#define dregs_hilo(x, i) REGNAME (decode_dregs_hilo[((i) << 3) | (x)])
+#define accum_ext(x) REGNAME (decode_accum_ext[(x) & 1])
+#define accum_word(x) REGNAME (decode_accum_word[(x) & 1])
+#define accum(x) REGNAME (decode_accum[(x) & 1])
+
+/* I(0..3). */
+static const enum machine_registers decode_iregs[] =
+{
+ REG_I0, REG_I1, REG_I2, REG_I3,
+};
+
+#define iregs(x) REGNAME (decode_iregs[(x) & 3])
+
+/* M(0..3). */
+static const enum machine_registers decode_mregs[] =
+{
+ REG_M0, REG_M1, REG_M2, REG_M3,
+};
+
+#define mregs(x) REGNAME (decode_mregs[(x) & 3])
+#define bregs(x) REGNAME (decode_bregs[(x) & 3])
+#define lregs(x) REGNAME (decode_lregs[(x) & 3])
+
+/* dregs pregs. */
+static const enum machine_registers decode_dpregs[] =
+{
+ REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
+};
+
+#define dpregs(x) REGNAME (decode_dpregs[(x) & 15])
+
+/* [dregs pregs]. */
+static const enum machine_registers decode_gregs[] =
+{
+ REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
+};
+
+#define gregs(x, i) REGNAME (decode_gregs[((i) << 3) | (x)])
+
+/* [dregs pregs (iregs mregs) (bregs lregs)]. */
+static const enum machine_registers decode_regs[] =
+{
+ REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
+ REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3,
+ REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,
+};
+
+#define regs(x, i) REGNAME (decode_regs[((i) << 3) | (x)])
+
+/* [dregs pregs (iregs mregs) (bregs lregs) Low Half]. */
+static const enum machine_registers decode_regs_lo[] =
+{
+ REG_RL0, REG_RL1, REG_RL2, REG_RL3, REG_RL4, REG_RL5, REG_RL6, REG_RL7,
+ REG_PL0, REG_PL1, REG_PL2, REG_PL3, REG_PL4, REG_PL5, REG_SLP, REG_FLP,
+ REG_IL0, REG_IL1, REG_IL2, REG_IL3, REG_ML0, REG_ML1, REG_ML2, REG_ML3,
+ REG_BL0, REG_BL1, REG_BL2, REG_BL3, REG_LL0, REG_LL1, REG_LL2, REG_LL3,
+};
+
+#define regs_lo(x, i) REGNAME (decode_regs_lo[((i) << 3) | (x)])
+
+/* [dregs pregs (iregs mregs) (bregs lregs) High Half]. */
+static const enum machine_registers decode_regs_hi[] =
+{
+ REG_RH0, REG_RH1, REG_RH2, REG_RH3, REG_RH4, REG_RH5, REG_RH6, REG_RH7,
+ REG_PH0, REG_PH1, REG_PH2, REG_PH3, REG_PH4, REG_PH5, REG_SHP, REG_FHP,
+ REG_IH0, REG_IH1, REG_IH2, REG_IH3, REG_MH0, REG_MH1, REG_MH2, REG_MH3,
+ REG_BH0, REG_BH1, REG_BH2, REG_BH3, REG_LH0, REG_LH1, REG_LH2, REG_LH3,
+};
+
+#define regs_hi(x, i) REGNAME (decode_regs_hi[((i) << 3) | (x)])
+
+static const enum machine_registers decode_statbits[] =
+{
+ REG_AZ, REG_AN, REG_AC0_COPY, REG_V_COPY,
+ REG_LASTREG, REG_LASTREG, REG_AQ, REG_LASTREG,
+ REG_RND_MOD, REG_LASTREG, REG_LASTREG, REG_LASTREG,
+ REG_AC0, REG_AC1, REG_LASTREG, REG_LASTREG,
+ REG_AV0, REG_AV0S, REG_AV1, REG_AV1S,
+ REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG,
+ REG_V, REG_VS, REG_LASTREG, REG_LASTREG,
+ REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG,
+};
+
+#define statbits(x) REGNAME (decode_statbits[(x) & 31])
+
+/* LC0 LC1. */
+static const enum machine_registers decode_counters[] =
+{
+ REG_LC0, REG_LC1,
+};
+
+#define counters(x) REGNAME (decode_counters[(x) & 1])
+#define dregs2_sysregs1(x) REGNAME (decode_dregs2_sysregs1[(x) & 7])
+
+/* [dregs pregs (iregs mregs) (bregs lregs)
+ dregs2_sysregs1 open sysregs2 sysregs3]. */
+static const enum machine_registers decode_allregs[] =
+{
+ REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
+ REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3,
+ REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,
+ REG_A0x, REG_A0w, REG_A1x, REG_A1w, REG_LASTREG, REG_LASTREG, REG_ASTAT, REG_RETS,
+ REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG, REG_LASTREG,
+ REG_LC0, REG_LT0, REG_LB0, REG_LC1, REG_LT1, REG_LB1, REG_CYCLES, REG_CYCLES2,
+ REG_USP, REG_SEQSTAT, REG_SYSCFG, REG_RETI, REG_RETX, REG_RETN, REG_RETE, REG_EMUDAT,
+ REG_LASTREG,
+};
+
+#define IS_DREG(g,r) ((g) == 0 && (r) < 8)
+#define IS_PREG(g,r) ((g) == 1 && (r) < 8)
+#define IS_AREG(g,r) ((g) == 4 && (r) >= 0 && (r) < 4)
+#define IS_GENREG(g,r) ((((g) == 0 || (g) == 1) && (r) < 8) || IS_AREG (g, r))
+#define IS_DAGREG(g,r) (((g) == 2 || (g) == 3) && (r) < 8)
+#define IS_SYSREG(g,r) \
+ (((g) == 4 && ((r) == 6 || (r) == 7)) || (g) == 6 || (g) == 7)
+#define IS_RESERVEDREG(g,r) \
+ (((r) > 7) || ((g) == 4 && ((r) == 4 || (r) == 5)) || (g) == 5)
+
+#define allreg(r,g) (!IS_RESERVEDREG (g, r))
+#define mostreg(r,g) (!(IS_DREG (g, r) || IS_PREG (g, r) || IS_RESERVEDREG (g, r)))
+
+#define allregs(x, i) REGNAME (decode_allregs[((i) << 3) | (x)])
+#define uimm16s4(x) fmtconst (c_uimm16s4, x, 0, outf)
+#define uimm16s4d(x) fmtconst (c_uimm16s4d, x, 0, outf)
+#define pcrel4(x) fmtconst (c_pcrel4, x, pc, outf)
+#define pcrel8(x) fmtconst (c_pcrel8, x, pc, outf)
+#define pcrel8s4(x) fmtconst (c_pcrel8s4, x, pc, outf)
+#define pcrel10(x) fmtconst (c_pcrel10, x, pc, outf)
+#define pcrel12(x) fmtconst (c_pcrel12, x, pc, outf)
+#define negimm5s4(x) fmtconst (c_negimm5s4, x, 0, outf)
+#define rimm16(x) fmtconst (c_rimm16, x, 0, outf)
+#define huimm16(x) fmtconst (c_huimm16, x, 0, outf)
+#define imm16(x) fmtconst (c_imm16, x, 0, outf)
+#define imm16d(x) fmtconst (c_imm16d, x, 0, outf)
+#define uimm2(x) fmtconst (c_uimm2, x, 0, outf)
+#define uimm3(x) fmtconst (c_uimm3, x, 0, outf)
+#define luimm16(x) fmtconst (c_luimm16, x, 0, outf)
+#define uimm4(x) fmtconst (c_uimm4, x, 0, outf)
+#define uimm5(x) fmtconst (c_uimm5, x, 0, outf)
+#define imm16s2(x) fmtconst (c_imm16s2, x, 0, outf)
+#define uimm8(x) fmtconst (c_uimm8, x, 0, outf)
+#define imm16s4(x) fmtconst (c_imm16s4, x, 0, outf)
+#define uimm4s2(x) fmtconst (c_uimm4s2, x, 0, outf)
+#define uimm4s4(x) fmtconst (c_uimm4s4, x, 0, outf)
+#define uimm4s4d(x) fmtconst (c_uimm4s4d, x, 0, outf)
+#define lppcrel10(x) fmtconst (c_lppcrel10, x, pc, outf)
+#define imm3(x) fmtconst (c_imm3, x, 0, outf)
+#define imm4(x) fmtconst (c_imm4, x, 0, outf)
+#define uimm8s4(x) fmtconst (c_uimm8s4, x, 0, outf)
+#define imm5(x) fmtconst (c_imm5, x, 0, outf)
+#define imm5d(x) fmtconst (c_imm5d, x, 0, outf)
+#define imm6(x) fmtconst (c_imm6, x, 0, outf)
+#define imm7(x) fmtconst (c_imm7, x, 0, outf)
+#define imm7d(x) fmtconst (c_imm7d, x, 0, outf)
+#define imm8(x) fmtconst (c_imm8, x, 0, outf)
+#define pcrel24(x) fmtconst (c_pcrel24, x, pc, outf)
+#define uimm16(x) fmtconst (c_uimm16, x, 0, outf)
+#define uimm32(x) fmtconst (c_uimm32, x, 0, outf)
+#define imm32(x) fmtconst (c_imm32, x, 0, outf)
+#define huimm32(x) fmtconst (c_huimm32, x, 0, outf)
+#define huimm32e(x) fmtconst (c_huimm32e, x, 0, outf)
+#define imm7_val(x) fmtconst_val (c_imm7, x, 0)
+#define imm16_val(x) fmtconst_val (c_uimm16, x, 0)
+#define luimm16_val(x) fmtconst_val (c_luimm16, x, 0)
+
+/* (arch.pm)arch_disassembler_functions. */
+#ifndef OUTS
+#define OUTS(p, txt) (p)->fprintf_func ((p)->stream, "%s", txt)
+#endif
+
+static void
+amod0 (int s0, int x0, disassemble_info *outf)
+{
+ if (s0 == 1 && x0 == 0)
+ OUTS (outf, " (S)");
+ else if (s0 == 0 && x0 == 1)
+ OUTS (outf, " (CO)");
+ else if (s0 == 1 && x0 == 1)
+ OUTS (outf, " (SCO)");
+}
+
+static void
+amod1 (int s0, int x0, disassemble_info *outf)
+{
+ if (s0 == 0 && x0 == 0)
+ OUTS (outf, " (NS)");
+ else if (s0 == 1 && x0 == 0)
+ OUTS (outf, " (S)");
+}
+
+static void
+amod0amod2 (int s0, int x0, int aop0, disassemble_info *outf)
+{
+ if (s0 == 1 && x0 == 0 && aop0 == 0)
+ OUTS (outf, " (S)");
+ else if (s0 == 0 && x0 == 1 && aop0 == 0)
+ OUTS (outf, " (CO)");
+ else if (s0 == 1 && x0 == 1 && aop0 == 0)
+ OUTS (outf, " (SCO)");
+ else if (s0 == 0 && x0 == 0 && aop0 == 2)
+ OUTS (outf, " (ASR)");
+ else if (s0 == 1 && x0 == 0 && aop0 == 2)
+ OUTS (outf, " (S, ASR)");
+ else if (s0 == 0 && x0 == 1 && aop0 == 2)
+ OUTS (outf, " (CO, ASR)");
+ else if (s0 == 1 && x0 == 1 && aop0 == 2)
+ OUTS (outf, " (SCO, ASR)");
+ else if (s0 == 0 && x0 == 0 && aop0 == 3)
+ OUTS (outf, " (ASL)");
+ else if (s0 == 1 && x0 == 0 && aop0 == 3)
+ OUTS (outf, " (S, ASL)");
+ else if (s0 == 0 && x0 == 1 && aop0 == 3)
+ OUTS (outf, " (CO, ASL)");
+ else if (s0 == 1 && x0 == 1 && aop0 == 3)
+ OUTS (outf, " (SCO, ASL)");
+}
+
+static void
+searchmod (int r0, disassemble_info *outf)
+{
+ if (r0 == 0)
+ OUTS (outf, "GT");
+ else if (r0 == 1)
+ OUTS (outf, "GE");
+ else if (r0 == 2)
+ OUTS (outf, "LT");
+ else if (r0 == 3)
+ OUTS (outf, "LE");
+}
+
+static void
+aligndir (int r0, disassemble_info *outf)
+{
+ if (r0 == 1)
+ OUTS (outf, " (R)");
+}
+
+static int
+decode_multfunc (int h0, int h1, int src0, int src1, disassemble_info *outf)
+{
+ const char *s0, *s1;
+
+ if (h0)
+ s0 = dregs_hi (src0);
+ else
+ s0 = dregs_lo (src0);
+
+ if (h1)
+ s1 = dregs_hi (src1);
+ else
+ s1 = dregs_lo (src1);
+
+ OUTS (outf, s0);
+ OUTS (outf, " * ");
+ OUTS (outf, s1);
+ return 0;
+}
+
+static int
+decode_macfunc (int which, int op, int h0, int h1, int src0, int src1, disassemble_info *outf)
+{
+ const char *a;
+ const char *sop = "<unknown op>";
+
+ if (which)
+ a = "A1";
+ else
+ a = "A0";
+
+ if (op == 3)
+ {
+ OUTS (outf, a);
+ return 0;
+ }
+
+ switch (op)
+ {
+ case 0: sop = " = "; break;
+ case 1: sop = " += "; break;
+ case 2: sop = " -= "; break;
+ default: break;
+ }
+
+ OUTS (outf, a);
+ OUTS (outf, sop);
+ decode_multfunc (h0, h1, src0, src1, outf);
+
+ return 0;
+}
+
+static void
+decode_optmode (int mod, int MM, disassemble_info *outf)
+{
+ if (mod == 0 && MM == 0)
+ return;
+
+ OUTS (outf, " (");
+
+ if (MM && !mod)
+ {
+ OUTS (outf, "M)");
+ return;
+ }
+
+ if (MM)
+ OUTS (outf, "M, ");
+
+ if (mod == M_S2RND)
+ OUTS (outf, "S2RND");
+ else if (mod == M_T)
+ OUTS (outf, "T");
+ else if (mod == M_W32)
+ OUTS (outf, "W32");
+ else if (mod == M_FU)
+ OUTS (outf, "FU");
+ else if (mod == M_TFU)
+ OUTS (outf, "TFU");
+ else if (mod == M_IS)
+ OUTS (outf, "IS");
+ else if (mod == M_ISS2)
+ OUTS (outf, "ISS2");
+ else if (mod == M_IH)
+ OUTS (outf, "IH");
+ else if (mod == M_IU)
+ OUTS (outf, "IU");
+ else
+ abort ();
+
+ OUTS (outf, ")");
+}
+
+static struct saved_state
+{
+ bu32 dpregs[16], iregs[4], mregs[4], bregs[4], lregs[4];
+ bu32 ax[2], aw[2];
+ bu32 lt[2], lc[2], lb[2];
+ bu32 rets;
+} saved_state;
+
+#define DREG(x) (saved_state.dpregs[x])
+#define GREG(x, i) DPREG ((x) | ((i) << 3))
+#define DPREG(x) (saved_state.dpregs[x])
+#define DREG(x) (saved_state.dpregs[x])
+#define PREG(x) (saved_state.dpregs[(x) + 8])
+#define SPREG PREG (6)
+#define FPREG PREG (7)
+#define IREG(x) (saved_state.iregs[x])
+#define MREG(x) (saved_state.mregs[x])
+#define BREG(x) (saved_state.bregs[x])
+#define LREG(x) (saved_state.lregs[x])
+#define AXREG(x) (saved_state.ax[x])
+#define AWREG(x) (saved_state.aw[x])
+#define LCREG(x) (saved_state.lc[x])
+#define LTREG(x) (saved_state.lt[x])
+#define LBREG(x) (saved_state.lb[x])
+#define RETSREG (saved_state.rets)
+
+static bu32 *
+get_allreg (int grp, int reg)
+{
+ int fullreg = (grp << 3) | reg;
+ /* REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7,
+ REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_SP, REG_FP,
+ REG_I0, REG_I1, REG_I2, REG_I3, REG_M0, REG_M1, REG_M2, REG_M3,
+ REG_B0, REG_B1, REG_B2, REG_B3, REG_L0, REG_L1, REG_L2, REG_L3,
+ REG_A0x, REG_A0w, REG_A1x, REG_A1w, , , REG_ASTAT, REG_RETS,
+ , , , , , , , ,
+ REG_LC0, REG_LT0, REG_LB0, REG_LC1, REG_LT1, REG_LB1, REG_CYCLES,
+ REG_CYCLES2,
+ REG_USP, REG_SEQSTAT, REG_SYSCFG, REG_RETI, REG_RETX, REG_RETN, REG_RETE,
+ REG_LASTREG */
+ switch (fullreg >> 2)
+ {
+ case 0: case 1: return &DREG (reg);
+ case 2: case 3: return &PREG (reg);
+ case 4: return &IREG (reg & 3);
+ case 5: return &MREG (reg & 3);
+ case 6: return &BREG (reg & 3);
+ case 7: return &LREG (reg & 3);
+ default:
+ switch (fullreg)
+ {
+ case 32: return &AXREG (0);
+ case 33: return &AWREG (0);
+ case 34: return &AXREG (1);
+ case 35: return &AWREG (1);
+ case 39: return &RETSREG;
+ case 48: return &LCREG (0);
+ case 49: return <REG (0);
+ case 50: return &LBREG (0);
+ case 51: return &LCREG (1);
+ case 52: return <REG (1);
+ case 53: return &LBREG (1);
+ }
+ }
+ abort ();
+}
+
+static int
+decode_ProgCtrl_0 (TIword iw0, disassemble_info *outf)
+{
+ /* ProgCtrl
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.prgfunc.......|.poprnd........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int poprnd = ((iw0 >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask);
+ int prgfunc = ((iw0 >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask);
+
+ if (prgfunc == 0 && poprnd == 0)
+ OUTS (outf, "NOP");
+ else if (parallel)
+ return 0;
+ else if (prgfunc == 1 && poprnd == 0)
+ OUTS (outf, "RTS");
+ else if (prgfunc == 1 && poprnd == 1)
+ OUTS (outf, "RTI");
+ else if (prgfunc == 1 && poprnd == 2)
+ OUTS (outf, "RTX");
+ else if (prgfunc == 1 && poprnd == 3)
+ OUTS (outf, "RTN");
+ else if (prgfunc == 1 && poprnd == 4)
+ OUTS (outf, "RTE");
+ else if (prgfunc == 2 && poprnd == 0)
+ OUTS (outf, "IDLE");
+ else if (prgfunc == 2 && poprnd == 3)
+ OUTS (outf, "CSYNC");
+ else if (prgfunc == 2 && poprnd == 4)
+ OUTS (outf, "SSYNC");
+ else if (prgfunc == 2 && poprnd == 5)
+ OUTS (outf, "EMUEXCPT");
+ else if (prgfunc == 3 && IS_DREG (0, poprnd))
+ {
+ OUTS (outf, "CLI ");
+ OUTS (outf, dregs (poprnd));
+ }
+ else if (prgfunc == 4 && IS_DREG (0, poprnd))
+ {
+ OUTS (outf, "STI ");
+ OUTS (outf, dregs (poprnd));
+ }
+ else if (prgfunc == 5 && IS_PREG (1, poprnd))
+ {
+ OUTS (outf, "JUMP (");
+ OUTS (outf, pregs (poprnd));
+ OUTS (outf, ")");
+ }
+ else if (prgfunc == 6 && IS_PREG (1, poprnd))
+ {
+ OUTS (outf, "CALL (");
+ OUTS (outf, pregs (poprnd));
+ OUTS (outf, ")");
+ }
+ else if (prgfunc == 7 && IS_PREG (1, poprnd))
+ {
+ OUTS (outf, "CALL (PC + ");
+ OUTS (outf, pregs (poprnd));
+ OUTS (outf, ")");
+ }
+ else if (prgfunc == 8 && IS_PREG (1, poprnd))
+ {
+ OUTS (outf, "JUMP (PC + ");
+ OUTS (outf, pregs (poprnd));
+ OUTS (outf, ")");
+ }
+ else if (prgfunc == 9)
+ {
+ OUTS (outf, "RAISE ");
+ OUTS (outf, uimm4 (poprnd));
+ }
+ else if (prgfunc == 10)
+ {
+ OUTS (outf, "EXCPT ");
+ OUTS (outf, uimm4 (poprnd));
+ }
+ else if (prgfunc == 11 && IS_PREG (1, poprnd) && poprnd <= 5)
+ {
+ OUTS (outf, "TESTSET (");
+ OUTS (outf, pregs (poprnd));
+ OUTS (outf, ")");
+ }
+ else
+ return 0;
+ return 2;
+}
+
+static int
+decode_CaCTRL_0 (TIword iw0, disassemble_info *outf)
+{
+ /* CaCTRL
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int a = ((iw0 >> CaCTRL_a_bits) & CaCTRL_a_mask);
+ int op = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask);
+ int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask);
+
+ if (parallel)
+ return 0;
+
+ if (a == 0 && op == 0)
+ {
+ OUTS (outf, "PREFETCH[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "]");
+ }
+ else if (a == 0 && op == 1)
+ {
+ OUTS (outf, "FLUSHINV[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "]");
+ }
+ else if (a == 0 && op == 2)
+ {
+ OUTS (outf, "FLUSH[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "]");
+ }
+ else if (a == 0 && op == 3)
+ {
+ OUTS (outf, "IFLUSH[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "]");
+ }
+ else if (a == 1 && op == 0)
+ {
+ OUTS (outf, "PREFETCH[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "++]");
+ }
+ else if (a == 1 && op == 1)
+ {
+ OUTS (outf, "FLUSHINV[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "++]");
+ }
+ else if (a == 1 && op == 2)
+ {
+ OUTS (outf, "FLUSH[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "++]");
+ }
+ else if (a == 1 && op == 3)
+ {
+ OUTS (outf, "IFLUSH[");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, "++]");
+ }
+ else
+ return 0;
+ return 2;
+}
+
+static int
+decode_PushPopReg_0 (TIword iw0, disassemble_info *outf)
+{
+ /* PushPopReg
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.W.|.grp.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int W = ((iw0 >> PushPopReg_W_bits) & PushPopReg_W_mask);
+ int grp = ((iw0 >> PushPopReg_grp_bits) & PushPopReg_grp_mask);
+ int reg = ((iw0 >> PushPopReg_reg_bits) & PushPopReg_reg_mask);
+
+ if (parallel)
+ return 0;
+
+ if (W == 0 && mostreg (reg, grp))
+ {
+ OUTS (outf, allregs (reg, grp));
+ OUTS (outf, " = [SP++]");
+ }
+ else if (W == 1 && allreg (reg, grp) && !(grp == 1 && reg == 6))
+ {
+ OUTS (outf, "[--SP] = ");
+ OUTS (outf, allregs (reg, grp));
+ }
+ else
+ return 0;
+ return 2;
+}
+
+static int
+decode_PushPopMultiple_0 (TIword iw0, disassemble_info *outf)
+{
+ /* PushPopMultiple
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.d.|.p.|.W.|.dr........|.pr........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int p = ((iw0 >> PushPopMultiple_p_bits) & PushPopMultiple_p_mask);
+ int d = ((iw0 >> PushPopMultiple_d_bits) & PushPopMultiple_d_mask);
+ int W = ((iw0 >> PushPopMultiple_W_bits) & PushPopMultiple_W_mask);
+ int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask);
+ int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask);
+
+ if (parallel)
+ return 0;
+
+ if (pr > 5)
+ return 0;
+
+ if (W == 1 && d == 1 && p == 1)
+ {
+ OUTS (outf, "[--SP] = (R7:");
+ OUTS (outf, imm5d (dr));
+ OUTS (outf, ", P5:");
+ OUTS (outf, imm5d (pr));
+ OUTS (outf, ")");
+ }
+ else if (W == 1 && d == 1 && p == 0 && pr == 0)
+ {
+ OUTS (outf, "[--SP] = (R7:");
+ OUTS (outf, imm5d (dr));
+ OUTS (outf, ")");
+ }
+ else if (W == 1 && d == 0 && p == 1 && dr == 0)
+ {
+ OUTS (outf, "[--SP] = (P5:");
+ OUTS (outf, imm5d (pr));
+ OUTS (outf, ")");
+ }
+ else if (W == 0 && d == 1 && p == 1)
+ {
+ OUTS (outf, "(R7:");
+ OUTS (outf, imm5d (dr));
+ OUTS (outf, ", P5:");
+ OUTS (outf, imm5d (pr));
+ OUTS (outf, ") = [SP++]");
+ }
+ else if (W == 0 && d == 1 && p == 0 && pr == 0)
+ {
+ OUTS (outf, "(R7:");
+ OUTS (outf, imm5d (dr));
+ OUTS (outf, ") = [SP++]");
+ }
+ else if (W == 0 && d == 0 && p == 1 && dr == 0)
+ {
+ OUTS (outf, "(P5:");
+ OUTS (outf, imm5d (pr));
+ OUTS (outf, ") = [SP++]");
+ }
+ else
+ return 0;
+ return 2;
+}
+
+static int
+decode_ccMV_0 (TIword iw0, disassemble_info *outf)
+{
+ /* ccMV
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.T.|.d.|.s.|.dst.......|.src.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int s = ((iw0 >> CCmv_s_bits) & CCmv_s_mask);
+ int d = ((iw0 >> CCmv_d_bits) & CCmv_d_mask);
+ int T = ((iw0 >> CCmv_T_bits) & CCmv_T_mask);
+ int src = ((iw0 >> CCmv_src_bits) & CCmv_src_mask);
+ int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask);
+
+ if (parallel)
+ return 0;
+
+ if (T == 1)
+ {
+ OUTS (outf, "IF CC ");
+ OUTS (outf, gregs (dst, d));
+ OUTS (outf, " = ");
+ OUTS (outf, gregs (src, s));
+ }
+ else if (T == 0)
+ {
+ OUTS (outf, "IF !CC ");
+ OUTS (outf, gregs (dst, d));
+ OUTS (outf, " = ");
+ OUTS (outf, gregs (src, s));
+ }
+ else
+ return 0;
+ return 2;
+}
+
+static int
+decode_CCflag_0 (TIword iw0, disassemble_info *outf)
+{
+ /* CCflag
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 1 |.I.|.opc.......|.G.|.y.........|.x.........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int x = ((iw0 >> CCflag_x_bits) & CCflag_x_mask);
+ int y = ((iw0 >> CCflag_y_bits) & CCflag_y_mask);
+ int I = ((iw0 >> CCflag_I_bits) & CCflag_I_mask);
+ int G = ((iw0 >> CCflag_G_bits) & CCflag_G_mask);
+ int opc = ((iw0 >> CCflag_opc_bits) & CCflag_opc_mask);
+
+ if (parallel)
+ return 0;
+
+ if (opc == 0 && I == 0 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " == ");
+ OUTS (outf, dregs (y));
+ }
+ else if (opc == 1 && I == 0 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, dregs (y));
+ }
+ else if (opc == 2 && I == 0 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, dregs (y));
+ }
+ else if (opc == 3 && I == 0 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, dregs (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 4 && I == 0 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, dregs (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 0 && I == 1 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " == ");
+ OUTS (outf, imm3 (y));
+ }
+ else if (opc == 1 && I == 1 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, imm3 (y));
+ }
+ else if (opc == 2 && I == 1 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, imm3 (y));
+ }
+ else if (opc == 3 && I == 1 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, uimm3 (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 4 && I == 1 && G == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, uimm3 (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 0 && I == 0 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " == ");
+ OUTS (outf, pregs (y));
+ }
+ else if (opc == 1 && I == 0 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, pregs (y));
+ }
+ else if (opc == 2 && I == 0 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, pregs (y));
+ }
+ else if (opc == 3 && I == 0 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, pregs (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 4 && I == 0 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, pregs (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 0 && I == 1 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " == ");
+ OUTS (outf, imm3 (y));
+ }
+ else if (opc == 1 && I == 1 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, imm3 (y));
+ }
+ else if (opc == 2 && I == 1 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, imm3 (y));
+ }
+ else if (opc == 3 && I == 1 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " < ");
+ OUTS (outf, uimm3 (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 4 && I == 1 && G == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, pregs (x));
+ OUTS (outf, " <= ");
+ OUTS (outf, uimm3 (y));
+ OUTS (outf, " (IU)");
+ }
+ else if (opc == 5 && I == 0 && G == 0 && x == 0 && y == 0)
+ OUTS (outf, "CC = A0 == A1");
+
+ else if (opc == 6 && I == 0 && G == 0 && x == 0 && y == 0)
+ OUTS (outf, "CC = A0 < A1");
+
+ else if (opc == 7 && I == 0 && G == 0 && x == 0 && y == 0)
+ OUTS (outf, "CC = A0 <= A1");
+
+ else
+ return 0;
+ return 2;
+}
+
+static int
+decode_CC2dreg_0 (TIword iw0, disassemble_info *outf)
+{
+ /* CC2dreg
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask);
+ int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask);
+
+ if (parallel)
+ return 0;
+
+ if (op == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = CC");
+ }
+ else if (op == 1)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (op == 3 && reg == 0)
+ OUTS (outf, "CC = !CC");
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_CC2stat_0 (TIword iw0, disassemble_info *outf)
+{
+ /* CC2stat
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int D = ((iw0 >> CC2stat_D_bits) & CC2stat_D_mask);
+ int op = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask);
+ int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask);
+
+ const char *bitname = statbits (cbit);
+
+ if (parallel)
+ return 0;
+
+ if (decode_statbits[cbit] == REG_LASTREG)
+ {
+ /* All ASTAT bits except CC may be operated on in hardware, but may
+ not have a dedicated insn, so still decode "valid" insns. */
+ static char bitnames[64];
+ if (cbit != 5)
+ sprintf (bitnames, "ASTAT[%i /* unused bit */]", cbit);
+ else
+ return 0;
+
+ bitname = bitnames;
+ }
+
+ if (op == 0 && D == 0)
+ {
+ OUTS (outf, "CC = ");
+ OUTS (outf, bitname);
+ }
+ else if (op == 1 && D == 0)
+ {
+ OUTS (outf, "CC |= ");
+ OUTS (outf, bitname);
+ }
+ else if (op == 2 && D == 0)
+ {
+ OUTS (outf, "CC &= ");
+ OUTS (outf, bitname);
+ }
+ else if (op == 3 && D == 0)
+ {
+ OUTS (outf, "CC ^= ");
+ OUTS (outf, bitname);
+ }
+ else if (op == 0 && D == 1)
+ {
+ OUTS (outf, bitname);
+ OUTS (outf, " = CC");
+ }
+ else if (op == 1 && D == 1)
+ {
+ OUTS (outf, bitname);
+ OUTS (outf, " |= CC");
+ }
+ else if (op == 2 && D == 1)
+ {
+ OUTS (outf, bitname);
+ OUTS (outf, " &= CC");
+ }
+ else if (op == 3 && D == 1)
+ {
+ OUTS (outf, bitname);
+ OUTS (outf, " ^= CC");
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_BRCC_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
+{
+ /* BRCC
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 1 |.T.|.B.|.offset................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int B = ((iw0 >> BRCC_B_bits) & BRCC_B_mask);
+ int T = ((iw0 >> BRCC_T_bits) & BRCC_T_mask);
+ int offset = ((iw0 >> BRCC_offset_bits) & BRCC_offset_mask);
+
+ if (parallel)
+ return 0;
+
+ if (T == 1 && B == 1)
+ {
+ OUTS (outf, "IF CC JUMP ");
+ OUTS (outf, pcrel10 (offset));
+ OUTS (outf, " (BP)");
+ }
+ else if (T == 0 && B == 1)
+ {
+ OUTS (outf, "IF !CC JUMP ");
+ OUTS (outf, pcrel10 (offset));
+ OUTS (outf, " (BP)");
+ }
+ else if (T == 1)
+ {
+ OUTS (outf, "IF CC JUMP ");
+ OUTS (outf, pcrel10 (offset));
+ }
+ else if (T == 0)
+ {
+ OUTS (outf, "IF !CC JUMP ");
+ OUTS (outf, pcrel10 (offset));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_UJUMP_0 (TIword iw0, bfd_vma pc, disassemble_info *outf)
+{
+ /* UJUMP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 1 | 0 |.offset........................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask);
+
+ if (parallel)
+ return 0;
+
+ OUTS (outf, "JUMP.S ");
+ OUTS (outf, pcrel12 (offset));
+ return 2;
+}
+
+static int
+decode_REGMV_0 (TIword iw0, disassemble_info *outf)
+{
+ /* REGMV
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 1 | 1 |.gd........|.gs........|.dst.......|.src.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int gs = ((iw0 >> RegMv_gs_bits) & RegMv_gs_mask);
+ int gd = ((iw0 >> RegMv_gd_bits) & RegMv_gd_mask);
+ int src = ((iw0 >> RegMv_src_bits) & RegMv_src_mask);
+ int dst = ((iw0 >> RegMv_dst_bits) & RegMv_dst_mask);
+
+ /* Reserved slots cannot be a src/dst. */
+ if (IS_RESERVEDREG (gs, src) || IS_RESERVEDREG (gd, dst))
+ goto invalid_move;
+
+ /* Standard register moves */
+ if ((gs < 2) || /* Dregs/Pregs as source */
+ (gd < 2) || /* Dregs/Pregs as dest */
+ (gs == 4 && src < 4) || /* Accumulators as source */
+ (gd == 4 && dst < 4 && (gs < 4)) || /* Accumulators as dest */
+ (gs == 7 && src == 7 && !(gd == 4 && dst < 4)) || /* EMUDAT as src */
+ (gd == 7 && dst == 7)) /* EMUDAT as dest */
+ goto valid_move;
+
+ /* dareg = dareg (IMBL) */
+ if (gs < 4 && gd < 4)
+ goto valid_move;
+
+ /* USP can be src to sysregs, but not dagregs. */
+ if ((gs == 7 && src == 0) && (gd >= 4))
+ goto valid_move;
+
+ /* USP can move between genregs (only check Accumulators). */
+ if (((gs == 7 && src == 0) && (gd == 4 && dst < 4)) ||
+ ((gd == 7 && dst == 0) && (gs == 4 && src < 4)))
+ goto valid_move;
+
+ /* Still here ? Invalid reg pair. */
+ invalid_move:
+ return 0;
+
+ valid_move:
+ OUTS (outf, allregs (dst, gd));
+ OUTS (outf, " = ");
+ OUTS (outf, allregs (src, gs));
+ return 2;
+}
+
+static int
+decode_ALU2op_0 (TIword iw0, disassemble_info *outf)
+{
+ /* ALU2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> ALU2op_src_bits) & ALU2op_src_mask);
+ int opc = ((iw0 >> ALU2op_opc_bits) & ALU2op_opc_mask);
+ int dst = ((iw0 >> ALU2op_dst_bits) & ALU2op_dst_mask);
+
+ if (opc == 0)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " >>>= ");
+ OUTS (outf, dregs (src));
+ }
+ else if (opc == 1)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " >>= ");
+ OUTS (outf, dregs (src));
+ }
+ else if (opc == 2)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " <<= ");
+ OUTS (outf, dregs (src));
+ }
+ else if (opc == 3)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " *= ");
+ OUTS (outf, dregs (src));
+ }
+ else if (opc == 4)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src));
+ OUTS (outf, ") << 0x1");
+ }
+ else if (opc == 5)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src));
+ OUTS (outf, ") << 0x2");
+ }
+ else if (opc == 8)
+ {
+ OUTS (outf, "DIVQ (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src));
+ OUTS (outf, ")");
+ }
+ else if (opc == 9)
+ {
+ OUTS (outf, "DIVS (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src));
+ OUTS (outf, ")");
+ }
+ else if (opc == 10)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src));
+ OUTS (outf, " (X)");
+ }
+ else if (opc == 11)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src));
+ OUTS (outf, " (Z)");
+ }
+ else if (opc == 12)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_byte (src));
+ OUTS (outf, " (X)");
+ }
+ else if (opc == 13)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_byte (src));
+ OUTS (outf, " (Z)");
+ }
+ else if (opc == 14)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = -");
+ OUTS (outf, dregs (src));
+ }
+ else if (opc == 15)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " =~ ");
+ OUTS (outf, dregs (src));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_PTR2op_0 (TIword iw0, disassemble_info *outf)
+{
+ /* PTR2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 0 | 1 | 0 |.opc.......|.src.......|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> PTR2op_src_bits) & PTR2op_dst_mask);
+ int opc = ((iw0 >> PTR2op_opc_bits) & PTR2op_opc_mask);
+ int dst = ((iw0 >> PTR2op_dst_bits) & PTR2op_dst_mask);
+
+ if (opc == 0)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " -= ");
+ OUTS (outf, pregs (src));
+ }
+ else if (opc == 1)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (src));
+ OUTS (outf, " << 0x2");
+ }
+ else if (opc == 3)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (src));
+ OUTS (outf, " >> 0x2");
+ }
+ else if (opc == 4)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (src));
+ OUTS (outf, " >> 0x1");
+ }
+ else if (opc == 5)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " += ");
+ OUTS (outf, pregs (src));
+ OUTS (outf, " (BREV)");
+ }
+ else if (opc == 6)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = (");
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " + ");
+ OUTS (outf, pregs (src));
+ OUTS (outf, ") << 0x1");
+ }
+ else if (opc == 7)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = (");
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " + ");
+ OUTS (outf, pregs (src));
+ OUTS (outf, ") << 0x2");
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_LOGI2op_0 (TIword iw0, disassemble_info *outf)
+{
+ /* LOGI2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 1 |.opc.......|.src...............|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> LOGI2op_src_bits) & LOGI2op_src_mask);
+ int opc = ((iw0 >> LOGI2op_opc_bits) & LOGI2op_opc_mask);
+ int dst = ((iw0 >> LOGI2op_dst_bits) & LOGI2op_dst_mask);
+
+ if (parallel)
+ return 0;
+
+ if (opc == 0)
+ {
+ OUTS (outf, "CC = !BITTST (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm5 (src));
+ OUTS (outf, ");\t\t/* bit");
+ OUTS (outf, imm7d (src));
+ OUTS (outf, " */");
+ comment = 1;
+ }
+ else if (opc == 1)
+ {
+ OUTS (outf, "CC = BITTST (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm5 (src));
+ OUTS (outf, ");\t\t/* bit");
+ OUTS (outf, imm7d (src));
+ OUTS (outf, " */");
+ comment = 1;
+ }
+ else if (opc == 2)
+ {
+ OUTS (outf, "BITSET (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm5 (src));
+ OUTS (outf, ");\t\t/* bit");
+ OUTS (outf, imm7d (src));
+ OUTS (outf, " */");
+ comment = 1;
+ }
+ else if (opc == 3)
+ {
+ OUTS (outf, "BITTGL (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm5 (src));
+ OUTS (outf, ");\t\t/* bit");
+ OUTS (outf, imm7d (src));
+ OUTS (outf, " */");
+ comment = 1;
+ }
+ else if (opc == 4)
+ {
+ OUTS (outf, "BITCLR (");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm5 (src));
+ OUTS (outf, ");\t\t/* bit");
+ OUTS (outf, imm7d (src));
+ OUTS (outf, " */");
+ comment = 1;
+ }
+ else if (opc == 5)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " >>>= ");
+ OUTS (outf, uimm5 (src));
+ }
+ else if (opc == 6)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " >>= ");
+ OUTS (outf, uimm5 (src));
+ }
+ else if (opc == 7)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " <<= ");
+ OUTS (outf, uimm5 (src));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_COMP3op_0 (TIword iw0, disassemble_info *outf)
+{
+ /* COMP3op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int opc = ((iw0 >> COMP3op_opc_bits) & COMP3op_opc_mask);
+ int dst = ((iw0 >> COMP3op_dst_bits) & COMP3op_dst_mask);
+ int src0 = ((iw0 >> COMP3op_src0_bits) & COMP3op_src0_mask);
+ int src1 = ((iw0 >> COMP3op_src1_bits) & COMP3op_src1_mask);
+
+ if (opc == 5 && src1 == src0)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (src0));
+ OUTS (outf, " << 0x1");
+ }
+ else if (opc == 1)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs (src1));
+ }
+ else if (opc == 2)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " & ");
+ OUTS (outf, dregs (src1));
+ }
+ else if (opc == 3)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " | ");
+ OUTS (outf, dregs (src1));
+ }
+ else if (opc == 4)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " ^ ");
+ OUTS (outf, dregs (src1));
+ }
+ else if (opc == 5)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, pregs (src1));
+ }
+ else if (opc == 6)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (src0));
+ OUTS (outf, " + (");
+ OUTS (outf, pregs (src1));
+ OUTS (outf, " << 0x1)");
+ }
+ else if (opc == 7)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (src0));
+ OUTS (outf, " + (");
+ OUTS (outf, pregs (src1));
+ OUTS (outf, " << 0x2)");
+ }
+ else if (opc == 0)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src1));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_COMPI2opD_0 (TIword iw0, disassemble_info *outf)
+{
+ /* COMPI2opD
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 1 | 0 | 0 |.op|..src......................|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> COMPI2opD_op_bits) & COMPI2opD_op_mask);
+ int dst = ((iw0 >> COMPI2opD_dst_bits) & COMPI2opD_dst_mask);
+ int src = ((iw0 >> COMPI2opD_src_bits) & COMPI2opD_src_mask);
+
+ bu32 *pval = get_allreg (0, dst);
+
+ if (parallel)
+ return 0;
+
+ /* Since we don't have 32-bit immediate loads, we allow the disassembler
+ to combine them, so it prints out the right values.
+ Here we keep track of the registers. */
+ if (op == 0)
+ {
+ *pval = imm7_val (src);
+ if (src & 0x40)
+ *pval |= 0xFFFFFF80;
+ else
+ *pval &= 0x7F;
+ }
+
+ if (op == 0)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, imm7 (src));
+ OUTS (outf, " (X);\t\t/*\t\t");
+ OUTS (outf, dregs (dst));
+ OUTS (outf, "=");
+ OUTS (outf, uimm32 (*pval));
+ OUTS (outf, "(");
+ OUTS (outf, imm32 (*pval));
+ OUTS (outf, ") */");
+ comment = 1;
+ }
+ else if (op == 1)
+ {
+ OUTS (outf, dregs (dst));
+ OUTS (outf, " += ");
+ OUTS (outf, imm7 (src));
+ OUTS (outf, ";\t\t/* (");
+ OUTS (outf, imm7d (src));
+ OUTS (outf, ") */");
+ comment = 1;
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_COMPI2opP_0 (TIword iw0, disassemble_info *outf)
+{
+ /* COMPI2opP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> COMPI2opP_op_bits) & COMPI2opP_op_mask);
+ int src = ((iw0 >> COMPI2opP_src_bits) & COMPI2opP_src_mask);
+ int dst = ((iw0 >> COMPI2opP_dst_bits) & COMPI2opP_dst_mask);
+
+ bu32 *pval = get_allreg (1, dst);
+
+ if (parallel)
+ return 0;
+
+ if (op == 0)
+ {
+ *pval = imm7_val (src);
+ if (src & 0x40)
+ *pval |= 0xFFFFFF80;
+ else
+ *pval &= 0x7F;
+ }
+
+ if (op == 0)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " = ");
+ OUTS (outf, imm7 (src));
+ OUTS (outf, " (X);\t\t/*\t\t");
+ OUTS (outf, pregs (dst));
+ OUTS (outf, "=");
+ OUTS (outf, uimm32 (*pval));
+ OUTS (outf, "(");
+ OUTS (outf, imm32 (*pval));
+ OUTS (outf, ") */");
+ comment = 1;
+ }
+ else if (op == 1)
+ {
+ OUTS (outf, pregs (dst));
+ OUTS (outf, " += ");
+ OUTS (outf, imm7 (src));
+ OUTS (outf, ";\t\t/* (");
+ OUTS (outf, imm7d (src));
+ OUTS (outf, ") */");
+ comment = 1;
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_LDSTpmod_0 (TIword iw0, disassemble_info *outf)
+{
+ /* LDSTpmod
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
+ int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
+ int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
+ int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
+ int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
+
+ if (aop == 1 && W == 0 && idx == ptr)
+ {
+ OUTS (outf, dregs_lo (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "]");
+ }
+ else if (aop == 2 && W == 0 && idx == ptr)
+ {
+ OUTS (outf, dregs_hi (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "]");
+ }
+ else if (aop == 1 && W == 1 && idx == ptr)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs_lo (reg));
+ }
+ else if (aop == 2 && W == 1 && idx == ptr)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs_hi (reg));
+ }
+ else if (aop == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "]");
+ }
+ else if (aop == 1 && W == 0)
+ {
+ OUTS (outf, dregs_lo (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "]");
+ }
+ else if (aop == 2 && W == 0)
+ {
+ OUTS (outf, dregs_hi (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "]");
+ }
+ else if (aop == 3 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "] (Z)");
+ }
+ else if (aop == 3 && W == 1)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "] (X)");
+ }
+ else if (aop == 0 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 1 && W == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs_lo (reg));
+ }
+ else if (aop == 2 && W == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " ++ ");
+ OUTS (outf, pregs (idx));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs_hi (reg));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_dagMODim_0 (TIword iw0, disassemble_info *outf)
+{
+ /* dagMODim
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
+ int m = ((iw0 >> DagMODim_m_bits) & DagMODim_m_mask);
+ int br = ((iw0 >> DagMODim_br_bits) & DagMODim_br_mask);
+ int op = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
+
+ if (op == 0 && br == 1)
+ {
+ OUTS (outf, iregs (i));
+ OUTS (outf, " += ");
+ OUTS (outf, mregs (m));
+ OUTS (outf, " (BREV)");
+ }
+ else if (op == 0)
+ {
+ OUTS (outf, iregs (i));
+ OUTS (outf, " += ");
+ OUTS (outf, mregs (m));
+ }
+ else if (op == 1 && br == 0)
+ {
+ OUTS (outf, iregs (i));
+ OUTS (outf, " -= ");
+ OUTS (outf, mregs (m));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_dagMODik_0 (TIword iw0, disassemble_info *outf)
+{
+ /* dagMODik
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
+ int op = ((iw0 >> DagMODik_op_bits) & DagMODik_op_mask);
+
+ if (op == 0)
+ {
+ OUTS (outf, iregs (i));
+ OUTS (outf, " += 0x2");
+ }
+ else if (op == 1)
+ {
+ OUTS (outf, iregs (i));
+ OUTS (outf, " -= 0x2");
+ }
+ else if (op == 2)
+ {
+ OUTS (outf, iregs (i));
+ OUTS (outf, " += 0x4");
+ }
+ else if (op == 3)
+ {
+ OUTS (outf, iregs (i));
+ OUTS (outf, " -= 0x4");
+ }
+ else
+ return 0;
+
+ if (! parallel )
+ {
+ OUTS (outf, ";\t\t/* ( ");
+ if (op == 0 || op == 1)
+ OUTS (outf, "2");
+ else if (op == 2 || op == 3)
+ OUTS (outf, "4");
+ OUTS (outf, ") */");
+ comment = 1;
+ }
+
+ return 2;
+}
+
+static int
+decode_dspLDST_0 (TIword iw0, disassemble_info *outf)
+{
+ /* dspLDST
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
+ int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
+ int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
+ int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
+ int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
+
+ if (aop == 0 && W == 0 && m == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "++]");
+ }
+ else if (aop == 0 && W == 0 && m == 1)
+ {
+ OUTS (outf, dregs_lo (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "++]");
+ }
+ else if (aop == 0 && W == 0 && m == 2)
+ {
+ OUTS (outf, dregs_hi (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "++]");
+ }
+ else if (aop == 1 && W == 0 && m == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "--]");
+ }
+ else if (aop == 1 && W == 0 && m == 1)
+ {
+ OUTS (outf, dregs_lo (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "--]");
+ }
+ else if (aop == 1 && W == 0 && m == 2)
+ {
+ OUTS (outf, dregs_hi (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "--]");
+ }
+ else if (aop == 2 && W == 0 && m == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "]");
+ }
+ else if (aop == 2 && W == 0 && m == 1)
+ {
+ OUTS (outf, dregs_lo (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "]");
+ }
+ else if (aop == 2 && W == 0 && m == 2)
+ {
+ OUTS (outf, dregs_hi (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "]");
+ }
+ else if (aop == 0 && W == 1 && m == 0)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "++] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 0 && W == 1 && m == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "++] = ");
+ OUTS (outf, dregs_lo (reg));
+ }
+ else if (aop == 0 && W == 1 && m == 2)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "++] = ");
+ OUTS (outf, dregs_hi (reg));
+ }
+ else if (aop == 1 && W == 1 && m == 0)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "--] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 1 && W == 1 && m == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "--] = ");
+ OUTS (outf, dregs_lo (reg));
+ }
+ else if (aop == 1 && W == 1 && m == 2)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "--] = ");
+ OUTS (outf, dregs_hi (reg));
+ }
+ else if (aop == 2 && W == 1 && m == 0)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 2 && W == 1 && m == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs_lo (reg));
+ }
+ else if (aop == 2 && W == 1 && m == 2)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs_hi (reg));
+ }
+ else if (aop == 3 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, iregs (i));
+ OUTS (outf, " ++ ");
+ OUTS (outf, mregs (m));
+ OUTS (outf, "]");
+ }
+ else if (aop == 3 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, iregs (i));
+ OUTS (outf, " ++ ");
+ OUTS (outf, mregs (m));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_LDST_0 (TIword iw0, disassemble_info *outf)
+{
+ /* LDST
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
+ int W = ((iw0 >> LDST_W_bits) & LDST_W_mask);
+ int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
+ int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
+ int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
+ int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask);
+
+ if (aop == 0 && sz == 0 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++]");
+ }
+ else if (aop == 0 && sz == 0 && Z == 1 && W == 0 && reg != ptr)
+ {
+ OUTS (outf, pregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++]");
+ }
+ else if (aop == 0 && sz == 1 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] (Z)");
+ }
+ else if (aop == 0 && sz == 1 && Z == 1 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] (X)");
+ }
+ else if (aop == 0 && sz == 2 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] (Z)");
+ }
+ else if (aop == 0 && sz == 2 && Z == 1 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] (X)");
+ }
+ else if (aop == 1 && sz == 0 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--]");
+ }
+ else if (aop == 1 && sz == 0 && Z == 1 && W == 0 && reg != ptr)
+ {
+ OUTS (outf, pregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--]");
+ }
+ else if (aop == 1 && sz == 1 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] (Z)");
+ }
+ else if (aop == 1 && sz == 1 && Z == 1 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] (X)");
+ }
+ else if (aop == 1 && sz == 2 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] (Z)");
+ }
+ else if (aop == 1 && sz == 2 && Z == 1 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] (X)");
+ }
+ else if (aop == 2 && sz == 0 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "]");
+ }
+ else if (aop == 2 && sz == 0 && Z == 1 && W == 0)
+ {
+ OUTS (outf, pregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "]");
+ }
+ else if (aop == 2 && sz == 1 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] (Z)");
+ }
+ else if (aop == 2 && sz == 1 && Z == 1 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] (X)");
+ }
+ else if (aop == 2 && sz == 2 && Z == 0 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] (Z)");
+ }
+ else if (aop == 2 && sz == 2 && Z == 1 && W == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] (X)");
+ }
+ else if (aop == 0 && sz == 0 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 0 && sz == 0 && Z == 1 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] = ");
+ OUTS (outf, pregs (reg));
+ }
+ else if (aop == 0 && sz == 1 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 0 && sz == 2 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "++] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 1 && sz == 0 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 1 && sz == 0 && Z == 1 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] = ");
+ OUTS (outf, pregs (reg));
+ }
+ else if (aop == 1 && sz == 1 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 1 && sz == 2 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "--] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 2 && sz == 0 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 2 && sz == 0 && Z == 1 && W == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] = ");
+ OUTS (outf, pregs (reg));
+ }
+ else if (aop == 2 && sz == 1 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (aop == 2 && sz == 2 && Z == 0 && W == 1)
+ {
+ OUTS (outf, "B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_LDSTiiFP_0 (TIword iw0, disassemble_info *outf)
+{
+ /* LDSTiiFP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask);
+ int offset = ((iw0 >> LDSTiiFP_offset_bits) & LDSTiiFP_offset_mask);
+ int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
+
+ if (W == 0)
+ {
+ OUTS (outf, dpregs (reg));
+ OUTS (outf, " = [FP ");
+ OUTS (outf, negimm5s4 (offset));
+ OUTS (outf, "]");
+ }
+ else if (W == 1)
+ {
+ OUTS (outf, "[FP ");
+ OUTS (outf, negimm5s4 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, dpregs (reg));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_LDSTii_0 (TIword iw0, disassemble_info *outf)
+{
+ /* LDSTii
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
+ int ptr = ((iw0 >> LDSTii_ptr_bit) & LDSTii_ptr_mask);
+ int offset = ((iw0 >> LDSTii_offset_bit) & LDSTii_offset_mask);
+ int op = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
+ int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
+
+ if (W == 0 && op == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, uimm4s4 (offset));
+ OUTS (outf, "]");
+ }
+ else if (W == 0 && op == 1)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, uimm4s2 (offset));
+ OUTS (outf, "] (Z)");
+ }
+ else if (W == 0 && op == 2)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, uimm4s2 (offset));
+ OUTS (outf, "] (X)");
+ }
+ else if (W == 0 && op == 3)
+ {
+ OUTS (outf, pregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, uimm4s4 (offset));
+ OUTS (outf, "]");
+ }
+ else if (W == 1 && op == 0)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, uimm4s4 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (W == 1 && op == 1)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, uimm4s2 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (W == 1 && op == 3)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, uimm4s4 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, pregs (reg));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_LoopSetup_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
+{
+ /* LoopSetup
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |.rop...|.c.|.soffset.......|
+ |.reg...........| - | - |.eoffset...............................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int c = ((iw0 >> (LoopSetup_c_bits - 16)) & LoopSetup_c_mask);
+ int reg = ((iw1 >> LoopSetup_reg_bits) & LoopSetup_reg_mask);
+ int rop = ((iw0 >> (LoopSetup_rop_bits - 16)) & LoopSetup_rop_mask);
+ int soffset = ((iw0 >> (LoopSetup_soffset_bits - 16)) & LoopSetup_soffset_mask);
+ int eoffset = ((iw1 >> LoopSetup_eoffset_bits) & LoopSetup_eoffset_mask);
+
+ if (parallel)
+ return 0;
+
+ if (rop == 0)
+ {
+ OUTS (outf, "LSETUP");
+ OUTS (outf, "(");
+ OUTS (outf, pcrel4 (soffset));
+ OUTS (outf, ", ");
+ OUTS (outf, lppcrel10 (eoffset));
+ OUTS (outf, ") ");
+ OUTS (outf, counters (c));
+ }
+ else if (rop == 1)
+ {
+ OUTS (outf, "LSETUP");
+ OUTS (outf, "(");
+ OUTS (outf, pcrel4 (soffset));
+ OUTS (outf, ", ");
+ OUTS (outf, lppcrel10 (eoffset));
+ OUTS (outf, ") ");
+ OUTS (outf, counters (c));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (reg));
+ }
+ else if (rop == 3)
+ {
+ OUTS (outf, "LSETUP");
+ OUTS (outf, "(");
+ OUTS (outf, pcrel4 (soffset));
+ OUTS (outf, ", ");
+ OUTS (outf, lppcrel10 (eoffset));
+ OUTS (outf, ") ");
+ OUTS (outf, counters (c));
+ OUTS (outf, " = ");
+ OUTS (outf, pregs (reg));
+ OUTS (outf, " >> 0x1");
+ }
+ else
+ return 0;
+
+ return 4;
+}
+
+static int
+decode_LDIMMhalf_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* LDIMMhalf
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |.Z.|.H.|.S.|.grp...|.reg.......|
+ |.hword.........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int H = ((iw0 >> (LDIMMhalf_H_bits - 16)) & LDIMMhalf_H_mask);
+ int Z = ((iw0 >> (LDIMMhalf_Z_bits - 16)) & LDIMMhalf_Z_mask);
+ int S = ((iw0 >> (LDIMMhalf_S_bits - 16)) & LDIMMhalf_S_mask);
+ int reg = ((iw0 >> (LDIMMhalf_reg_bits - 16)) & LDIMMhalf_reg_mask);
+ int grp = ((iw0 >> (LDIMMhalf_grp_bits - 16)) & LDIMMhalf_grp_mask);
+ int hword = ((iw1 >> LDIMMhalf_hword_bits) & LDIMMhalf_hword_mask);
+
+ bu32 *pval = get_allreg (grp, reg);
+
+ if (parallel)
+ return 0;
+
+ /* Since we don't have 32-bit immediate loads, we allow the disassembler
+ to combine them, so it prints out the right values.
+ Here we keep track of the registers. */
+ if (H == 0 && S == 1 && Z == 0)
+ {
+ /* regs = imm16 (x) */
+ *pval = imm16_val (hword);
+ if (hword & 0x8000)
+ *pval |= 0xFFFF0000;
+ else
+ *pval &= 0xFFFF;
+ }
+ else if (H == 0 && S == 0 && Z == 1)
+ {
+ /* regs = luimm16 (Z) */
+ *pval = luimm16_val (hword);
+ *pval &= 0xFFFF;
+ }
+ else if (H == 0 && S == 0 && Z == 0)
+ {
+ /* regs_lo = luimm16 */
+ *pval &= 0xFFFF0000;
+ *pval |= luimm16_val (hword);
+ }
+ else if (H == 1 && S == 0 && Z == 0)
+ {
+ /* regs_hi = huimm16 */
+ *pval &= 0xFFFF;
+ *pval |= luimm16_val (hword) << 16;
+ }
+
+ /* Here we do the disassembly */
+ if (grp == 0 && H == 0 && S == 0 && Z == 0)
+ {
+ OUTS (outf, dregs_lo (reg));
+ OUTS (outf, " = ");
+ OUTS (outf, uimm16 (hword));
+ }
+ else if (grp == 0 && H == 1 && S == 0 && Z == 0)
+ {
+ OUTS (outf, dregs_hi (reg));
+ OUTS (outf, " = ");
+ OUTS (outf, uimm16 (hword));
+ }
+ else if (grp == 0 && H == 0 && S == 1 && Z == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = ");
+ OUTS (outf, imm16 (hword));
+ OUTS (outf, " (X)");
+ }
+ else if (H == 0 && S == 1 && Z == 0)
+ {
+ OUTS (outf, regs (reg, grp));
+ OUTS (outf, " = ");
+ OUTS (outf, imm16 (hword));
+ OUTS (outf, " (X)");
+ }
+ else if (H == 0 && S == 0 && Z == 1)
+ {
+ OUTS (outf, regs (reg, grp));
+ OUTS (outf, " = ");
+ OUTS (outf, uimm16 (hword));
+ OUTS (outf, " (Z)");
+ }
+ else if (H == 0 && S == 0 && Z == 0)
+ {
+ OUTS (outf, regs_lo (reg, grp));
+ OUTS (outf, " = ");
+ OUTS (outf, uimm16 (hword));
+ }
+ else if (H == 1 && S == 0 && Z == 0)
+ {
+ OUTS (outf, regs_hi (reg, grp));
+ OUTS (outf, " = ");
+ OUTS (outf, uimm16 (hword));
+ }
+ else
+ return 0;
+
+ /* And we print out the 32-bit value if it is a pointer. */
+ if (S == 0 && Z == 0)
+ {
+ OUTS (outf, ";\t\t/* (");
+ OUTS (outf, imm16d (hword));
+ OUTS (outf, ")\t");
+
+ /* If it is an MMR, don't print the symbol. */
+ if (*pval < 0xFFC00000 && grp == 1)
+ {
+ OUTS (outf, regs (reg, grp));
+ OUTS (outf, "=");
+ OUTS (outf, huimm32e (*pval));
+ }
+ else
+ {
+ OUTS (outf, regs (reg, grp));
+ OUTS (outf, "=");
+ OUTS (outf, huimm32e (*pval));
+ OUTS (outf, "(");
+ OUTS (outf, imm32 (*pval));
+ OUTS (outf, ")");
+ }
+
+ OUTS (outf, " */");
+ comment = 1;
+ }
+ if (S == 1 || Z == 1)
+ {
+ OUTS (outf, ";\t\t/*\t\t");
+ OUTS (outf, regs (reg, grp));
+ OUTS (outf, "=");
+ OUTS (outf, huimm32e (*pval));
+ OUTS (outf, "(");
+ OUTS (outf, imm32 (*pval));
+ OUTS (outf, ") */");
+ comment = 1;
+ }
+ return 4;
+}
+
+static int
+decode_CALLa_0 (TIword iw0, TIword iw1, bfd_vma pc, disassemble_info *outf)
+{
+ /* CALLa
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 1 |.S.|.msw...........................|
+ |.lsw...........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int S = ((iw0 >> (CALLa_S_bits - 16)) & CALLa_S_mask);
+ int lsw = ((iw1 >> 0) & 0xffff);
+ int msw = ((iw0 >> 0) & 0xff);
+
+ if (parallel)
+ return 0;
+
+ if (S == 1)
+ OUTS (outf, "CALL ");
+ else if (S == 0)
+ OUTS (outf, "JUMP.L ");
+ else
+ return 0;
+
+ OUTS (outf, pcrel24 (((msw) << 16) | (lsw)));
+ return 4;
+}
+
+static int
+decode_LDSTidxI_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* LDSTidxI
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 1 |.W.|.Z.|.sz....|.ptr.......|.reg.......|
+ |.offset........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int Z = ((iw0 >> (LDSTidxI_Z_bits - 16)) & LDSTidxI_Z_mask);
+ int W = ((iw0 >> (LDSTidxI_W_bits - 16)) & LDSTidxI_W_mask);
+ int sz = ((iw0 >> (LDSTidxI_sz_bits - 16)) & LDSTidxI_sz_mask);
+ int reg = ((iw0 >> (LDSTidxI_reg_bits - 16)) & LDSTidxI_reg_mask);
+ int ptr = ((iw0 >> (LDSTidxI_ptr_bits - 16)) & LDSTidxI_ptr_mask);
+ int offset = ((iw1 >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask);
+
+ if (W == 0 && sz == 0 && Z == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16s4 (offset));
+ OUTS (outf, "]");
+ }
+ else if (W == 0 && sz == 0 && Z == 1)
+ {
+ OUTS (outf, pregs (reg));
+ OUTS (outf, " = [");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16s4 (offset));
+ OUTS (outf, "]");
+ }
+ else if (W == 0 && sz == 1 && Z == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16s2 (offset));
+ OUTS (outf, "] (Z)");
+ }
+ else if (W == 0 && sz == 1 && Z == 1)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16s2 (offset));
+ OUTS (outf, "] (X)");
+ }
+ else if (W == 0 && sz == 2 && Z == 0)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16 (offset));
+ OUTS (outf, "] (Z)");
+ }
+ else if (W == 0 && sz == 2 && Z == 1)
+ {
+ OUTS (outf, dregs (reg));
+ OUTS (outf, " = B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16 (offset));
+ OUTS (outf, "] (X)");
+ }
+ else if (W == 1 && sz == 0 && Z == 0)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16s4 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (W == 1 && sz == 0 && Z == 1)
+ {
+ OUTS (outf, "[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16s4 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, pregs (reg));
+ }
+ else if (W == 1 && sz == 1 && Z == 0)
+ {
+ OUTS (outf, "W[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16s2 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (W == 1 && sz == 2 && Z == 0)
+ {
+ OUTS (outf, "B[");
+ OUTS (outf, pregs (ptr));
+ OUTS (outf, " + ");
+ OUTS (outf, imm16 (offset));
+ OUTS (outf, "] = ");
+ OUTS (outf, dregs (reg));
+ }
+ else
+ return 0;
+
+ return 4;
+}
+
+static int
+decode_linkage_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* linkage
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.R.|
+ |.framesize.....................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int R = ((iw0 >> (Linkage_R_bits - 16)) & Linkage_R_mask);
+ int framesize = ((iw1 >> Linkage_framesize_bits) & Linkage_framesize_mask);
+
+ if (parallel)
+ return 0;
+
+ if (R == 0)
+ {
+ OUTS (outf, "LINK ");
+ OUTS (outf, uimm16s4 (framesize));
+ OUTS (outf, ";\t\t/* (");
+ OUTS (outf, uimm16s4d (framesize));
+ OUTS (outf, ") */");
+ comment = 1;
+ }
+ else if (R == 1)
+ OUTS (outf, "UNLINK");
+ else
+ return 0;
+
+ return 4;
+}
+
+static int
+decode_dsp32mac_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* dsp32mac
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
+ |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
+ int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+ int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+ int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
+ int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+ int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+ int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
+ int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
+ int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+ int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
+ int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
+ int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
+ int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
+ int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
+
+ if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
+ return 0;
+
+ if ((w1 || w0) && mmod == M_W32)
+ return 0;
+
+ if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
+ return 0;
+
+ if (w1 == 1 || op1 != 3)
+ {
+ if (w1)
+ OUTS (outf, P ? dregs (dst + 1) : dregs_hi (dst));
+
+ if (op1 == 3)
+ OUTS (outf, " = A1");
+ else
+ {
+ if (w1)
+ OUTS (outf, " = (");
+ decode_macfunc (1, op1, h01, h11, src0, src1, outf);
+ if (w1)
+ OUTS (outf, ")");
+ }
+
+ if (w0 == 1 || op0 != 3)
+ {
+ if (MM)
+ OUTS (outf, " (M)");
+ OUTS (outf, ", ");
+ }
+ }
+
+ if (w0 == 1 || op0 != 3)
+ {
+ /* Clear MM option since it only matters for MAC1, and if we made
+ it this far, we've already shown it or we want to ignore it. */
+ MM = 0;
+
+ if (w0)
+ OUTS (outf, P ? dregs (dst) : dregs_lo (dst));
+
+ if (op0 == 3)
+ OUTS (outf, " = A0");
+ else
+ {
+ if (w0)
+ OUTS (outf, " = (");
+ decode_macfunc (0, op0, h00, h10, src0, src1, outf);
+ if (w0)
+ OUTS (outf, ")");
+ }
+ }
+
+ decode_optmode (mmod, MM, outf);
+
+ return 4;
+}
+
+static int
+decode_dsp32mult_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* dsp32mult
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
+ |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+ int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+ int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
+ int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+ int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+ int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
+ int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
+ int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+ int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
+ int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
+ int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
+ int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
+
+ if (w1 == 0 && w0 == 0)
+ return 0;
+
+ if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
+ return 0;
+
+ if (w1)
+ {
+ OUTS (outf, P ? dregs (dst + 1) : dregs_hi (dst));
+ OUTS (outf, " = ");
+ decode_multfunc (h01, h11, src0, src1, outf);
+
+ if (w0)
+ {
+ if (MM)
+ OUTS (outf, " (M)");
+ MM = 0;
+ OUTS (outf, ", ");
+ }
+ }
+
+ if (w0)
+ {
+ OUTS (outf, P ? dregs (dst) : dregs_lo (dst));
+ OUTS (outf, " = ");
+ decode_multfunc (h00, h10, src0, src1, outf);
+ }
+
+ decode_optmode (mmod, MM, outf);
+ return 4;
+}
+
+static int
+decode_dsp32alu_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* dsp32alu
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
+ |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
+ int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
+ int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
+ int src0 = ((iw1 >> DSP32Alu_src0_bits) & DSP32Alu_src0_mask);
+ int src1 = ((iw1 >> DSP32Alu_src1_bits) & DSP32Alu_src1_mask);
+ int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
+ int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
+ int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
+ int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
+
+ if (aop == 0 && aopcde == 9 && HL == 0 && s == 0)
+ {
+ OUTS (outf, "A0.L = ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (aop == 2 && aopcde == 9 && HL == 1 && s == 0)
+ {
+ OUTS (outf, "A1.H = ");
+ OUTS (outf, dregs_hi (src0));
+ }
+ else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0)
+ {
+ OUTS (outf, "A1.L = ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (aop == 0 && aopcde == 9 && HL == 1 && s == 0)
+ {
+ OUTS (outf, "A0.H = ");
+ OUTS (outf, dregs_hi (src0));
+ }
+ else if (x == 1 && HL == 1 && aop == 3 && aopcde == 5)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND20)");
+ }
+ else if (x == 1 && HL == 1 && aop == 2 && aopcde == 5)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND20)");
+ }
+ else if (x == 0 && HL == 0 && aop == 1 && aopcde == 5)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND12)");
+ }
+ else if (x == 0 && HL == 0 && aop == 0 && aopcde == 5)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND12)");
+ }
+ else if (x == 1 && HL == 0 && aop == 3 && aopcde == 5)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND20)");
+ }
+ else if (x == 0 && HL == 1 && aop == 0 && aopcde == 5)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND12)");
+ }
+ else if (x == 1 && HL == 0 && aop == 2 && aopcde == 5)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND20)");
+ }
+ else if (x == 0 && HL == 1 && aop == 1 && aopcde == 5)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " (RND12)");
+ }
+ else if (HL == 1 && aop == 0 && aopcde == 2)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 1 && aop == 1 && aopcde == 2)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 1 && aop == 2 && aopcde == 2)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 1 && aop == 3 && aopcde == 2)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 0 && aopcde == 3)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 1 && aopcde == 3)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 3 && aopcde == 2)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 1 && aop == 0 && aopcde == 3)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 1 && aop == 1 && aopcde == 3)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 1 && aop == 2 && aopcde == 3)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 1 && aop == 3 && aopcde == 3)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 2 && aopcde == 2)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 1 && aopcde == 2)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 2 && aopcde == 3)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 3 && aopcde == 3)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs_hi (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aop == 0 && aopcde == 2)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs_lo (src1));
+ amod1 (s, x, outf);
+ }
+ else if (aop == 0 && aopcde == 9 && s == 1)
+ {
+ OUTS (outf, "A0 = ");
+ OUTS (outf, dregs (src0));
+ }
+ else if (aop == 3 && aopcde == 11 && s == 0)
+ OUTS (outf, "A0 -= A1");
+
+ else if (aop == 3 && aopcde == 11 && s == 1)
+ OUTS (outf, "A0 -= A1 (W32)");
+
+ else if (aop == 1 && aopcde == 22 && HL == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP2P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ") (TH");
+ if (s == 1)
+ OUTS (outf, ", R)");
+ else
+ OUTS (outf, ")");
+ }
+ else if (aop == 1 && aopcde == 22 && HL == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP2P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ") (TL");
+ if (s == 1)
+ OUTS (outf, ", R)");
+ else
+ OUTS (outf, ")");
+ }
+ else if (aop == 0 && aopcde == 22 && HL == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP2P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ") (RNDH");
+ if (s == 1)
+ OUTS (outf, ", R)");
+ else
+ OUTS (outf, ")");
+ }
+ else if (aop == 0 && aopcde == 22 && HL == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP2P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ") (RNDL");
+ if (s == 1)
+ OUTS (outf, ", R)");
+ else
+ OUTS (outf, ")");
+ }
+ else if (aop == 0 && s == 0 && aopcde == 8)
+ OUTS (outf, "A0 = 0");
+
+ else if (aop == 0 && s == 1 && aopcde == 8)
+ OUTS (outf, "A0 = A0 (S)");
+
+ else if (aop == 1 && s == 0 && aopcde == 8)
+ OUTS (outf, "A1 = 0");
+
+ else if (aop == 1 && s == 1 && aopcde == 8)
+ OUTS (outf, "A1 = A1 (S)");
+
+ else if (aop == 2 && s == 0 && aopcde == 8)
+ OUTS (outf, "A1 = A0 = 0");
+
+ else if (aop == 2 && s == 1 && aopcde == 8)
+ OUTS (outf, "A1 = A1 (S), A0 = A0 (S)");
+
+ else if (aop == 3 && s == 0 && aopcde == 8)
+ OUTS (outf, "A0 = A1");
+
+ else if (aop == 3 && s == 1 && aopcde == 8)
+ OUTS (outf, "A1 = A0");
+
+ else if (aop == 1 && aopcde == 9 && s == 0)
+ {
+ OUTS (outf, "A0.X = ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (aop == 1 && HL == 0 && aopcde == 11)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = (A0 += A1)");
+ }
+ else if (aop == 3 && HL == 0 && aopcde == 16)
+ OUTS (outf, "A1 = ABS A1, A0 = ABS A0");
+
+ else if (aop == 0 && aopcde == 23 && HL == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP3P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ") (HI");
+ if (s == 1)
+ OUTS (outf, ", R)");
+ else
+ OUTS (outf, ")");
+ }
+ else if (aop == 3 && aopcde == 9 && s == 0)
+ {
+ OUTS (outf, "A1.X = ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (aop == 1 && HL == 1 && aopcde == 16)
+ OUTS (outf, "A1 = ABS A1");
+
+ else if (aop == 0 && HL == 1 && aopcde == 16)
+ OUTS (outf, "A1 = ABS A0");
+
+ else if (aop == 2 && aopcde == 9 && s == 1)
+ {
+ OUTS (outf, "A1 = ");
+ OUTS (outf, dregs (src0));
+ }
+ else if (HL == 0 && aop == 3 && aopcde == 12)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " (RND)");
+ }
+ else if (aop == 1 && HL == 0 && aopcde == 16)
+ OUTS (outf, "A0 = ABS A1");
+
+ else if (aop == 0 && HL == 0 && aopcde == 16)
+ OUTS (outf, "A0 = ABS A0");
+
+ else if (aop == 3 && HL == 0 && aopcde == 15)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = -");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " (V)");
+ }
+ else if (aop == 3 && s == 1 && HL == 0 && aopcde == 7)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = -");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " (S)");
+ }
+ else if (aop == 3 && s == 0 && HL == 0 && aopcde == 7)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = -");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " (NS)");
+ }
+ else if (aop == 1 && HL == 1 && aopcde == 11)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = (A0 += A1)");
+ }
+ else if (aop == 2 && aopcde == 11 && s == 0)
+ OUTS (outf, "A0 += A1");
+
+ else if (aop == 2 && aopcde == 11 && s == 1)
+ OUTS (outf, "A0 += A1 (W32)");
+
+ else if (aop == 3 && HL == 0 && aopcde == 14)
+ OUTS (outf, "A1 = -A1, A0 = -A0");
+
+ else if (HL == 1 && aop == 3 && aopcde == 12)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " (RND)");
+ }
+ else if (aop == 0 && aopcde == 23 && HL == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP3P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ") (LO");
+ if (s == 1)
+ OUTS (outf, ", R)");
+ else
+ OUTS (outf, ")");
+ }
+ else if (aop == 0 && HL == 0 && aopcde == 14)
+ OUTS (outf, "A0 = -A0");
+
+ else if (aop == 1 && HL == 0 && aopcde == 14)
+ OUTS (outf, "A0 = -A1");
+
+ else if (aop == 0 && HL == 1 && aopcde == 14)
+ OUTS (outf, "A1 = -A0");
+
+ else if (aop == 1 && HL == 1 && aopcde == 14)
+ OUTS (outf, "A1 = -A1");
+
+ else if (aop == 0 && aopcde == 12)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = SIGN (");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, ") * ");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, " + SIGN (");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ") * ");
+ OUTS (outf, dregs_lo (src1));
+ }
+ else if (aop == 2 && aopcde == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " -|+ ");
+ OUTS (outf, dregs (src1));
+ amod0 (s, x, outf);
+ }
+ else if (aop == 1 && aopcde == 12)
+ {
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, " = A1.L + A1.H, ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = A0.L + A0.H");
+ }
+ else if (aop == 2 && aopcde == 4)
+ {
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs (src1));
+ amod1 (s, x, outf);
+ }
+ else if (HL == 0 && aopcde == 1)
+ {
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " +|+ ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " -|- ");
+ OUTS (outf, dregs (src1));
+ amod0amod2 (s, x, aop, outf);
+ }
+ else if (aop == 0 && aopcde == 11)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = (A0 += A1)");
+ }
+ else if (aop == 0 && aopcde == 10)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = A0.X");
+ }
+ else if (aop == 1 && aopcde == 10)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = A1.X");
+ }
+ else if (aop == 1 && aopcde == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " +|- ");
+ OUTS (outf, dregs (src1));
+ amod0 (s, x, outf);
+ }
+ else if (aop == 3 && aopcde == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " -|- ");
+ OUTS (outf, dregs (src1));
+ amod0 (s, x, outf);
+ }
+ else if (aop == 1 && aopcde == 4)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " - ");
+ OUTS (outf, dregs (src1));
+ amod1 (s, x, outf);
+ }
+ else if (aop == 0 && aopcde == 17)
+ {
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, " = A1 + A0, ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = A1 - A0");
+ amod1 (s, x, outf);
+ }
+ else if (aop == 1 && aopcde == 17)
+ {
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, " = A0 + A1, ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = A0 - A1");
+ amod1 (s, x, outf);
+ }
+ else if (aop == 0 && aopcde == 18)
+ {
+ OUTS (outf, "SAA (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ")");
+ aligndir (s, outf);
+ }
+ else if (aop == 3 && aopcde == 18)
+ OUTS (outf, "DISALGNEXCPT");
+
+ else if (aop == 0 && aopcde == 20)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP1P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ")");
+ aligndir (s, outf);
+ }
+ else if (aop == 1 && aopcde == 20)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEOP1P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ") (T");
+ if (s == 1)
+ OUTS (outf, ", R)");
+ else
+ OUTS (outf, ")");
+ }
+ else if (aop == 0 && aopcde == 21)
+ {
+ OUTS (outf, "(");
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, ") = BYTEOP16P (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ")");
+ aligndir (s, outf);
+ }
+ else if (aop == 1 && aopcde == 21)
+ {
+ OUTS (outf, "(");
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, ") = BYTEOP16M (");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src1));
+ OUTS (outf, ")");
+ aligndir (s, outf);
+ }
+ else if (aop == 2 && aopcde == 7)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ABS ");
+ OUTS (outf, dregs (src0));
+ }
+ else if (aop == 1 && aopcde == 7)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = MIN (");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ")");
+ }
+ else if (aop == 0 && aopcde == 7)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = MAX (");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ")");
+ }
+ else if (aop == 2 && aopcde == 6)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ABS ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " (V)");
+ }
+ else if (aop == 1 && aopcde == 6)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = MIN (");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ") (V)");
+ }
+ else if (aop == 0 && aopcde == 6)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = MAX (");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ") (V)");
+ }
+ else if (HL == 1 && aopcde == 1)
+ {
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " +|- ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " -|+ ");
+ OUTS (outf, dregs (src1));
+ amod0amod2 (s, x, aop, outf);
+ }
+ else if (aop == 0 && aopcde == 4)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " + ");
+ OUTS (outf, dregs (src1));
+ amod1 (s, x, outf);
+ }
+ else if (aop == 0 && aopcde == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " +|+ ");
+ OUTS (outf, dregs (src1));
+ amod0 (s, x, outf);
+ }
+ else if (aop == 0 && aopcde == 24)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = BYTEPACK (");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ")");
+ }
+ else if (aop == 1 && aopcde == 24)
+ {
+ OUTS (outf, "(");
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, ") = BYTEUNPACK ");
+ OUTS (outf, dregs (src0 + 1));
+ OUTS (outf, ":");
+ OUTS (outf, imm5d (src0));
+ aligndir (s, outf);
+ }
+ else if (aopcde == 13)
+ {
+ OUTS (outf, "(");
+ OUTS (outf, dregs (dst1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, ") = SEARCH ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, " (");
+ searchmod (aop, outf);
+ OUTS (outf, ")");
+ }
+ else
+ return 0;
+
+ return 4;
+}
+
+static int
+decode_dsp32shift_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* dsp32shift
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
+ |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
+ int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
+ int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
+ int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
+ int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
+ int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
+ const char *acc01 = (HLs & 1) == 0 ? "A0" : "A1";
+
+ if (HLs == 0 && sop == 0 && sopcde == 0)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_lo (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (HLs == 1 && sop == 0 && sopcde == 0)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (HLs == 2 && sop == 0 && sopcde == 0)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_lo (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (HLs == 3 && sop == 0 && sopcde == 0)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (HLs == 0 && sop == 1 && sopcde == 0)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_lo (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (S)");
+ }
+ else if (HLs == 1 && sop == 1 && sopcde == 0)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (S)");
+ }
+ else if (HLs == 2 && sop == 1 && sopcde == 0)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_lo (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (S)");
+ }
+ else if (HLs == 3 && sop == 1 && sopcde == 0)
+ {
+ OUTS (outf, dregs_hi (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (S)");
+ }
+ else if (sop == 2 && sopcde == 0)
+ {
+ OUTS (outf, (HLs & 2) == 0 ? dregs_lo (dst0) : dregs_hi (dst0));
+ OUTS (outf, " = LSHIFT ");
+ OUTS (outf, (HLs & 1) == 0 ? dregs_lo (src1) : dregs_hi (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 0 && sopcde == 3)
+ {
+ OUTS (outf, acc01);
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, acc01);
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 1 && sopcde == 3)
+ {
+ OUTS (outf, acc01);
+ OUTS (outf, " = LSHIFT ");
+ OUTS (outf, acc01);
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 2 && sopcde == 3)
+ {
+ OUTS (outf, acc01);
+ OUTS (outf, " = ROT ");
+ OUTS (outf, acc01);
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 3 && sopcde == 3)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ROT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 1 && sopcde == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (V, S)");
+ }
+ else if (sop == 0 && sopcde == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (V)");
+ }
+ else if (sop == 0 && sopcde == 2)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 1 && sopcde == 2)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ASHIFT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (S)");
+ }
+ else if (sop == 2 && sopcde == 2)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = LSHIFT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 3 && sopcde == 2)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ROT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ }
+ else if (sop == 2 && sopcde == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = LSHIFT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, " (V)");
+ }
+ else if (sop == 0 && sopcde == 4)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = PACK (");
+ OUTS (outf, dregs_lo (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 1 && sopcde == 4)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = PACK (");
+ OUTS (outf, dregs_lo (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 2 && sopcde == 4)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = PACK (");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 3 && sopcde == 4)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = PACK (");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_hi (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 0 && sopcde == 5)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = SIGNBITS ");
+ OUTS (outf, dregs (src1));
+ }
+ else if (sop == 1 && sopcde == 5)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = SIGNBITS ");
+ OUTS (outf, dregs_lo (src1));
+ }
+ else if (sop == 2 && sopcde == 5)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = SIGNBITS ");
+ OUTS (outf, dregs_hi (src1));
+ }
+ else if (sop == 0 && sopcde == 6)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = SIGNBITS A0");
+ }
+ else if (sop == 1 && sopcde == 6)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = SIGNBITS A1");
+ }
+ else if (sop == 3 && sopcde == 6)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = ONES ");
+ OUTS (outf, dregs (src1));
+ }
+ else if (sop == 0 && sopcde == 7)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = EXPADJ (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 1 && sopcde == 7)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = EXPADJ (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ") (V)");
+ }
+ else if (sop == 2 && sopcde == 7)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = EXPADJ (");
+ OUTS (outf, dregs_lo (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 3 && sopcde == 7)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = EXPADJ (");
+ OUTS (outf, dregs_hi (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 0 && sopcde == 8)
+ {
+ OUTS (outf, "BITMUX (");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", A0) (ASR)");
+ }
+ else if (sop == 1 && sopcde == 8)
+ {
+ OUTS (outf, "BITMUX (");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", A0) (ASL)");
+ }
+ else if (sop == 0 && sopcde == 9)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = VIT_MAX (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ") (ASL)");
+ }
+ else if (sop == 1 && sopcde == 9)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = VIT_MAX (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ") (ASR)");
+ }
+ else if (sop == 2 && sopcde == 9)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = VIT_MAX (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ") (ASL)");
+ }
+ else if (sop == 3 && sopcde == 9)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = VIT_MAX (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ") (ASR)");
+ }
+ else if (sop == 0 && sopcde == 10)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = EXTRACT (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ") (Z)");
+ }
+ else if (sop == 1 && sopcde == 10)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = EXTRACT (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs_lo (src0));
+ OUTS (outf, ") (X)");
+ }
+ else if (sop == 2 && sopcde == 10)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = DEPOSIT (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 3 && sopcde == 10)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = DEPOSIT (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ") (X)");
+ }
+ else if (sop == 0 && sopcde == 11)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = CC = BXORSHIFT (A0, ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 1 && sopcde == 11)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = CC = BXOR (A0, ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 0 && sopcde == 12)
+ OUTS (outf, "A0 = BXORSHIFT (A0, A1, CC)");
+
+ else if (sop == 1 && sopcde == 12)
+ {
+ OUTS (outf, dregs_lo (dst0));
+ OUTS (outf, " = CC = BXOR (A0, A1, CC)");
+ }
+ else if (sop == 0 && sopcde == 13)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ALIGN8 (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 1 && sopcde == 13)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ALIGN16 (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ")");
+ }
+ else if (sop == 2 && sopcde == 13)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ALIGN24 (");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, ", ");
+ OUTS (outf, dregs (src0));
+ OUTS (outf, ")");
+ }
+ else
+ return 0;
+
+ return 4;
+}
+
+static int
+decode_dsp32shiftimm_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* dsp32shiftimm
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
+ |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src1 = ((iw1 >> DSP32ShiftImm_src1_bits) & DSP32ShiftImm_src1_mask);
+ int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
+ int bit8 = ((iw1 >> 8) & 0x1);
+ int immag = ((iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
+ int newimmag = (-(iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
+ int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
+ int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
+ int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
+
+
+ if (sop == 0 && sopcde == 0)
+ {
+ OUTS (outf, (HLs & 2) ? dregs_hi (dst0) : dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, (HLs & 1) ? dregs_hi (src1) : dregs_lo (src1));
+ OUTS (outf, " >>> ");
+ OUTS (outf, uimm4 (newimmag));
+ }
+ else if (sop == 1 && sopcde == 0 && bit8 == 0)
+ {
+ OUTS (outf, (HLs & 2) ? dregs_hi (dst0) : dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, (HLs & 1) ? dregs_hi (src1) : dregs_lo (src1));
+ OUTS (outf, " << ");
+ OUTS (outf, uimm4 (immag));
+ OUTS (outf, " (S)");
+ }
+ else if (sop == 1 && sopcde == 0 && bit8 == 1)
+ {
+ OUTS (outf, (HLs & 2) ? dregs_hi (dst0) : dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, (HLs & 1) ? dregs_hi (src1) : dregs_lo (src1));
+ OUTS (outf, " >>> ");
+ OUTS (outf, uimm4 (newimmag));
+ OUTS (outf, " (S)");
+ }
+ else if (sop == 2 && sopcde == 0 && bit8 == 0)
+ {
+ OUTS (outf, (HLs & 2) ? dregs_hi (dst0) : dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, (HLs & 1) ? dregs_hi (src1) : dregs_lo (src1));
+ OUTS (outf, " << ");
+ OUTS (outf, uimm4 (immag));
+ }
+ else if (sop == 2 && sopcde == 0 && bit8 == 1)
+ {
+ OUTS (outf, (HLs & 2) ? dregs_hi (dst0) : dregs_lo (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, (HLs & 1) ? dregs_hi (src1) : dregs_lo (src1));
+ OUTS (outf, " >> ");
+ OUTS (outf, uimm4 (newimmag));
+ }
+ else if (sop == 2 && sopcde == 3 && HLs == 1)
+ {
+ OUTS (outf, "A1 = ROT A1 BY ");
+ OUTS (outf, imm6 (immag));
+ }
+ else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0)
+ {
+ OUTS (outf, "A0 = A0 << ");
+ OUTS (outf, uimm5 (immag));
+ }
+ else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1)
+ {
+ OUTS (outf, "A0 = A0 >>> ");
+ OUTS (outf, uimm5 (newimmag));
+ }
+ else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0)
+ {
+ OUTS (outf, "A1 = A1 << ");
+ OUTS (outf, uimm5 (immag));
+ }
+ else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1)
+ {
+ OUTS (outf, "A1 = A1 >>> ");
+ OUTS (outf, uimm5 (newimmag));
+ }
+ else if (sop == 1 && sopcde == 3 && HLs == 0)
+ {
+ OUTS (outf, "A0 = A0 >> ");
+ OUTS (outf, uimm5 (newimmag));
+ }
+ else if (sop == 1 && sopcde == 3 && HLs == 1)
+ {
+ OUTS (outf, "A1 = A1 >> ");
+ OUTS (outf, uimm5 (newimmag));
+ }
+ else if (sop == 2 && sopcde == 3 && HLs == 0)
+ {
+ OUTS (outf, "A0 = ROT A0 BY ");
+ OUTS (outf, imm6 (immag));
+ }
+ else if (sop == 1 && sopcde == 1 && bit8 == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " << ");
+ OUTS (outf, uimm5 (immag));
+ OUTS (outf, " (V, S)");
+ }
+ else if (sop == 1 && sopcde == 1 && bit8 == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " >>> ");
+ OUTS (outf, imm5 (-immag));
+ OUTS (outf, " (V, S)");
+ }
+ else if (sop == 2 && sopcde == 1 && bit8 == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " >> ");
+ OUTS (outf, uimm5 (newimmag));
+ OUTS (outf, " (V)");
+ }
+ else if (sop == 2 && sopcde == 1 && bit8 == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " << ");
+ OUTS (outf, imm5 (immag));
+ OUTS (outf, " (V)");
+ }
+ else if (sop == 0 && sopcde == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " >>> ");
+ OUTS (outf, uimm5 (newimmag));
+ OUTS (outf, " (V)");
+ }
+ else if (sop == 1 && sopcde == 2)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " << ");
+ OUTS (outf, uimm5 (immag));
+ OUTS (outf, " (S)");
+ }
+ else if (sop == 2 && sopcde == 2 && bit8 == 1)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " >> ");
+ OUTS (outf, uimm5 (newimmag));
+ }
+ else if (sop == 2 && sopcde == 2 && bit8 == 0)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " << ");
+ OUTS (outf, uimm5 (immag));
+ }
+ else if (sop == 3 && sopcde == 2)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ROT ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " BY ");
+ OUTS (outf, imm6 (immag));
+ }
+ else if (sop == 0 && sopcde == 2)
+ {
+ OUTS (outf, dregs (dst0));
+ OUTS (outf, " = ");
+ OUTS (outf, dregs (src1));
+ OUTS (outf, " >>> ");
+ OUTS (outf, uimm5 (newimmag));
+ }
+ else
+ return 0;
+
+ return 4;
+}
+
+static int
+decode_pseudoDEBUG_0 (TIword iw0, disassemble_info *outf)
+{
+ /* pseudoDEBUG
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |.fn....|.grp.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int fn = ((iw0 >> PseudoDbg_fn_bits) & PseudoDbg_fn_mask);
+ int grp = ((iw0 >> PseudoDbg_grp_bits) & PseudoDbg_grp_mask);
+ int reg = ((iw0 >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask);
+
+ if (parallel)
+ return 0;
+
+ if (reg == 0 && fn == 3)
+ OUTS (outf, "DBG A0");
+
+ else if (reg == 1 && fn == 3)
+ OUTS (outf, "DBG A1");
+
+ else if (reg == 3 && fn == 3)
+ OUTS (outf, "ABORT");
+
+ else if (reg == 4 && fn == 3)
+ OUTS (outf, "HLT");
+
+ else if (reg == 5 && fn == 3)
+ OUTS (outf, "DBGHALT");
+
+ else if (reg == 6 && fn == 3)
+ {
+ OUTS (outf, "DBGCMPLX (");
+ OUTS (outf, dregs (grp));
+ OUTS (outf, ")");
+ }
+ else if (reg == 7 && fn == 3)
+ OUTS (outf, "DBG");
+
+ else if (grp == 0 && fn == 2)
+ {
+ OUTS (outf, "OUTC ");
+ OUTS (outf, dregs (reg));
+ }
+ else if (fn == 0)
+ {
+ OUTS (outf, "DBG ");
+ OUTS (outf, allregs (reg, grp));
+ }
+ else if (fn == 1)
+ {
+ OUTS (outf, "PRNT ");
+ OUTS (outf, allregs (reg, grp));
+ }
+ else
+ return 0;
+
+ return 2;
+}
+
+static int
+decode_pseudoOChar_0 (TIword iw0, disassemble_info *outf)
+{
+ /* psedoOChar
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int ch = ((iw0 >> PseudoChr_ch_bits) & PseudoChr_ch_mask);
+
+ if (parallel)
+ return 0;
+
+ OUTS (outf, "OUTC ");
+ OUTS (outf, uimm8 (ch));
+
+ return 2;
+}
+
+static int
+decode_pseudodbg_assert_0 (TIword iw0, TIword iw1, disassemble_info *outf)
+{
+ /* pseudodbg_assert
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 0 | - | - | - | dbgop |.grp.......|.regtest...|
+ |.expected......................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int expected = ((iw1 >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask);
+ int dbgop = ((iw0 >> (PseudoDbg_Assert_dbgop_bits - 16)) & PseudoDbg_Assert_dbgop_mask);
+ int grp = ((iw0 >> (PseudoDbg_Assert_grp_bits - 16)) & PseudoDbg_Assert_grp_mask);
+ int regtest = ((iw0 >> (PseudoDbg_Assert_regtest_bits - 16)) & PseudoDbg_Assert_regtest_mask);
+
+ if (parallel)
+ return 0;
+
+ if (dbgop == 0)
+ {
+ OUTS (outf, "DBGA (");
+ OUTS (outf, regs_lo (regtest, grp));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm16 (expected));
+ OUTS (outf, ")");
+ }
+ else if (dbgop == 1)
+ {
+ OUTS (outf, "DBGA (");
+ OUTS (outf, regs_hi (regtest, grp));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm16 (expected));
+ OUTS (outf, ")");
+ }
+ else if (dbgop == 2)
+ {
+ OUTS (outf, "DBGAL (");
+ OUTS (outf, allregs (regtest, grp));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm16 (expected));
+ OUTS (outf, ")");
+ }
+ else if (dbgop == 3)
+ {
+ OUTS (outf, "DBGAH (");
+ OUTS (outf, allregs (regtest, grp));
+ OUTS (outf, ", ");
+ OUTS (outf, uimm16 (expected));
+ OUTS (outf, ")");
+ }
+ else
+ return 0;
+ return 4;
+}
+
+static int
+_print_insn_bfin (bfd_vma pc, disassemble_info *outf)
+{
+ bfd_byte buf[4];
+ TIword iw0;
+ TIword iw1;
+ int rv = 0;
+
+ (*outf->read_memory_func) (pc & ~0x1, buf, 2, outf);
+ (*outf->read_memory_func) ((pc + 2) & ~0x1, buf + 2, 2, outf);
+
+ iw0 = bfd_getl16 (buf);
+ iw1 = bfd_getl16 (buf + 2);
+
+ if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
+ {
+ if (parallel)
+ {
+ OUTS (outf, "ILLEGAL");
+ return 0;
+ }
+ OUTS (outf, "MNOP");
+ return 4;
+ }
+ else if ((iw0 & 0xff00) == 0x0000)
+ rv = decode_ProgCtrl_0 (iw0, outf);
+ else if ((iw0 & 0xffc0) == 0x0240)
+ rv = decode_CaCTRL_0 (iw0, outf);
+ else if ((iw0 & 0xff80) == 0x0100)
+ rv = decode_PushPopReg_0 (iw0, outf);
+ else if ((iw0 & 0xfe00) == 0x0400)
+ rv = decode_PushPopMultiple_0 (iw0, outf);
+ else if ((iw0 & 0xfe00) == 0x0600)
+ rv = decode_ccMV_0 (iw0, outf);
+ else if ((iw0 & 0xf800) == 0x0800)
+ rv = decode_CCflag_0 (iw0, outf);
+ else if ((iw0 & 0xffe0) == 0x0200)
+ rv = decode_CC2dreg_0 (iw0, outf);
+ else if ((iw0 & 0xff00) == 0x0300)
+ rv = decode_CC2stat_0 (iw0, outf);
+ else if ((iw0 & 0xf000) == 0x1000)
+ rv = decode_BRCC_0 (iw0, pc, outf);
+ else if ((iw0 & 0xf000) == 0x2000)
+ rv = decode_UJUMP_0 (iw0, pc, outf);
+ else if ((iw0 & 0xf000) == 0x3000)
+ rv = decode_REGMV_0 (iw0, outf);
+ else if ((iw0 & 0xfc00) == 0x4000)
+ rv = decode_ALU2op_0 (iw0, outf);
+ else if ((iw0 & 0xfe00) == 0x4400)
+ rv = decode_PTR2op_0 (iw0, outf);
+ else if ((iw0 & 0xf800) == 0x4800)
+ rv = decode_LOGI2op_0 (iw0, outf);
+ else if ((iw0 & 0xf000) == 0x5000)
+ rv = decode_COMP3op_0 (iw0, outf);
+ else if ((iw0 & 0xf800) == 0x6000)
+ rv = decode_COMPI2opD_0 (iw0, outf);
+ else if ((iw0 & 0xf800) == 0x6800)
+ rv = decode_COMPI2opP_0 (iw0, outf);
+ else if ((iw0 & 0xf000) == 0x8000)
+ rv = decode_LDSTpmod_0 (iw0, outf);
+ else if ((iw0 & 0xff60) == 0x9e60)
+ rv = decode_dagMODim_0 (iw0, outf);
+ else if ((iw0 & 0xfff0) == 0x9f60)
+ rv = decode_dagMODik_0 (iw0, outf);
+ else if ((iw0 & 0xfc00) == 0x9c00)
+ rv = decode_dspLDST_0 (iw0, outf);
+ else if ((iw0 & 0xf000) == 0x9000)
+ rv = decode_LDST_0 (iw0, outf);
+ else if ((iw0 & 0xfc00) == 0xb800)
+ rv = decode_LDSTiiFP_0 (iw0, outf);
+ else if ((iw0 & 0xe000) == 0xA000)
+ rv = decode_LDSTii_0 (iw0, outf);
+ else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000)
+ rv = decode_LoopSetup_0 (iw0, iw1, pc, outf);
+ else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_LDIMMhalf_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_CALLa_0 (iw0, iw1, pc, outf);
+ else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_LDSTidxI_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_linkage_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_dsp32mac_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_dsp32mult_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_dsp32alu_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000)
+ rv = decode_dsp32shift_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_dsp32shiftimm_0 (iw0, iw1, outf);
+ else if ((iw0 & 0xff00) == 0xf800)
+ rv = decode_pseudoDEBUG_0 (iw0, outf);
+ else if ((iw0 & 0xFF00) == 0xF900)
+ rv = decode_pseudoOChar_0 (iw0, outf);
+ else if ((iw0 & 0xFF00) == 0xf000 && (iw1 & 0x0000) == 0x0000)
+ rv = decode_pseudodbg_assert_0 (iw0, iw1, outf);
+
+ if (rv == 0)
+ OUTS (outf, "ILLEGAL");
+
+ return rv;
+}
+
+
+int
+print_insn_bfin (bfd_vma pc, disassemble_info *outf)
+{
+ bfd_byte buf[2];
+ unsigned short iw0;
+ int count = 0;
+
+ (*outf->read_memory_func) (pc & ~0x01, buf, 2, outf);
+ iw0 = bfd_getl16 (buf);
+
+ count += _print_insn_bfin (pc, outf);
+
+ /* Proper display of multiple issue instructions. */
+
+ if (count == 4 && (iw0 & 0xc000) == 0xc000 && (iw0 & BIT_MULTI_INS)
+ && ((iw0 & 0xe800) != 0xe800 /* Not Linkage. */ ))
+ {
+ int legal = 1;
+ int len;
+
+ parallel = 1;
+ outf->fprintf_func (outf->stream, " || ");
+ len = _print_insn_bfin (pc + 4, outf);
+ outf->fprintf_func (outf->stream, " || ");
+ if (len != 2)
+ legal = 0;
+ len = _print_insn_bfin (pc + 6, outf);
+ if (len != 2)
+ legal = 0;
+
+ if (legal)
+ count = 8;
+ else
+ {
+ outf->fprintf_func (outf->stream, ";\t\t/* ILLEGAL PARALLEL INSTRUCTION */");
+ comment = 1;
+ count = 0;
+ }
+ parallel = 0;
+ }
+
+ if (!comment)
+ outf->fprintf_func (outf->stream, ";");
+
+ if (count == 0)
+ return 2;
+
+ comment = 0;
+
+ return count;
+}
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 803b6ef..27dff70 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -213,6 +213,8 @@ enum bfd_architecture
#define bfd_mach_m32r 0 /* backwards compatibility */
bfd_arch_mn10200, /* Matsushita MN10200 */
bfd_arch_mn10300, /* Matsushita MN10300 */
+ bfd_arch_bfin, /* ADI Blackfin */
+#define bfd_mach_bfin 1
bfd_arch_cris, /* Axis CRIS */
#define bfd_mach_cris_v0_v10 255
#define bfd_mach_cris_v32 32
@@ -382,6 +384,7 @@ int print_insn_h8500 (bfd_vma, disassemble_info*);
int print_insn_alpha (bfd_vma, disassemble_info*);
disassembler_ftype arc_get_disassembler (int, int);
int print_insn_arm (bfd_vma, disassemble_info*);
+int print_insn_bfin (bfd_vma, disassemble_info*);
int print_insn_sparc (bfd_vma, disassemble_info*);
int print_insn_big_a29k (bfd_vma, disassemble_info*);
int print_insn_little_a29k (bfd_vma, disassemble_info*);
diff --git a/target-bfin/opcode/bfin.h b/target-bfin/opcode/bfin.h
new file mode 100644
index 0000000..21ddfab
--- /dev/null
+++ b/target-bfin/opcode/bfin.h
@@ -0,0 +1,1754 @@
+/* bfin.h -- Header file for ADI Blackfin opcode table
+ Copyright 2005 Free Software Foundation, Inc.
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+will be useful, but WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this file; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef OPCODE_BFIN_H
+#define OPCODE_BFIN_H
+
+/* Common to all DSP32 instructions. */
+#define BIT_MULTI_INS 0x0800
+
+/* This just sets the multi instruction bit of a DSP32 instruction. */
+#define SET_MULTI_INSTRUCTION_BIT(x) x->value |= BIT_MULTI_INS;
+
+
+/* DSP instructions (32 bit) */
+
+/* mmod field. */
+#define M_S2RND 1
+#define M_T 2
+#define M_W32 3
+#define M_FU 4
+#define M_TFU 6
+#define M_IS 8
+#define M_ISS2 9
+#define M_IH 11
+#define M_IU 12
+
+static inline int is_macmod_pmove(int x)
+{
+ return (x == 0) || (x == M_IS) || (x == M_FU) || (x == M_S2RND)
+ || (x == M_ISS2) || (x == M_IU);
+}
+
+static inline int is_macmod_hmove(int x)
+{
+ return (x == 0) || (x == M_IS) || (x == M_FU) || (x == M_IU) || (x == M_T)
+ || (x == M_TFU) || (x == M_S2RND) || (x == M_ISS2) || (x == M_IH);
+}
+
+/* dsp32mac
++----+----+---+---|---+----+----+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
+|.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1......|
++----+----+---+---|---+----+----+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_src1;
+ int mask_src1;
+ int bits_src0;
+ int mask_src0;
+ int bits_dst;
+ int mask_dst;
+ int bits_h10;
+ int mask_h10;
+ int bits_h00;
+ int mask_h00;
+ int bits_op0;
+ int mask_op0;
+ int bits_w0;
+ int mask_w0;
+ int bits_h11;
+ int mask_h11;
+ int bits_h01;
+ int mask_h01;
+ int bits_op1;
+ int mask_op1;
+ int bits_w1;
+ int mask_w1;
+ int bits_P;
+ int mask_P;
+ int bits_MM;
+ int mask_MM;
+ int bits_mmod;
+ int mask_mmod;
+ int bits_code2;
+ int mask_code2;
+ int bits_M;
+ int mask_M;
+ int bits_code;
+ int mask_code;
+} DSP32Mac;
+
+#define DSP32Mac_opcode 0xc0000000
+#define DSP32Mac_src1_bits 0
+#define DSP32Mac_src1_mask 0x7
+#define DSP32Mac_src0_bits 3
+#define DSP32Mac_src0_mask 0x7
+#define DSP32Mac_dst_bits 6
+#define DSP32Mac_dst_mask 0x7
+#define DSP32Mac_h10_bits 9
+#define DSP32Mac_h10_mask 0x1
+#define DSP32Mac_h00_bits 10
+#define DSP32Mac_h00_mask 0x1
+#define DSP32Mac_op0_bits 11
+#define DSP32Mac_op0_mask 0x3
+#define DSP32Mac_w0_bits 13
+#define DSP32Mac_w0_mask 0x1
+#define DSP32Mac_h11_bits 14
+#define DSP32Mac_h11_mask 0x1
+#define DSP32Mac_h01_bits 15
+#define DSP32Mac_h01_mask 0x1
+#define DSP32Mac_op1_bits 16
+#define DSP32Mac_op1_mask 0x3
+#define DSP32Mac_w1_bits 18
+#define DSP32Mac_w1_mask 0x1
+#define DSP32Mac_p_bits 19
+#define DSP32Mac_p_mask 0x1
+#define DSP32Mac_MM_bits 20
+#define DSP32Mac_MM_mask 0x1
+#define DSP32Mac_mmod_bits 21
+#define DSP32Mac_mmod_mask 0xf
+#define DSP32Mac_code2_bits 25
+#define DSP32Mac_code2_mask 0x3
+#define DSP32Mac_M_bits 27
+#define DSP32Mac_M_mask 0x1
+#define DSP32Mac_code_bits 28
+#define DSP32Mac_code_mask 0xf
+
+#define init_DSP32Mac \
+{ \
+ DSP32Mac_opcode, \
+ DSP32Mac_src1_bits, DSP32Mac_src1_mask, \
+ DSP32Mac_src0_bits, DSP32Mac_src0_mask, \
+ DSP32Mac_dst_bits, DSP32Mac_dst_mask, \
+ DSP32Mac_h10_bits, DSP32Mac_h10_mask, \
+ DSP32Mac_h00_bits, DSP32Mac_h00_mask, \
+ DSP32Mac_op0_bits, DSP32Mac_op0_mask, \
+ DSP32Mac_w0_bits, DSP32Mac_w0_mask, \
+ DSP32Mac_h11_bits, DSP32Mac_h11_mask, \
+ DSP32Mac_h01_bits, DSP32Mac_h01_mask, \
+ DSP32Mac_op1_bits, DSP32Mac_op1_mask, \
+ DSP32Mac_w1_bits, DSP32Mac_w1_mask, \
+ DSP32Mac_p_bits, DSP32Mac_p_mask, \
+ DSP32Mac_MM_bits, DSP32Mac_MM_mask, \
+ DSP32Mac_mmod_bits, DSP32Mac_mmod_mask, \
+ DSP32Mac_code2_bits, DSP32Mac_code2_mask, \
+ DSP32Mac_M_bits, DSP32Mac_M_mask, \
+ DSP32Mac_code_bits, DSP32Mac_code_mask \
+};
+
+/* dsp32mult
++----+----+---+---|---+----+----+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
+|.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1......|
++----+----+---+---|---+----+----+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef DSP32Mac DSP32Mult;
+#define DSP32Mult_opcode 0xc2000000
+
+#define init_DSP32Mult \
+{ \
+ DSP32Mult_opcode, \
+ DSP32Mac_src1_bits, DSP32Mac_src1_mask, \
+ DSP32Mac_src0_bits, DSP32Mac_src0_mask, \
+ DSP32Mac_dst_bits, DSP32Mac_dst_mask, \
+ DSP32Mac_h10_bits, DSP32Mac_h10_mask, \
+ DSP32Mac_h00_bits, DSP32Mac_h00_mask, \
+ DSP32Mac_op0_bits, DSP32Mac_op0_mask, \
+ DSP32Mac_w0_bits, DSP32Mac_w0_mask, \
+ DSP32Mac_h11_bits, DSP32Mac_h11_mask, \
+ DSP32Mac_h01_bits, DSP32Mac_h01_mask, \
+ DSP32Mac_op1_bits, DSP32Mac_op1_mask, \
+ DSP32Mac_w1_bits, DSP32Mac_w1_mask, \
+ DSP32Mac_p_bits, DSP32Mac_p_mask, \
+ DSP32Mac_MM_bits, DSP32Mac_MM_mask, \
+ DSP32Mac_mmod_bits, DSP32Mac_mmod_mask, \
+ DSP32Mac_code2_bits, DSP32Mac_code2_mask, \
+ DSP32Mac_M_bits, DSP32Mac_M_mask, \
+ DSP32Mac_code_bits, DSP32Mac_code_mask \
+};
+
+/* dsp32alu
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
+|.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_src1;
+ int mask_src1;
+ int bits_src0;
+ int mask_src0;
+ int bits_dst1;
+ int mask_dst1;
+ int bits_dst0;
+ int mask_dst0;
+ int bits_x;
+ int mask_x;
+ int bits_s;
+ int mask_s;
+ int bits_aop;
+ int mask_aop;
+ int bits_aopcde;
+ int mask_aopcde;
+ int bits_HL;
+ int mask_HL;
+ int bits_dontcare;
+ int mask_dontcare;
+ int bits_code2;
+ int mask_code2;
+ int bits_M;
+ int mask_M;
+ int bits_code;
+ int mask_code;
+} DSP32Alu;
+
+#define DSP32Alu_opcode 0xc4000000
+#define DSP32Alu_src1_bits 0
+#define DSP32Alu_src1_mask 0x7
+#define DSP32Alu_src0_bits 3
+#define DSP32Alu_src0_mask 0x7
+#define DSP32Alu_dst1_bits 6
+#define DSP32Alu_dst1_mask 0x7
+#define DSP32Alu_dst0_bits 9
+#define DSP32Alu_dst0_mask 0x7
+#define DSP32Alu_x_bits 12
+#define DSP32Alu_x_mask 0x1
+#define DSP32Alu_s_bits 13
+#define DSP32Alu_s_mask 0x1
+#define DSP32Alu_aop_bits 14
+#define DSP32Alu_aop_mask 0x3
+#define DSP32Alu_aopcde_bits 16
+#define DSP32Alu_aopcde_mask 0x1f
+#define DSP32Alu_HL_bits 21
+#define DSP32Alu_HL_mask 0x1
+#define DSP32Alu_dontcare_bits 22
+#define DSP32Alu_dontcare_mask 0x7
+#define DSP32Alu_code2_bits 25
+#define DSP32Alu_code2_mask 0x3
+#define DSP32Alu_M_bits 27
+#define DSP32Alu_M_mask 0x1
+#define DSP32Alu_code_bits 28
+#define DSP32Alu_code_mask 0xf
+
+#define init_DSP32Alu \
+{ \
+ DSP32Alu_opcode, \
+ DSP32Alu_src1_bits, DSP32Alu_src1_mask, \
+ DSP32Alu_src0_bits, DSP32Alu_src0_mask, \
+ DSP32Alu_dst1_bits, DSP32Alu_dst1_mask, \
+ DSP32Alu_dst0_bits, DSP32Alu_dst0_mask, \
+ DSP32Alu_x_bits, DSP32Alu_x_mask, \
+ DSP32Alu_s_bits, DSP32Alu_s_mask, \
+ DSP32Alu_aop_bits, DSP32Alu_aop_mask, \
+ DSP32Alu_aopcde_bits, DSP32Alu_aopcde_mask, \
+ DSP32Alu_HL_bits, DSP32Alu_HL_mask, \
+ DSP32Alu_dontcare_bits, DSP32Alu_dontcare_mask, \
+ DSP32Alu_code2_bits, DSP32Alu_code2_mask, \
+ DSP32Alu_M_bits, DSP32Alu_M_mask, \
+ DSP32Alu_code_bits, DSP32Alu_code_mask \
+};
+
+/* dsp32shift
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
+|.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_src1;
+ int mask_src1;
+ int bits_src0;
+ int mask_src0;
+ int bits_dst1;
+ int mask_dst1;
+ int bits_dst0;
+ int mask_dst0;
+ int bits_HLs;
+ int mask_HLs;
+ int bits_sop;
+ int mask_sop;
+ int bits_sopcde;
+ int mask_sopcde;
+ int bits_dontcare;
+ int mask_dontcare;
+ int bits_code2;
+ int mask_code2;
+ int bits_M;
+ int mask_M;
+ int bits_code;
+ int mask_code;
+} DSP32Shift;
+
+#define DSP32Shift_opcode 0xc6000000
+#define DSP32Shift_src1_bits 0
+#define DSP32Shift_src1_mask 0x7
+#define DSP32Shift_src0_bits 3
+#define DSP32Shift_src0_mask 0x7
+#define DSP32Shift_dst1_bits 6
+#define DSP32Shift_dst1_mask 0x7
+#define DSP32Shift_dst0_bits 9
+#define DSP32Shift_dst0_mask 0x7
+#define DSP32Shift_HLs_bits 12
+#define DSP32Shift_HLs_mask 0x3
+#define DSP32Shift_sop_bits 14
+#define DSP32Shift_sop_mask 0x3
+#define DSP32Shift_sopcde_bits 16
+#define DSP32Shift_sopcde_mask 0x1f
+#define DSP32Shift_dontcare_bits 21
+#define DSP32Shift_dontcare_mask 0x3
+#define DSP32Shift_code2_bits 23
+#define DSP32Shift_code2_mask 0xf
+#define DSP32Shift_M_bits 27
+#define DSP32Shift_M_mask 0x1
+#define DSP32Shift_code_bits 28
+#define DSP32Shift_code_mask 0xf
+
+#define init_DSP32Shift \
+{ \
+ DSP32Shift_opcode, \
+ DSP32Shift_src1_bits, DSP32Shift_src1_mask, \
+ DSP32Shift_src0_bits, DSP32Shift_src0_mask, \
+ DSP32Shift_dst1_bits, DSP32Shift_dst1_mask, \
+ DSP32Shift_dst0_bits, DSP32Shift_dst0_mask, \
+ DSP32Shift_HLs_bits, DSP32Shift_HLs_mask, \
+ DSP32Shift_sop_bits, DSP32Shift_sop_mask, \
+ DSP32Shift_sopcde_bits, DSP32Shift_sopcde_mask, \
+ DSP32Shift_dontcare_bits, DSP32Shift_dontcare_mask, \
+ DSP32Shift_code2_bits, DSP32Shift_code2_mask, \
+ DSP32Shift_M_bits, DSP32Shift_M_mask, \
+ DSP32Shift_code_bits, DSP32Shift_code_mask \
+};
+
+/* dsp32shiftimm
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
+|.sop...|.HLs...|.dst0......|.immag.................|.src1......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_src1;
+ int mask_src1;
+ int bits_immag;
+ int mask_immag;
+ int bits_dst0;
+ int mask_dst0;
+ int bits_HLs;
+ int mask_HLs;
+ int bits_sop;
+ int mask_sop;
+ int bits_sopcde;
+ int mask_sopcde;
+ int bits_dontcare;
+ int mask_dontcare;
+ int bits_code2;
+ int mask_code2;
+ int bits_M;
+ int mask_M;
+ int bits_code;
+ int mask_code;
+} DSP32ShiftImm;
+
+#define DSP32ShiftImm_opcode 0xc6800000
+#define DSP32ShiftImm_src1_bits 0
+#define DSP32ShiftImm_src1_mask 0x7
+#define DSP32ShiftImm_immag_bits 3
+#define DSP32ShiftImm_immag_mask 0x3f
+#define DSP32ShiftImm_dst0_bits 9
+#define DSP32ShiftImm_dst0_mask 0x7
+#define DSP32ShiftImm_HLs_bits 12
+#define DSP32ShiftImm_HLs_mask 0x3
+#define DSP32ShiftImm_sop_bits 14
+#define DSP32ShiftImm_sop_mask 0x3
+#define DSP32ShiftImm_sopcde_bits 16
+#define DSP32ShiftImm_sopcde_mask 0x1f
+#define DSP32ShiftImm_dontcare_bits 21
+#define DSP32ShiftImm_dontcare_mask 0x3
+#define DSP32ShiftImm_code2_bits 23
+#define DSP32ShiftImm_code2_mask 0xf
+#define DSP32ShiftImm_M_bits 27
+#define DSP32ShiftImm_M_mask 0x1
+#define DSP32ShiftImm_code_bits 28
+#define DSP32ShiftImm_code_mask 0xf
+
+#define init_DSP32ShiftImm \
+{ \
+ DSP32ShiftImm_opcode, \
+ DSP32ShiftImm_src1_bits, DSP32ShiftImm_src1_mask, \
+ DSP32ShiftImm_immag_bits, DSP32ShiftImm_immag_mask, \
+ DSP32ShiftImm_dst0_bits, DSP32ShiftImm_dst0_mask, \
+ DSP32ShiftImm_HLs_bits, DSP32ShiftImm_HLs_mask, \
+ DSP32ShiftImm_sop_bits, DSP32ShiftImm_sop_mask, \
+ DSP32ShiftImm_sopcde_bits, DSP32ShiftImm_sopcde_mask, \
+ DSP32ShiftImm_dontcare_bits, DSP32ShiftImm_dontcare_mask, \
+ DSP32ShiftImm_code2_bits, DSP32ShiftImm_code2_mask, \
+ DSP32ShiftImm_M_bits, DSP32ShiftImm_M_mask, \
+ DSP32ShiftImm_code_bits, DSP32ShiftImm_code_mask \
+};
+
+/* LOAD / STORE */
+
+/* LDSTidxI
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 0 | 0 | 1 |.W.|.Z.|.sz....|.ptr.......|.reg.......|
+|.offset........................................................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_offset;
+ int mask_offset;
+ int bits_reg;
+ int mask_reg;
+ int bits_ptr;
+ int mask_ptr;
+ int bits_sz;
+ int mask_sz;
+ int bits_Z;
+ int mask_Z;
+ int bits_W;
+ int mask_W;
+ int bits_code;
+ int mask_code;
+} LDSTidxI;
+
+#define LDSTidxI_opcode 0xe4000000
+#define LDSTidxI_offset_bits 0
+#define LDSTidxI_offset_mask 0xffff
+#define LDSTidxI_reg_bits 16
+#define LDSTidxI_reg_mask 0x7
+#define LDSTidxI_ptr_bits 19
+#define LDSTidxI_ptr_mask 0x7
+#define LDSTidxI_sz_bits 22
+#define LDSTidxI_sz_mask 0x3
+#define LDSTidxI_Z_bits 24
+#define LDSTidxI_Z_mask 0x1
+#define LDSTidxI_W_bits 25
+#define LDSTidxI_W_mask 0x1
+#define LDSTidxI_code_bits 26
+#define LDSTidxI_code_mask 0x3f
+
+#define init_LDSTidxI \
+{ \
+ LDSTidxI_opcode, \
+ LDSTidxI_offset_bits, LDSTidxI_offset_mask, \
+ LDSTidxI_reg_bits, LDSTidxI_reg_mask, \
+ LDSTidxI_ptr_bits, LDSTidxI_ptr_mask, \
+ LDSTidxI_sz_bits, LDSTidxI_sz_mask, \
+ LDSTidxI_Z_bits, LDSTidxI_Z_mask, \
+ LDSTidxI_W_bits, LDSTidxI_W_mask, \
+ LDSTidxI_code_bits, LDSTidxI_code_mask \
+};
+
+
+/* LDST
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_ptr;
+ int mask_ptr;
+ int bits_Z;
+ int mask_Z;
+ int bits_aop;
+ int mask_aop;
+ int bits_W;
+ int mask_W;
+ int bits_sz;
+ int mask_sz;
+ int bits_code;
+ int mask_code;
+} LDST;
+
+#define LDST_opcode 0x9000
+#define LDST_reg_bits 0
+#define LDST_reg_mask 0x7
+#define LDST_ptr_bits 3
+#define LDST_ptr_mask 0x7
+#define LDST_Z_bits 6
+#define LDST_Z_mask 0x1
+#define LDST_aop_bits 7
+#define LDST_aop_mask 0x3
+#define LDST_W_bits 9
+#define LDST_W_mask 0x1
+#define LDST_sz_bits 10
+#define LDST_sz_mask 0x3
+#define LDST_code_bits 12
+#define LDST_code_mask 0xf
+
+#define init_LDST \
+{ \
+ LDST_opcode, \
+ LDST_reg_bits, LDST_reg_mask, \
+ LDST_ptr_bits, LDST_ptr_mask, \
+ LDST_Z_bits, LDST_Z_mask, \
+ LDST_aop_bits, LDST_aop_mask, \
+ LDST_W_bits, LDST_W_mask, \
+ LDST_sz_bits, LDST_sz_mask, \
+ LDST_code_bits, LDST_code_mask \
+};
+
+/* LDSTii
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_ptr;
+ int mask_ptr;
+ int bits_offset;
+ int mask_offset;
+ int bits_op;
+ int mask_op;
+ int bits_W;
+ int mask_W;
+ int bits_code;
+ int mask_code;
+} LDSTii;
+
+#define LDSTii_opcode 0xa000
+#define LDSTii_reg_bit 0
+#define LDSTii_reg_mask 0x7
+#define LDSTii_ptr_bit 3
+#define LDSTii_ptr_mask 0x7
+#define LDSTii_offset_bit 6
+#define LDSTii_offset_mask 0xf
+#define LDSTii_op_bit 10
+#define LDSTii_op_mask 0x3
+#define LDSTii_W_bit 12
+#define LDSTii_W_mask 0x1
+#define LDSTii_code_bit 13
+#define LDSTii_code_mask 0x7
+
+#define init_LDSTii \
+{ \
+ LDSTii_opcode, \
+ LDSTii_reg_bit, LDSTii_reg_mask, \
+ LDSTii_ptr_bit, LDSTii_ptr_mask, \
+ LDSTii_offset_bit, LDSTii_offset_mask, \
+ LDSTii_op_bit, LDSTii_op_mask, \
+ LDSTii_W_bit, LDSTii_W_mask, \
+ LDSTii_code_bit, LDSTii_code_mask \
+};
+
+
+/* LDSTiiFP
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_offset;
+ int mask_offset;
+ int bits_W;
+ int mask_W;
+ int bits_code;
+ int mask_code;
+} LDSTiiFP;
+
+#define LDSTiiFP_opcode 0xb800
+#define LDSTiiFP_reg_bits 0
+#define LDSTiiFP_reg_mask 0xf
+#define LDSTiiFP_offset_bits 4
+#define LDSTiiFP_offset_mask 0x1f
+#define LDSTiiFP_W_bits 9
+#define LDSTiiFP_W_mask 0x1
+#define LDSTiiFP_code_bits 10
+#define LDSTiiFP_code_mask 0x3f
+
+#define init_LDSTiiFP \
+{ \
+ LDSTiiFP_opcode, \
+ LDSTiiFP_reg_bits, LDSTiiFP_reg_mask, \
+ LDSTiiFP_offset_bits, LDSTiiFP_offset_mask, \
+ LDSTiiFP_W_bits, LDSTiiFP_W_mask, \
+ LDSTiiFP_code_bits, LDSTiiFP_code_mask \
+};
+
+/* dspLDST
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_i;
+ int mask_i;
+ int bits_m;
+ int mask_m;
+ int bits_aop;
+ int mask_aop;
+ int bits_W;
+ int mask_W;
+ int bits_code;
+ int mask_code;
+} DspLDST;
+
+#define DspLDST_opcode 0x9c00
+#define DspLDST_reg_bits 0
+#define DspLDST_reg_mask 0x7
+#define DspLDST_i_bits 3
+#define DspLDST_i_mask 0x3
+#define DspLDST_m_bits 5
+#define DspLDST_m_mask 0x3
+#define DspLDST_aop_bits 7
+#define DspLDST_aop_mask 0x3
+#define DspLDST_W_bits 9
+#define DspLDST_W_mask 0x1
+#define DspLDST_code_bits 10
+#define DspLDST_code_mask 0x3f
+
+#define init_DspLDST \
+{ \
+ DspLDST_opcode, \
+ DspLDST_reg_bits, DspLDST_reg_mask, \
+ DspLDST_i_bits, DspLDST_i_mask, \
+ DspLDST_m_bits, DspLDST_m_mask, \
+ DspLDST_aop_bits, DspLDST_aop_mask, \
+ DspLDST_W_bits, DspLDST_W_mask, \
+ DspLDST_code_bits, DspLDST_code_mask \
+};
+
+
+/* LDSTpmod
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_ptr;
+ int mask_ptr;
+ int bits_idx;
+ int mask_idx;
+ int bits_reg;
+ int mask_reg;
+ int bits_aop;
+ int mask_aop;
+ int bits_W;
+ int mask_W;
+ int bits_code;
+ int mask_code;
+} LDSTpmod;
+
+#define LDSTpmod_opcode 0x8000
+#define LDSTpmod_ptr_bits 0
+#define LDSTpmod_ptr_mask 0x7
+#define LDSTpmod_idx_bits 3
+#define LDSTpmod_idx_mask 0x7
+#define LDSTpmod_reg_bits 6
+#define LDSTpmod_reg_mask 0x7
+#define LDSTpmod_aop_bits 9
+#define LDSTpmod_aop_mask 0x3
+#define LDSTpmod_W_bits 11
+#define LDSTpmod_W_mask 0x1
+#define LDSTpmod_code_bits 12
+#define LDSTpmod_code_mask 0xf
+
+#define init_LDSTpmod \
+{ \
+ LDSTpmod_opcode, \
+ LDSTpmod_ptr_bits, LDSTpmod_ptr_mask, \
+ LDSTpmod_idx_bits, LDSTpmod_idx_mask, \
+ LDSTpmod_reg_bits, LDSTpmod_reg_mask, \
+ LDSTpmod_aop_bits, LDSTpmod_aop_mask, \
+ LDSTpmod_W_bits, LDSTpmod_W_mask, \
+ LDSTpmod_code_bits, LDSTpmod_code_mask \
+};
+
+
+/* LOGI2op
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 1 | 0 | 0 | 1 |.opc.......|.src...............|.dst.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_dst;
+ int mask_dst;
+ int bits_src;
+ int mask_src;
+ int bits_opc;
+ int mask_opc;
+ int bits_code;
+ int mask_code;
+} LOGI2op;
+
+#define LOGI2op_opcode 0x4800
+#define LOGI2op_dst_bits 0
+#define LOGI2op_dst_mask 0x7
+#define LOGI2op_src_bits 3
+#define LOGI2op_src_mask 0x1f
+#define LOGI2op_opc_bits 8
+#define LOGI2op_opc_mask 0x7
+#define LOGI2op_code_bits 11
+#define LOGI2op_code_mask 0x1f
+
+#define init_LOGI2op \
+{ \
+ LOGI2op_opcode, \
+ LOGI2op_dst_bits, LOGI2op_dst_mask, \
+ LOGI2op_src_bits, LOGI2op_src_mask, \
+ LOGI2op_opc_bits, LOGI2op_opc_mask, \
+ LOGI2op_code_bits, LOGI2op_code_mask \
+};
+
+
+/* ALU2op
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_dst;
+ int mask_dst;
+ int bits_src;
+ int mask_src;
+ int bits_opc;
+ int mask_opc;
+ int bits_code;
+ int mask_code;
+} ALU2op;
+
+#define ALU2op_opcode 0x4000
+#define ALU2op_dst_bits 0
+#define ALU2op_dst_mask 0x7
+#define ALU2op_src_bits 3
+#define ALU2op_src_mask 0x7
+#define ALU2op_opc_bits 6
+#define ALU2op_opc_mask 0xf
+#define ALU2op_code_bits 10
+#define ALU2op_code_mask 0x3f
+
+#define init_ALU2op \
+{ \
+ ALU2op_opcode, \
+ ALU2op_dst_bits, ALU2op_dst_mask, \
+ ALU2op_src_bits, ALU2op_src_mask, \
+ ALU2op_opc_bits, ALU2op_opc_mask, \
+ ALU2op_code_bits, ALU2op_code_mask \
+};
+
+
+/* BRCC
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 1 |.T.|.B.|.offset................................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_offset;
+ int mask_offset;
+ int bits_B;
+ int mask_B;
+ int bits_T;
+ int mask_T;
+ int bits_code;
+ int mask_code;
+} BRCC;
+
+#define BRCC_opcode 0x1000
+#define BRCC_offset_bits 0
+#define BRCC_offset_mask 0x3ff
+#define BRCC_B_bits 10
+#define BRCC_B_mask 0x1
+#define BRCC_T_bits 11
+#define BRCC_T_mask 0x1
+#define BRCC_code_bits 12
+#define BRCC_code_mask 0xf
+
+#define init_BRCC \
+{ \
+ BRCC_opcode, \
+ BRCC_offset_bits, BRCC_offset_mask, \
+ BRCC_B_bits, BRCC_B_mask, \
+ BRCC_T_bits, BRCC_T_mask, \
+ BRCC_code_bits, BRCC_code_mask \
+};
+
+
+/* UJUMP
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 1 | 0 |.offset........................................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_offset;
+ int mask_offset;
+ int bits_code;
+ int mask_code;
+} UJump;
+
+#define UJump_opcode 0x2000
+#define UJump_offset_bits 0
+#define UJump_offset_mask 0xfff
+#define UJump_code_bits 12
+#define UJump_code_mask 0xf
+
+#define init_UJump \
+{ \
+ UJump_opcode, \
+ UJump_offset_bits, UJump_offset_mask, \
+ UJump_code_bits, UJump_code_mask \
+};
+
+
+/* ProgCtrl
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.prgfunc.......|.poprnd........|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_poprnd;
+ int mask_poprnd;
+ int bits_prgfunc;
+ int mask_prgfunc;
+ int bits_code;
+ int mask_code;
+} ProgCtrl;
+
+#define ProgCtrl_opcode 0x0000
+#define ProgCtrl_poprnd_bits 0
+#define ProgCtrl_poprnd_mask 0xf
+#define ProgCtrl_prgfunc_bits 4
+#define ProgCtrl_prgfunc_mask 0xf
+#define ProgCtrl_code_bits 8
+#define ProgCtrl_code_mask 0xff
+
+#define init_ProgCtrl \
+{ \
+ ProgCtrl_opcode, \
+ ProgCtrl_poprnd_bits, ProgCtrl_poprnd_mask, \
+ ProgCtrl_prgfunc_bits, ProgCtrl_prgfunc_mask, \
+ ProgCtrl_code_bits, ProgCtrl_code_mask \
+};
+
+/* CALLa
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 0 | 0 | 0 | 1 |.S.|.msw...........................|
+|.lsw...........................................................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_addr;
+ int mask_addr;
+ int bits_S;
+ int mask_S;
+ int bits_code;
+ int mask_code;
+} CALLa;
+
+#define CALLa_opcode 0xe2000000
+#define CALLa_addr_bits 0
+#define CALLa_addr_mask 0xffffff
+#define CALLa_S_bits 24
+#define CALLa_S_mask 0x1
+#define CALLa_code_bits 25
+#define CALLa_code_mask 0x7f
+
+#define init_CALLa \
+{ \
+ CALLa_opcode, \
+ CALLa_addr_bits, CALLa_addr_mask, \
+ CALLa_S_bits, CALLa_S_mask, \
+ CALLa_code_bits, CALLa_code_mask \
+};
+
+
+/* pseudoDEBUG
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |.fn....|.grp.......|.reg.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_grp;
+ int mask_grp;
+ int bits_fn;
+ int mask_fn;
+ int bits_code;
+ int mask_code;
+} PseudoDbg;
+
+#define PseudoDbg_opcode 0xf800
+#define PseudoDbg_reg_bits 0
+#define PseudoDbg_reg_mask 0x7
+#define PseudoDbg_grp_bits 3
+#define PseudoDbg_grp_mask 0x7
+#define PseudoDbg_fn_bits 6
+#define PseudoDbg_fn_mask 0x3
+#define PseudoDbg_code_bits 8
+#define PseudoDbg_code_mask 0xff
+
+#define init_PseudoDbg \
+{ \
+ PseudoDbg_opcode, \
+ PseudoDbg_reg_bits, PseudoDbg_reg_mask, \
+ PseudoDbg_grp_bits, PseudoDbg_grp_mask, \
+ PseudoDbg_fn_bits, PseudoDbg_fn_mask, \
+ PseudoDbg_code_bits, PseudoDbg_code_mask \
+};
+
+/* PseudoDbg_assert
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 1 | 0 | - | - | - | dbgop |.grp.......|.regtest...|
+|.expected......................................................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_expected;
+ int mask_expected;
+ int bits_regtest;
+ int mask_regtest;
+ int bits_grp;
+ int mask_grp;
+ int bits_dbgop;
+ int mask_dbgop;
+ int bits_dontcare;
+ int mask_dontcare;
+ int bits_code;
+ int mask_code;
+} PseudoDbg_Assert;
+
+#define PseudoDbg_Assert_opcode 0xf0000000
+#define PseudoDbg_Assert_expected_bits 0
+#define PseudoDbg_Assert_expected_mask 0xffff
+#define PseudoDbg_Assert_regtest_bits 16
+#define PseudoDbg_Assert_regtest_mask 0x7
+#define PseudoDbg_Assert_grp_bits 19
+#define PseudoDbg_Assert_grp_mask 0x7
+#define PseudoDbg_Assert_dbgop_bits 22
+#define PseudoDbg_Assert_dbgop_mask 0x3
+#define PseudoDbg_Assert_dontcare_bits 24
+#define PseudoDbg_Assert_dontcare_mask 0x7
+#define PseudoDbg_Assert_code_bits 27
+#define PseudoDbg_Assert_code_mask 0x1f
+
+#define init_PseudoDbg_Assert \
+{ \
+ PseudoDbg_Assert_opcode, \
+ PseudoDbg_Assert_expected_bits, PseudoDbg_Assert_expected_mask, \
+ PseudoDbg_Assert_regtest_bits, PseudoDbg_Assert_regtest_mask, \
+ PseudoDbg_Assert_grp_bits, PseudoDbg_Assert_grp_mask, \
+ PseudoDbg_Assert_dbgop_bits, PseudoDbg_Assert_dbgop_mask, \
+ PseudoDbg_Assert_dontcare_bits, PseudoDbg_Assert_dontcare_mask, \
+ PseudoDbg_Assert_code_bits, PseudoDbg_Assert_code_mask \
+};
+
+/* pseudoChr
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_ch;
+ int mask_ch;
+ int bits_code;
+ int mask_code;
+} PseudoChr;
+
+#define PseudoChr_opcode 0xf900
+#define PseudoChr_ch_bits 0
+#define PseudoChr_ch_mask 0xff
+#define PseudoChr_code_bits 8
+#define PseudoChr_code_mask 0xff
+
+#define init_PseudoChr \
+{ \
+ PseudoChr_opcode, \
+ PseudoChr_ch_bits, PseudoChr_ch_mask, \
+ PseudoChr_code_bits, PseudoChr_code_mask \
+};
+
+/* CaCTRL
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_op;
+ int mask_op;
+ int bits_a;
+ int mask_a;
+ int bits_code;
+ int mask_code;
+} CaCTRL;
+
+#define CaCTRL_opcode 0x0240
+#define CaCTRL_reg_bits 0
+#define CaCTRL_reg_mask 0x7
+#define CaCTRL_op_bits 3
+#define CaCTRL_op_mask 0x3
+#define CaCTRL_a_bits 5
+#define CaCTRL_a_mask 0x1
+#define CaCTRL_code_bits 6
+#define CaCTRL_code_mask 0x3fff
+
+#define init_CaCTRL \
+{ \
+ CaCTRL_opcode, \
+ CaCTRL_reg_bits, CaCTRL_reg_mask, \
+ CaCTRL_op_bits, CaCTRL_op_mask, \
+ CaCTRL_a_bits, CaCTRL_a_mask, \
+ CaCTRL_code_bits, CaCTRL_code_mask \
+};
+
+/* PushPopMultiple
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 0 | 1 | 0 |.d.|.p.|.W.|.dr........|.pr........|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_pr;
+ int mask_pr;
+ int bits_dr;
+ int mask_dr;
+ int bits_W;
+ int mask_W;
+ int bits_p;
+ int mask_p;
+ int bits_d;
+ int mask_d;
+ int bits_code;
+ int mask_code;
+} PushPopMultiple;
+
+#define PushPopMultiple_opcode 0x0400
+#define PushPopMultiple_pr_bits 0
+#define PushPopMultiple_pr_mask 0x7
+#define PushPopMultiple_dr_bits 3
+#define PushPopMultiple_dr_mask 0x7
+#define PushPopMultiple_W_bits 6
+#define PushPopMultiple_W_mask 0x1
+#define PushPopMultiple_p_bits 7
+#define PushPopMultiple_p_mask 0x1
+#define PushPopMultiple_d_bits 8
+#define PushPopMultiple_d_mask 0x1
+#define PushPopMultiple_code_bits 8
+#define PushPopMultiple_code_mask 0x1
+
+#define init_PushPopMultiple \
+{ \
+ PushPopMultiple_opcode, \
+ PushPopMultiple_pr_bits, PushPopMultiple_pr_mask, \
+ PushPopMultiple_dr_bits, PushPopMultiple_dr_mask, \
+ PushPopMultiple_W_bits, PushPopMultiple_W_mask, \
+ PushPopMultiple_p_bits, PushPopMultiple_p_mask, \
+ PushPopMultiple_d_bits, PushPopMultiple_d_mask, \
+ PushPopMultiple_code_bits, PushPopMultiple_code_mask \
+};
+
+/* PushPopReg
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.W.|.grp.......|.reg.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_grp;
+ int mask_grp;
+ int bits_W;
+ int mask_W;
+ int bits_code;
+ int mask_code;
+} PushPopReg;
+
+#define PushPopReg_opcode 0x0100
+#define PushPopReg_reg_bits 0
+#define PushPopReg_reg_mask 0x7
+#define PushPopReg_grp_bits 3
+#define PushPopReg_grp_mask 0x7
+#define PushPopReg_W_bits 6
+#define PushPopReg_W_mask 0x1
+#define PushPopReg_code_bits 7
+#define PushPopReg_code_mask 0x1ff
+
+#define init_PushPopReg \
+{ \
+ PushPopReg_opcode, \
+ PushPopReg_reg_bits, PushPopReg_reg_mask, \
+ PushPopReg_grp_bits, PushPopReg_grp_mask, \
+ PushPopReg_W_bits, PushPopReg_W_mask, \
+ PushPopReg_code_bits, PushPopReg_code_mask, \
+};
+
+/* linkage
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.R.|
+|.framesize.....................................................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_framesize;
+ int mask_framesize;
+ int bits_R;
+ int mask_R;
+ int bits_code;
+ int mask_code;
+} Linkage;
+
+#define Linkage_opcode 0xe8000000
+#define Linkage_framesize_bits 0
+#define Linkage_framesize_mask 0xffff
+#define Linkage_R_bits 16
+#define Linkage_R_mask 0x1
+#define Linkage_code_bits 17
+#define Linkage_code_mask 0x7fff
+
+#define init_Linkage \
+{ \
+ Linkage_opcode, \
+ Linkage_framesize_bits, Linkage_framesize_mask, \
+ Linkage_R_bits, Linkage_R_mask, \
+ Linkage_code_bits, Linkage_code_mask \
+};
+
+/* LoopSetup
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |.rop...|.c.|.soffset.......|
+|.reg...........| - | - |.eoffset...............................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_eoffset;
+ int mask_eoffset;
+ int bits_dontcare;
+ int mask_dontcare;
+ int bits_reg;
+ int mask_reg;
+ int bits_soffset;
+ int mask_soffset;
+ int bits_c;
+ int mask_c;
+ int bits_rop;
+ int mask_rop;
+ int bits_code;
+ int mask_code;
+} LoopSetup;
+
+#define LoopSetup_opcode 0xe0800000
+#define LoopSetup_eoffset_bits 0
+#define LoopSetup_eoffset_mask 0x3ff
+#define LoopSetup_dontcare_bits 10
+#define LoopSetup_dontcare_mask 0x3
+#define LoopSetup_reg_bits 12
+#define LoopSetup_reg_mask 0xf
+#define LoopSetup_soffset_bits 16
+#define LoopSetup_soffset_mask 0xf
+#define LoopSetup_c_bits 20
+#define LoopSetup_c_mask 0x1
+#define LoopSetup_rop_bits 21
+#define LoopSetup_rop_mask 0x3
+#define LoopSetup_code_bits 23
+#define LoopSetup_code_mask 0x1ff
+
+#define init_LoopSetup \
+{ \
+ LoopSetup_opcode, \
+ LoopSetup_eoffset_bits, LoopSetup_eoffset_mask, \
+ LoopSetup_dontcare_bits, LoopSetup_dontcare_mask, \
+ LoopSetup_reg_bits, LoopSetup_reg_mask, \
+ LoopSetup_soffset_bits, LoopSetup_soffset_mask, \
+ LoopSetup_c_bits, LoopSetup_c_mask, \
+ LoopSetup_rop_bits, LoopSetup_rop_mask, \
+ LoopSetup_code_bits, LoopSetup_code_mask \
+};
+
+/* LDIMMhalf
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |.Z.|.H.|.S.|.grp...|.reg.......|
+|.hword.........................................................|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned long opcode;
+ int bits_hword;
+ int mask_hword;
+ int bits_reg;
+ int mask_reg;
+ int bits_grp;
+ int mask_grp;
+ int bits_S;
+ int mask_S;
+ int bits_H;
+ int mask_H;
+ int bits_Z;
+ int mask_Z;
+ int bits_code;
+ int mask_code;
+} LDIMMhalf;
+
+#define LDIMMhalf_opcode 0xe1000000
+#define LDIMMhalf_hword_bits 0
+#define LDIMMhalf_hword_mask 0xffff
+#define LDIMMhalf_reg_bits 16
+#define LDIMMhalf_reg_mask 0x7
+#define LDIMMhalf_grp_bits 19
+#define LDIMMhalf_grp_mask 0x3
+#define LDIMMhalf_S_bits 21
+#define LDIMMhalf_S_mask 0x1
+#define LDIMMhalf_H_bits 22
+#define LDIMMhalf_H_mask 0x1
+#define LDIMMhalf_Z_bits 23
+#define LDIMMhalf_Z_mask 0x1
+#define LDIMMhalf_code_bits 24
+#define LDIMMhalf_code_mask 0xff
+
+#define init_LDIMMhalf \
+{ \
+ LDIMMhalf_opcode, \
+ LDIMMhalf_hword_bits, LDIMMhalf_hword_mask, \
+ LDIMMhalf_reg_bits, LDIMMhalf_reg_mask, \
+ LDIMMhalf_grp_bits, LDIMMhalf_grp_mask, \
+ LDIMMhalf_S_bits, LDIMMhalf_S_mask, \
+ LDIMMhalf_H_bits, LDIMMhalf_H_mask, \
+ LDIMMhalf_Z_bits, LDIMMhalf_Z_mask, \
+ LDIMMhalf_code_bits, LDIMMhalf_code_mask \
+};
+
+
+/* CC2dreg
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_reg;
+ int mask_reg;
+ int bits_op;
+ int mask_op;
+ int bits_code;
+ int mask_code;
+} CC2dreg;
+
+#define CC2dreg_opcode 0x0200
+#define CC2dreg_reg_bits 0
+#define CC2dreg_reg_mask 0x7
+#define CC2dreg_op_bits 3
+#define CC2dreg_op_mask 0x3
+#define CC2dreg_code_bits 5
+#define CC2dreg_code_mask 0x7fff
+
+#define init_CC2dreg \
+{ \
+ CC2dreg_opcode, \
+ CC2dreg_reg_bits, CC2dreg_reg_mask, \
+ CC2dreg_op_bits, CC2dreg_op_mask, \
+ CC2dreg_code_bits, CC2dreg_code_mask \
+};
+
+
+/* PTR2op
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 1 | 0 | 0 | 0 | 1 | 0 |.opc.......|.src.......|.dst.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_dst;
+ int mask_dst;
+ int bits_src;
+ int mask_src;
+ int bits_opc;
+ int mask_opc;
+ int bits_code;
+ int mask_code;
+} PTR2op;
+
+#define PTR2op_opcode 0x4400
+#define PTR2op_dst_bits 0
+#define PTR2op_dst_mask 0x7
+#define PTR2op_src_bits 3
+#define PTR2op_src_mask 0x7
+#define PTR2op_opc_bits 6
+#define PTR2op_opc_mask 0x7
+#define PTR2op_code_bits 9
+#define PTR2op_code_mask 0x7f
+
+#define init_PTR2op \
+{ \
+ PTR2op_opcode, \
+ PTR2op_dst_bits, PTR2op_dst_mask, \
+ PTR2op_src_bits, PTR2op_src_mask, \
+ PTR2op_opc_bits, PTR2op_opc_mask, \
+ PTR2op_code_bits, PTR2op_code_mask \
+};
+
+
+/* COMP3op
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_src0;
+ int mask_src0;
+ int bits_src1;
+ int mask_src1;
+ int bits_dst;
+ int mask_dst;
+ int bits_opc;
+ int mask_opc;
+ int bits_code;
+ int mask_code;
+} COMP3op;
+
+#define COMP3op_opcode 0x5000
+#define COMP3op_src0_bits 0
+#define COMP3op_src0_mask 0x7
+#define COMP3op_src1_bits 3
+#define COMP3op_src1_mask 0x7
+#define COMP3op_dst_bits 6
+#define COMP3op_dst_mask 0x7
+#define COMP3op_opc_bits 9
+#define COMP3op_opc_mask 0x7
+#define COMP3op_code_bits 12
+#define COMP3op_code_mask 0xf
+
+#define init_COMP3op \
+{ \
+ COMP3op_opcode, \
+ COMP3op_src0_bits, COMP3op_src0_mask, \
+ COMP3op_src1_bits, COMP3op_src1_mask, \
+ COMP3op_dst_bits, COMP3op_dst_mask, \
+ COMP3op_opc_bits, COMP3op_opc_mask, \
+ COMP3op_code_bits, COMP3op_code_mask \
+};
+
+/* ccMV
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 0 | 1 | 1 |.T.|.d.|.s.|.dst.......|.src.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_src;
+ int mask_src;
+ int bits_dst;
+ int mask_dst;
+ int bits_s;
+ int mask_s;
+ int bits_d;
+ int mask_d;
+ int bits_T;
+ int mask_T;
+ int bits_code;
+ int mask_code;
+} CCmv;
+
+#define CCmv_opcode 0x0600
+#define CCmv_src_bits 0
+#define CCmv_src_mask 0x7
+#define CCmv_dst_bits 3
+#define CCmv_dst_mask 0x7
+#define CCmv_s_bits 6
+#define CCmv_s_mask 0x1
+#define CCmv_d_bits 7
+#define CCmv_d_mask 0x1
+#define CCmv_T_bits 8
+#define CCmv_T_mask 0x1
+#define CCmv_code_bits 9
+#define CCmv_code_mask 0x7f
+
+#define init_CCmv \
+{ \
+ CCmv_opcode, \
+ CCmv_src_bits, CCmv_src_mask, \
+ CCmv_dst_bits, CCmv_dst_mask, \
+ CCmv_s_bits, CCmv_s_mask, \
+ CCmv_d_bits, CCmv_d_mask, \
+ CCmv_T_bits, CCmv_T_mask, \
+ CCmv_code_bits, CCmv_code_mask \
+};
+
+
+/* CCflag
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 1 |.I.|.opc.......|.G.|.y.........|.x.........|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_x;
+ int mask_x;
+ int bits_y;
+ int mask_y;
+ int bits_G;
+ int mask_G;
+ int bits_opc;
+ int mask_opc;
+ int bits_I;
+ int mask_I;
+ int bits_code;
+ int mask_code;
+} CCflag;
+
+#define CCflag_opcode 0x0800
+#define CCflag_x_bits 0
+#define CCflag_x_mask 0x7
+#define CCflag_y_bits 3
+#define CCflag_y_mask 0x7
+#define CCflag_G_bits 6
+#define CCflag_G_mask 0x1
+#define CCflag_opc_bits 7
+#define CCflag_opc_mask 0x7
+#define CCflag_I_bits 10
+#define CCflag_I_mask 0x1
+#define CCflag_code_bits 11
+#define CCflag_code_mask 0x1f
+
+#define init_CCflag \
+{ \
+ CCflag_opcode, \
+ CCflag_x_bits, CCflag_x_mask, \
+ CCflag_y_bits, CCflag_y_mask, \
+ CCflag_G_bits, CCflag_G_mask, \
+ CCflag_opc_bits, CCflag_opc_mask, \
+ CCflag_I_bits, CCflag_I_mask, \
+ CCflag_code_bits, CCflag_code_mask, \
+};
+
+
+/* CC2stat
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_cbit;
+ int mask_cbit;
+ int bits_op;
+ int mask_op;
+ int bits_D;
+ int mask_D;
+ int bits_code;
+ int mask_code;
+} CC2stat;
+
+#define CC2stat_opcode 0x0300
+#define CC2stat_cbit_bits 0
+#define CC2stat_cbit_mask 0x1f
+#define CC2stat_op_bits 5
+#define CC2stat_op_mask 0x3
+#define CC2stat_D_bits 7
+#define CC2stat_D_mask 0x1
+#define CC2stat_code_bits 8
+#define CC2stat_code_mask 0xff
+
+#define init_CC2stat \
+{ \
+ CC2stat_opcode, \
+ CC2stat_cbit_bits, CC2stat_cbit_mask, \
+ CC2stat_op_bits, CC2stat_op_mask, \
+ CC2stat_D_bits, CC2stat_D_mask, \
+ CC2stat_code_bits, CC2stat_code_mask \
+};
+
+
+/* REGMV
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 0 | 1 | 1 |.gd........|.gs........|.dst.......|.src.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_src;
+ int mask_src;
+ int bits_dst;
+ int mask_dst;
+ int bits_gs;
+ int mask_gs;
+ int bits_gd;
+ int mask_gd;
+ int bits_code;
+ int mask_code;
+} RegMv;
+
+#define RegMv_opcode 0x3000
+#define RegMv_src_bits 0
+#define RegMv_src_mask 0x7
+#define RegMv_dst_bits 3
+#define RegMv_dst_mask 0x7
+#define RegMv_gs_bits 6
+#define RegMv_gs_mask 0x7
+#define RegMv_gd_bits 9
+#define RegMv_gd_mask 0x7
+#define RegMv_code_bits 12
+#define RegMv_code_mask 0xf
+
+#define init_RegMv \
+{ \
+ RegMv_opcode, \
+ RegMv_src_bits, RegMv_src_mask, \
+ RegMv_dst_bits, RegMv_dst_mask, \
+ RegMv_gs_bits, RegMv_gs_mask, \
+ RegMv_gd_bits, RegMv_gd_mask, \
+ RegMv_code_bits, RegMv_code_mask \
+};
+
+
+/* COMPI2opD
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 1 | 1 | 0 | 0 |.op|.isrc......................|.dst.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_dst;
+ int mask_dst;
+ int bits_src;
+ int mask_src;
+ int bits_op;
+ int mask_op;
+ int bits_code;
+ int mask_code;
+} COMPI2opD;
+
+#define COMPI2opD_opcode 0x6000
+#define COMPI2opD_dst_bits 0
+#define COMPI2opD_dst_mask 0x7
+#define COMPI2opD_src_bits 3
+#define COMPI2opD_src_mask 0x7f
+#define COMPI2opD_op_bits 10
+#define COMPI2opD_op_mask 0x1
+#define COMPI2opD_code_bits 11
+#define COMPI2opD_code_mask 0x1f
+
+#define init_COMPI2opD \
+{ \
+ COMPI2opD_opcode, \
+ COMPI2opD_dst_bits, COMPI2opD_dst_mask, \
+ COMPI2opD_src_bits, COMPI2opD_src_mask, \
+ COMPI2opD_op_bits, COMPI2opD_op_mask, \
+ COMPI2opD_code_bits, COMPI2opD_code_mask \
+};
+
+/* COMPI2opP
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef COMPI2opD COMPI2opP;
+
+#define COMPI2opP_opcode 0x6800
+#define COMPI2opP_dst_bits 0
+#define COMPI2opP_dst_mask 0x7
+#define COMPI2opP_src_bits 3
+#define COMPI2opP_src_mask 0x7f
+#define COMPI2opP_op_bits 10
+#define COMPI2opP_op_mask 0x1
+#define COMPI2opP_code_bits 11
+#define COMPI2opP_code_mask 0x1f
+
+#define init_COMPI2opP \
+{ \
+ COMPI2opP_opcode, \
+ COMPI2opP_dst_bits, COMPI2opP_dst_mask, \
+ COMPI2opP_src_bits, COMPI2opP_src_mask, \
+ COMPI2opP_op_bits, COMPI2opP_op_mask, \
+ COMPI2opP_code_bits, COMPI2opP_code_mask \
+};
+
+
+/* dagMODim
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_i;
+ int mask_i;
+ int bits_m;
+ int mask_m;
+ int bits_op;
+ int mask_op;
+ int bits_code2;
+ int mask_code2;
+ int bits_br;
+ int mask_br;
+ int bits_code;
+ int mask_code;
+} DagMODim;
+
+#define DagMODim_opcode 0x9e60
+#define DagMODim_i_bits 0
+#define DagMODim_i_mask 0x3
+#define DagMODim_m_bits 2
+#define DagMODim_m_mask 0x3
+#define DagMODim_op_bits 4
+#define DagMODim_op_mask 0x1
+#define DagMODim_code2_bits 5
+#define DagMODim_code2_mask 0x3
+#define DagMODim_br_bits 7
+#define DagMODim_br_mask 0x1
+#define DagMODim_code_bits 8
+#define DagMODim_code_mask 0xff
+
+#define init_DagMODim \
+{ \
+ DagMODim_opcode, \
+ DagMODim_i_bits, DagMODim_i_mask, \
+ DagMODim_m_bits, DagMODim_m_mask, \
+ DagMODim_op_bits, DagMODim_op_mask, \
+ DagMODim_code2_bits, DagMODim_code2_mask, \
+ DagMODim_br_bits, DagMODim_br_mask, \
+ DagMODim_code_bits, DagMODim_code_mask \
+};
+
+/* dagMODik
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+| 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
++---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+*/
+
+typedef struct
+{
+ unsigned short opcode;
+ int bits_i;
+ int mask_i;
+ int bits_op;
+ int mask_op;
+ int bits_code;
+ int mask_code;
+} DagMODik;
+
+#define DagMODik_opcode 0x9f60
+#define DagMODik_i_bits 0
+#define DagMODik_i_mask 0x3
+#define DagMODik_op_bits 2
+#define DagMODik_op_mask 0x3
+#define DagMODik_code_bits 3
+#define DagMODik_code_mask 0xfff
+
+#define init_DagMODik \
+{ \
+ DagMODik_opcode, \
+ DagMODik_i_bits, DagMODik_i_mask, \
+ DagMODik_op_bits, DagMODik_op_mask, \
+ DagMODik_code_bits, DagMODik_code_mask \
+};
+
+#endif
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 2/5] Blackfin: initial port
2013-06-17 7:13 [Qemu-devel] [PATCH 0/5] Initial Blackfin support (linux-user only) Mike Frysinger
2013-06-17 7:13 ` [Qemu-devel] [PATCH 1/5] Blackfin: add disassembler support Mike Frysinger
@ 2013-06-17 7:16 ` Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support Mike Frysinger
` (5 more replies)
1 sibling, 6 replies; 10+ messages in thread
From: Mike Frysinger @ 2013-06-17 7:16 UTC (permalink / raw)
To: qemu-devel
This is the core Blackfin support. While most things work that gcc will
generate, there are notable things missing at this point:
- many dsp/alu/mac insns not supported
- no saturation support
- many astat flags not updated
- probably other stuff
Details as to what is missing "by design" vs "not done due to laziness"
can be sorted out in the Blackfin README/TODO files.
FLAT and FDPIC ELFs however seem to work nicely, as do random samplings of
apps from a typical build.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
MAINTAINERS | 5 +
configure | 4 +
cpu-exec.c | 5 +-
gdbstub.c | 103 ++
include/elf.h | 6 +
qapi-schema.json | 9 +-
scripts/qemu-binfmt-conf.sh | 4 +
target-bfin/Makefile.objs | 3 +
target-bfin/README | 32 +
target-bfin/TODO | 25 +
target-bfin/bfin-sim.c | 3666 ++++++++++++++++++++++++++++++++++++++++
target-bfin/bfin-tdep.h | 94 ++
target-bfin/cpu-qom.h | 61 +
target-bfin/cpu.c | 55 +
target-bfin/cpu.h | 236 +++
target-bfin/helper.c | 37 +
target-bfin/helper.h | 23 +
target-bfin/linux-fixed-code.h | 23 +
target-bfin/op_helper.c | 229 +++
target-bfin/translate.c | 1347 +++++++++++++++
20 files changed, 5962 insertions(+), 5 deletions(-)
create mode 100644 target-bfin/Makefile.objs
create mode 100644 target-bfin/README
create mode 100644 target-bfin/TODO
create mode 100644 target-bfin/bfin-sim.c
create mode 100644 target-bfin/bfin-tdep.h
create mode 100644 target-bfin/cpu-qom.h
create mode 100644 target-bfin/cpu.c
create mode 100644 target-bfin/cpu.h
create mode 100644 target-bfin/helper.c
create mode 100644 target-bfin/helper.h
create mode 100644 target-bfin/linux-fixed-code.h
create mode 100644 target-bfin/op_helper.c
create mode 100644 target-bfin/translate.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 3412b07..9563bb7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -69,6 +69,11 @@ F: target-arm/
F: hw/arm/
F: hw/cpu/a*mpcore.c
+Blackfin
+M: Mike Frysinger <vapier@gentoo.org>
+S: Maintained
+F: target-bfin/
+
CRIS
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
diff --git a/configure b/configure
index bc7a9c0..95dc66b 100755
--- a/configure
+++ b/configure
@@ -4146,6 +4146,10 @@ case "$target_arch2" in
target_nptl="yes"
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
;;
+ bfin)
+ bflt="yes"
+ target_phys_bits=32
+ ;;
cris)
target_nptl="yes"
;;
diff --git a/cpu-exec.c b/cpu-exec.c
index ec46380..98a99d8 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -249,6 +249,7 @@ int cpu_exec(CPUArchState *env)
#elif defined(TARGET_MOXIE)
#elif defined(TARGET_OPENRISC)
#elif defined(TARGET_SH4)
+#elif defined(TARGET_BFIN)
#elif defined(TARGET_CRIS)
#elif defined(TARGET_S390X)
#elif defined(TARGET_XTENSA)
@@ -302,7 +303,8 @@ int cpu_exec(CPUArchState *env)
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
- defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
+ defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32) || \
+ defined(TARGET_BFIN)
if (interrupt_request & CPU_INTERRUPT_HALT) {
cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
cpu->halted = 1;
@@ -698,6 +700,7 @@ int cpu_exec(CPUArchState *env)
#elif defined(TARGET_MOXIE)
#elif defined(TARGET_OPENRISC)
#elif defined(TARGET_SH4)
+#elif defined(TARGET_BFIN)
#elif defined(TARGET_ALPHA)
#elif defined(TARGET_CRIS)
#elif defined(TARGET_S390X)
diff --git a/gdbstub.c b/gdbstub.c
index 94c78ce..0947a31 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1780,6 +1780,107 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
return 4;
}
+#elif defined (TARGET_BFIN)
+
+#include "target-bfin/bfin-tdep.h"
+
+#define NUM_CORE_REGS BFIN_NUM_REGS
+
+static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
+{
+ switch (n) {
+ case BFIN_R0_REGNUM ... BFIN_R7_REGNUM:
+ GET_REGL(env->dreg[n - BFIN_R0_REGNUM]); break;
+ case BFIN_P0_REGNUM ... BFIN_FP_REGNUM:
+ GET_REGL(env->preg[n - BFIN_P0_REGNUM]); break;
+ case BFIN_I0_REGNUM ... BFIN_I3_REGNUM:
+ GET_REGL(env->ireg[n - BFIN_I0_REGNUM]); break;
+ case BFIN_M0_REGNUM ... BFIN_M3_REGNUM:
+ GET_REGL(env->mreg[n - BFIN_M0_REGNUM]); break;
+ case BFIN_B0_REGNUM ... BFIN_B3_REGNUM:
+ GET_REGL(env->breg[n - BFIN_B0_REGNUM]); break;
+ case BFIN_L0_REGNUM ... BFIN_L3_REGNUM:
+ GET_REGL(env->lreg[n - BFIN_L0_REGNUM]); break;
+ case BFIN_A0_DOT_X_REGNUM: GET_REGL((env->areg[0] >> 32) & 0xff); break;
+ case BFIN_A0_DOT_W_REGNUM: GET_REGL(env->areg[0]); break;
+ case BFIN_A1_DOT_X_REGNUM: GET_REGL((env->areg[1] >> 32) & 0xff); break;
+ case BFIN_A1_DOT_W_REGNUM: GET_REGL(env->areg[1]); break;
+ case BFIN_ASTAT_REGNUM: GET_REGL(bfin_astat_read(env)); break;
+ case BFIN_RETS_REGNUM: GET_REGL(env->rets); break;
+ case BFIN_LC0_REGNUM: GET_REGL(env->lcreg[0]); break;
+ case BFIN_LT0_REGNUM: GET_REGL(env->ltreg[0]); break;
+ case BFIN_LB0_REGNUM: GET_REGL(env->lbreg[0]); break;
+ case BFIN_LC1_REGNUM: GET_REGL(env->lcreg[1]); break;
+ case BFIN_LT1_REGNUM: GET_REGL(env->ltreg[1]); break;
+ case BFIN_LB1_REGNUM: GET_REGL(env->lbreg[1]); break;
+ case BFIN_CYCLES_REGNUM ... BFIN_CYCLES2_REGNUM:
+ GET_REGL(env->cycles[n - BFIN_CYCLES_REGNUM]); break;
+ case BFIN_USP_REGNUM: GET_REGL(env->uspreg); break;
+ case BFIN_SEQSTAT_REGNUM: GET_REGL(env->seqstat); break;
+ case BFIN_SYSCFG_REGNUM: GET_REGL(env->syscfg); break;
+ case BFIN_RETI_REGNUM: GET_REGL(env->reti); break;
+ case BFIN_RETX_REGNUM: GET_REGL(env->retx); break;
+ case BFIN_RETN_REGNUM: GET_REGL(env->retn); break;
+ case BFIN_RETE_REGNUM: GET_REGL(env->rete); break;
+ case BFIN_PC_REGNUM: GET_REGL(env->pc); break;
+ }
+
+ return 0;
+}
+
+static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n)
+{
+ target_ulong tmpl;
+ int r = 4;
+ tmpl = ldtul_p(mem_buf);
+
+ switch (n) {
+ case BFIN_R0_REGNUM ... BFIN_R7_REGNUM:
+ env->dreg[n - BFIN_R0_REGNUM] = tmpl; break;
+ case BFIN_P0_REGNUM ... BFIN_FP_REGNUM:
+ env->preg[n - BFIN_P0_REGNUM] = tmpl; break;
+ case BFIN_I0_REGNUM ... BFIN_I3_REGNUM:
+ env->ireg[n - BFIN_I0_REGNUM] = tmpl; break;
+ case BFIN_M0_REGNUM ... BFIN_M3_REGNUM:
+ env->mreg[n - BFIN_M0_REGNUM] = tmpl; break;
+ case BFIN_B0_REGNUM ... BFIN_B3_REGNUM:
+ env->breg[n - BFIN_B0_REGNUM] = tmpl; break;
+ case BFIN_L0_REGNUM ... BFIN_L3_REGNUM:
+ env->lreg[n - BFIN_L0_REGNUM] = tmpl; break;
+ case BFIN_A0_DOT_X_REGNUM:
+ env->areg[0] = (env->areg[0] & 0xffffffff) | ((uint64_t)tmpl << 32);
+ break;
+ case BFIN_A0_DOT_W_REGNUM:
+ env->areg[0] = (env->areg[0] & ~0xffffffff) | tmpl;
+ break;
+ case BFIN_A1_DOT_X_REGNUM:
+ env->areg[1] = (env->areg[1] & 0xffffffff) | ((uint64_t)tmpl << 32);
+ break;
+ case BFIN_A1_DOT_W_REGNUM:
+ env->areg[1] = (env->areg[1] & ~0xffffffff) | tmpl;
+ break;
+ case BFIN_ASTAT_REGNUM: bfin_astat_write(env, tmpl); break;
+ case BFIN_RETS_REGNUM: env->rets = tmpl; break;
+ case BFIN_LC0_REGNUM: env->lcreg[0] = tmpl; break;
+ case BFIN_LT0_REGNUM: env->ltreg[0] = tmpl; break;
+ case BFIN_LB0_REGNUM: env->lbreg[0] = tmpl; break;
+ case BFIN_LC1_REGNUM: env->lcreg[1] = tmpl; break;
+ case BFIN_LT1_REGNUM: env->ltreg[1] = tmpl; break;
+ case BFIN_LB1_REGNUM: env->lbreg[1] = tmpl; break;
+ case BFIN_CYCLES_REGNUM ... BFIN_CYCLES2_REGNUM:
+ env->cycles[n - BFIN_CYCLES_REGNUM] = tmpl; break;
+ case BFIN_USP_REGNUM: env->uspreg = tmpl; break;
+ case BFIN_SEQSTAT_REGNUM: env->seqstat = tmpl; break;
+ case BFIN_SYSCFG_REGNUM: env->syscfg = tmpl; break;
+ case BFIN_RETI_REGNUM: env->reti = tmpl; break;
+ case BFIN_RETX_REGNUM: env->retx = tmpl; break;
+ case BFIN_RETN_REGNUM: env->retn = tmpl; break;
+ case BFIN_RETE_REGNUM: env->rete = tmpl; break;
+ case BFIN_PC_REGNUM: env->pc = tmpl; break;
+ }
+
+ return r;
+}
#else
#define NUM_CORE_REGS 0
@@ -2066,6 +2167,8 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
s->c_cpu->pc = pc;
#elif defined(TARGET_XTENSA)
s->c_cpu->pc = pc;
+#elif defined (TARGET_BFIN)
+ s->c_cpu->pc = pc;
#endif
}
diff --git a/include/elf.h b/include/elf.h
index cf0d3e2..110e7b8 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -104,6 +104,7 @@ typedef int64_t Elf64_Sxword;
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin */
#define EM_LATTICEMICO32 138 /* LatticeMico32 */
#define EM_OPENRISC 92 /* OpenCores OpenRISC */
@@ -848,6 +849,11 @@ typedef struct {
#define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */
+/* Blackfin specific definitions. */
+
+#define EF_BFIN_PIC 0x00000001 /* -fpic */
+#define EF_BFIN_FDPIC 0x00000002 /* -mfdpic */
+
/* HPPA specific definitions. */
/* Legal values for e_flags field of Elf32_Ehdr. */
diff --git a/qapi-schema.json b/qapi-schema.json
index 5ad6894..c7f4304 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3023,10 +3023,11 @@
# Since: 1.2.0
##
{ 'enum': 'TargetType',
- 'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel',
- 'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'moxie',
- 'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4',
- 'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] }
+ 'data': [ 'alpha', 'arm', 'bfin', 'cris', 'i386', 'lm32', 'm68k',
+ 'microblazeel', 'microblaze', 'mips64el', 'mips64', 'mipsel',
+ 'mips', 'moxie', 'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb',
+ 'sh4', 'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb',
+ 'xtensa' ] }
##
# @TargetInfo:
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index 0da2618..52b9ef7 100644
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -41,6 +41,10 @@ if [ $cpu != "arm" ] ; then
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
fi
+if [ $cpu != "bfin" ] ; then
+ echo ':bfin:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00''\x02\x00''\x6A\x00''::/usr/local/bin/qemu-bfin:' > /proc/sys/fs/binfmt_misc/register
+ echo ':bfin-flat:M::bFLT\x00\x00\x00\x04::/usr/local/bin/qemu-bfin:' > /proc/sys/fs/binfmt_misc/register
+fi
if [ $cpu != "sparc" ] ; then
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
fi
diff --git a/target-bfin/Makefile.objs b/target-bfin/Makefile.objs
new file mode 100644
index 0000000..7e6c528
--- /dev/null
+++ b/target-bfin/Makefile.objs
@@ -0,0 +1,3 @@
+obj-y += translate.o op_helper.o helper.o cpu.o
+
+$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-bfin/README b/target-bfin/README
new file mode 100644
index 0000000..25f7fde
--- /dev/null
+++ b/target-bfin/README
@@ -0,0 +1,32 @@
+------------------
+Blackfin QEMU port
+------------------
+
+There are some things we don't bother handling in the port for speed reasons.
+If you want an accurate (but not as fast) simulator, then use the GNU sim as
+found in the GNU toolchain (part of gdb).
+
+Things we do not currently handle by design:
+
+ - invalid parallel instruction combinations
+ - no toolchain will output these
+ - things like jumps
+
+ - invalid register combinations
+ - some insns cannot have same register be both source and dest
+ - no toolchain will output these
+
+ - transactional parallel instructions
+ - on the hardware, if a load/store causes an exception, the other
+ insns do not change register states either. in qemu, they do,
+ but since those exceptions will kill the program anyways, who
+ cares. no intermediate store buffers!
+
+ - AC0_COPY and V_COPY
+ - no one has ever used these instead of AC0 or V
+
+ - no support for RND_MOD
+
+There are a few insns/modes we don't currently handle, but it's more a matter
+of nothing really uses these, so we haven't bothered. If these matter to you,
+then feel free to request support for them.
diff --git a/target-bfin/TODO b/target-bfin/TODO
new file mode 100644
index 0000000..80802bd
--- /dev/null
+++ b/target-bfin/TODO
@@ -0,0 +1,25 @@
+CEC behavior in user-emulation (SP vs USP)
+
+see if making a global "0", "1", "2", and "4" register speeds things up
+
+TB chaining is not implemented
+
+we often over-translate code blocks. consider a bfin mem/str func:
+ {
+ [1] setup code
+ [2] hwloop0
+ [3] some other stuff
+ [4] hwloop1
+ [5] clean up / return
+ }
+the first TB will go from the start to the end (since there are no
+unconditional branches). then when we hit the hwloop bottom, we jump
+back up to the top of the hwloop and a new TB which goes all the way
+to the end of the func. so we end up with the TBs covering:
+ {1-5} {2-5} {3-5} {4-5} {5-5}
+In reality, we probably want to have the TBs to be like:
+ {[1] to LSETUP then to LT0 (usually the same)}
+ {[2] LT0 to LB0}
+ {[3] to LSETUP then to LT1 (usually the same)}
+ {[4] LT1 to LB1}
+ {[5]}
diff --git a/target-bfin/bfin-sim.c b/target-bfin/bfin-sim.c
new file mode 100644
index 0000000..560fada
--- /dev/null
+++ b/target-bfin/bfin-sim.c
@@ -0,0 +1,3666 @@
+/*
+ * Simulator for Analog Devices Blackfin processors.
+ *
+ * Copyright 2005-2013 Mike Frysinger
+ * Copyright 2005-2011 Analog Devices, Inc.
+ *
+ * Licensed under the GPL 2 or later.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#define TRACE_EXTRACT(fmt, args...) \
+do { \
+ if (1) \
+ qemu_log_mask(CPU_LOG_TB_CPU, "%s: " fmt "\n", __func__, ## args); \
+} while (0)
+
+static void
+illegal_instruction(DisasContext *dc)
+{
+ cec_exception(dc, EXCP_UNDEF_INST);
+}
+
+static void
+unhandled_instruction(DisasContext *dc, const char *insn)
+{
+ fprintf(stderr, "unhandled insn: %s\n", insn);
+ illegal_instruction(dc);
+}
+
+typedef enum {
+ c_0, c_1, c_4, c_2, c_uimm2, c_uimm3, c_imm3, c_pcrel4,
+ c_imm4, c_uimm4s4, c_uimm4s4d, c_uimm4, c_uimm4s2, c_negimm5s4, c_imm5, c_imm5d, c_uimm5, c_imm6,
+ c_imm7, c_imm7d, c_imm8, c_uimm8, c_pcrel8, c_uimm8s4, c_pcrel8s4, c_lppcrel10, c_pcrel10,
+ c_pcrel12, c_imm16s4, c_luimm16, c_imm16, c_imm16d, c_huimm16, c_rimm16, c_imm16s2, c_uimm16s4,
+ c_uimm16s4d, c_uimm16, c_pcrel24, c_uimm32, c_imm32, c_huimm32, c_huimm32e,
+} const_forms_t;
+
+static const struct {
+ const char *name;
+ const int nbits;
+ const char reloc;
+ const char issigned;
+ const char pcrel;
+ const char scale;
+ const char offset;
+ const char negative;
+ const char positive;
+ const char decimal;
+ const char leading;
+ const char exact;
+} constant_formats[] = {
+ { "0", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "1", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "4", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "2", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm2", 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm3", 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm3", 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel4", 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "imm4", 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm4s4", 4, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0},
+ { "uimm4s4d", 4, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0},
+ { "uimm4", 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm4s2", 4, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},
+ { "negimm5s4", 5, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0},
+ { "imm5", 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm5d", 5, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
+ { "uimm5", 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm6", 6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm7", 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm7d", 7, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "imm8", 8, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "uimm8", 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel8", 8, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm8s4", 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "pcrel8s4", 8, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
+ { "lppcrel10", 10, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "pcrel10", 10, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "pcrel12", 12, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "imm16s4", 16, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "luimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16", 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16d", 16, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "huimm16", 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "rimm16", 16, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm16s2", 16, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm16s4", 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0},
+ { "uimm16s4d", 16, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0},
+ { "uimm16", 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "pcrel24", 24, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ { "uimm32", 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "imm32", 32, 0, 1, 0, 0, 0, 0, 0, 1, 3, 0},
+ { "huimm32", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { "huimm32e", 32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+};
+
+#define HOST_LONG_WORD_SIZE (sizeof(long) * 8)
+#define SIGNEXTEND(v, n) (((int32_t)(v) << (HOST_LONG_WORD_SIZE - (n))) >> (HOST_LONG_WORD_SIZE - (n)))
+
+static uint32_t
+fmtconst_val(const_forms_t cf, uint32_t x)
+{
+ /* Negative constants have an implied sign bit. */
+ if (constant_formats[cf].negative) {
+ int nb = constant_formats[cf].nbits + 1;
+ x = x | (1 << constant_formats[cf].nbits);
+ x = SIGNEXTEND(x, nb);
+ } else if (constant_formats[cf].issigned) {
+ x = SIGNEXTEND(x, constant_formats[cf].nbits);
+ }
+
+ x += constant_formats[cf].offset;
+ x <<= constant_formats[cf].scale;
+
+ return x;
+}
+
+#define uimm16s4(x) fmtconst_val(c_uimm16s4, x)
+#define uimm16s4d(x) fmtconst_val(c_uimm16s4d, x)
+#define pcrel4(x) fmtconst_val(c_pcrel4, x)
+#define pcrel8(x) fmtconst_val(c_pcrel8, x)
+#define pcrel8s4(x) fmtconst_val(c_pcrel8s4, x)
+#define pcrel10(x) fmtconst_val(c_pcrel10, x)
+#define pcrel12(x) fmtconst_val(c_pcrel12, x)
+#define negimm5s4(x) fmtconst_val(c_negimm5s4, x)
+#define rimm16(x) fmtconst_val(c_rimm16, x)
+#define huimm16(x) fmtconst_val(c_huimm16, x)
+#define imm16(x) fmtconst_val(c_imm16, x)
+#define imm16d(x) fmtconst_val(c_imm16d, x)
+#define uimm2(x) fmtconst_val(c_uimm2, x)
+#define uimm3(x) fmtconst_val(c_uimm3, x)
+#define luimm16(x) fmtconst_val(c_luimm16, x)
+#define uimm4(x) fmtconst_val(c_uimm4, x)
+#define uimm5(x) fmtconst_val(c_uimm5, x)
+#define imm16s2(x) fmtconst_val(c_imm16s2, x)
+#define uimm8(x) fmtconst_val(c_uimm8, x)
+#define imm16s4(x) fmtconst_val(c_imm16s4, x)
+#define uimm4s2(x) fmtconst_val(c_uimm4s2, x)
+#define uimm4s4(x) fmtconst_val(c_uimm4s4, x)
+#define uimm4s4d(x) fmtconst_val(c_uimm4s4d, x)
+#define lppcrel10(x) fmtconst_val(c_lppcrel10, x)
+#define imm3(x) fmtconst_val(c_imm3, x)
+#define imm4(x) fmtconst_val(c_imm4, x)
+#define uimm8s4(x) fmtconst_val(c_uimm8s4, x)
+#define imm5(x) fmtconst_val(c_imm5, x)
+#define imm5d(x) fmtconst_val(c_imm5d, x)
+#define imm6(x) fmtconst_val(c_imm6, x)
+#define imm7(x) fmtconst_val(c_imm7, x)
+#define imm7d(x) fmtconst_val(c_imm7d, x)
+#define imm8(x) fmtconst_val(c_imm8, x)
+#define pcrel24(x) fmtconst_val(c_pcrel24, x)
+#define uimm16(x) fmtconst_val(c_uimm16, x)
+#define uimm32(x) fmtconst_val(c_uimm32, x)
+#define imm32(x) fmtconst_val(c_imm32, x)
+#define huimm32(x) fmtconst_val(c_huimm32, x)
+#define huimm32e(x) fmtconst_val(c_huimm32e, x)
+
+/* Table C-4. Core Register Encoding Map */
+const char * const greg_names[] = {
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
+ "P0", "P1", "P2", "P3", "P4", "P5", "SP", "FP",
+ "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3",
+ "B0", "B1", "B2", "B3", "L0", "L1", "L2", "L3",
+ "A0.X", "A0.W", "A1.X", "A1.W", "<res>", "<res>", "ASTAT", "RETS",
+ "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>",
+ "LC0", "LT0", "LB0", "LC1", "LT1", "LB1", "CYCLES", "CYCLES2",
+ "USP", "SEQSTAT", "SYSCFG", "RETI", "RETX", "RETN", "RETE", "EMUDAT",
+};
+
+const char *
+get_allreg_name(int grp, int reg)
+{
+ return greg_names[(grp << 3) | reg];
+}
+
+static TCGv * const cpu_regs[] = {
+ &cpu_dreg[0], &cpu_dreg[1], &cpu_dreg[2], &cpu_dreg[3], &cpu_dreg[4], &cpu_dreg[5], &cpu_dreg[6], &cpu_dreg[7],
+ &cpu_preg[0], &cpu_preg[1], &cpu_preg[2], &cpu_preg[3], &cpu_preg[4], &cpu_preg[5], &cpu_preg[6], &cpu_preg[7],
+ &cpu_ireg[0], &cpu_ireg[1], &cpu_ireg[2], &cpu_ireg[3], &cpu_mreg[0], &cpu_mreg[1], &cpu_mreg[2], &cpu_mreg[3],
+ &cpu_breg[0], &cpu_breg[1], &cpu_breg[2], &cpu_breg[3], &cpu_lreg[0], &cpu_lreg[1], &cpu_lreg[2], &cpu_lreg[3],
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cpu_rets,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ &cpu_lcreg[0], &cpu_ltreg[0], &cpu_lbreg[0], &cpu_lcreg[1], &cpu_ltreg[1], &cpu_lbreg[1], &cpu_cycles[0], &cpu_cycles[1],
+ &cpu_uspreg, &cpu_seqstat, &cpu_syscfg, &cpu_reti, &cpu_retx, &cpu_retn, &cpu_rete, &cpu_emudat,
+};
+
+static TCGv
+get_allreg(DisasContext *dc, int grp, int reg)
+{
+ TCGv *ret = cpu_regs[(grp << 3) | reg];
+ if (ret) {
+ return *ret;
+ }
+ abort();
+ illegal_instruction(dc);
+}
+
+static void
+reg_check_sup(DisasContext *dc, int grp, int reg)
+{
+ if (grp == 7) {
+ cec_require_supervisor(dc);
+ }
+}
+
+#define gen_unextend_acc(acc) tcg_gen_andi_i64(acc, acc, 0xffffffffffull)
+#define gen_extend_acc(acc) gen_extNsi_i64(acc, acc, 40)
+
+/* Perform a multiplication of D registers SRC0 and SRC1, sign- or
+ zero-extending the result to 64 bit. H0 and H1 determine whether the
+ high part or the low part of the source registers is used. Store 1 in
+ *PSAT if saturation occurs, 0 otherwise. */
+static TCGv
+decode_multfunc_tl(DisasContext *dc, int h0, int h1, int src0, int src1,
+ int mmod, int MM, TCGv psat)
+{
+ TCGv s0, s1, val;
+
+ s0 = tcg_temp_local_new();
+ if (h0) {
+ tcg_gen_shri_tl(s0, cpu_dreg[src0], 16);
+ } else {
+ tcg_gen_andi_tl(s0, cpu_dreg[src0], 0xffff);
+ }
+
+ s1 = tcg_temp_local_new();
+ if (h1) {
+ tcg_gen_shri_tl(s1, cpu_dreg[src1], 16);
+ } else {
+ tcg_gen_andi_tl(s1, cpu_dreg[src1], 0xffff);
+ }
+
+ if (MM) {
+ tcg_gen_ext16s_tl(s0, s0);
+ } else {
+ switch (mmod) {
+ case 0:
+ case M_S2RND:
+ case M_T:
+ case M_IS:
+ case M_ISS2:
+ case M_IH:
+ case M_W32:
+ tcg_gen_ext16s_tl(s0, s0);
+ tcg_gen_ext16s_tl(s1, s1);
+ break;
+ case M_FU:
+ case M_IU:
+ case M_TFU:
+ break;
+ default:
+ illegal_instruction(dc);
+ }
+ }
+
+ val = tcg_temp_local_new();
+ tcg_gen_mul_tl(val, s0, s1);
+ tcg_temp_free(s0);
+ tcg_temp_free(s1);
+
+ /* Perform shift correction if appropriate for the mode. */
+ tcg_gen_movi_tl(psat, 0);
+ if (!MM && (mmod == 0 || mmod == M_T || mmod == M_S2RND || mmod == M_W32)) {
+ int l, endl;
+
+ l = gen_new_label();
+ endl = gen_new_label();
+
+ tcg_gen_brcondi_tl(TCG_COND_NE, val, 0x40000000, l);
+ if (mmod == M_W32) {
+ tcg_gen_movi_tl(val, 0x7fffffff);
+ } else {
+ tcg_gen_movi_tl(val, 0x80000000);
+ }
+ tcg_gen_movi_tl(psat, 1);
+ tcg_gen_br(endl);
+
+ gen_set_label(l);
+ tcg_gen_shli_tl(val, val, 1);
+
+ gen_set_label(endl);
+ }
+
+ return val;
+}
+
+static TCGv_i64
+decode_multfunc_i64(DisasContext *dc, int h0, int h1, int src0, int src1,
+ int mmod, int MM, TCGv psat)
+{
+ TCGv val;
+ TCGv_i64 val1;
+ int l;
+
+ val = decode_multfunc_tl(dc, h0, h1, src0, src1, mmod, MM, psat);
+ val1 = tcg_temp_local_new_i64();
+ tcg_gen_extu_i32_i64(val1, val);
+ tcg_temp_free(val);
+
+ if (mmod == 0 || mmod == M_IS || mmod == M_T || mmod == M_S2RND ||
+ mmod == M_ISS2 || mmod == M_IH || (MM && mmod == M_FU)) {
+ gen_extNsi_i64(val1, val1, 40);
+ }
+
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_EQ, psat, 0, l);
+ tcg_gen_ext32u_i64(val1, val1);
+ gen_set_label(l);
+
+ return val1;
+}
+
+static void
+saturate_s32(TCGv_i64 val, TCGv overflow)
+{
+ int l, endl;
+
+ endl = gen_new_label();
+
+ l = gen_new_label();
+ tcg_gen_brcondi_i64(TCG_COND_GE, val, -0x80000000ll, l);
+ tcg_gen_movi_tl(overflow, 1);
+ tcg_gen_movi_i64(val, 0x80000000);
+ tcg_gen_br(endl);
+ gen_set_label(l);
+
+ l = gen_new_label();
+ tcg_gen_brcondi_i64(TCG_COND_LE, val, 0x7fffffff, l);
+ tcg_gen_movi_tl(overflow, 1);
+ tcg_gen_movi_i64(val, 0x7fffffff);
+ gen_set_label(l);
+
+ gen_set_label(endl);
+}
+
+static TCGv
+decode_macfunc(DisasContext *dc, int which, int op, int h0, int h1, int src0,
+ int src1, int mmod, int MM, int fullword, int *overflow)
+{
+ /* XXX: Very incomplete. */
+ TCGv_i64 acc;
+
+ if (mmod == 0 || mmod == M_T || mmod == M_IS || mmod == M_ISS2 ||
+ mmod == M_S2RND || mmod == M_IH || mmod == M_W32) {
+ gen_extend_acc(cpu_areg[which]);
+ } else {
+ gen_unextend_acc(cpu_areg[which]);
+ }
+ acc = cpu_areg[which];
+
+ if (op != 3) {
+ /* this can't saturate, so we don't keep track of the sat flag */
+ TCGv tsat = tcg_temp_local_new();;
+ TCGv_i64 res = decode_multfunc_i64(dc, h0, h1, src0, src1, mmod, MM, tsat);
+ tcg_temp_free(tsat);
+
+ /* Perform accumulation. */
+ switch (op) {
+ case 0:
+ tcg_gen_mov_i64(acc, res);
+ break;
+ case 1:
+ tcg_gen_add_i64(acc, acc, res);
+ break;
+ case 2:
+ tcg_gen_sub_i64(acc, acc, res);
+ break;
+ }
+ tcg_temp_free_i64(res);
+
+ /* XXX: Saturate. */
+ }
+
+ TCGv tmp = tcg_temp_local_new();
+ tcg_gen_trunc_i64_i32(tmp, acc);
+ return tmp;
+}
+
+static void
+decode_ProgCtrl_0(DisasContext *dc, uint16_t iw0)
+{
+ /* ProgCtrl
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.prgfunc.......|.poprnd........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int poprnd = ((iw0 >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask);
+ int prgfunc = ((iw0 >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask);
+
+ TRACE_EXTRACT("poprnd:%i prgfunc:%i", poprnd, prgfunc);
+
+ if (prgfunc == 0 && poprnd == 0) {
+ /* NOP */;
+ } else if (prgfunc == 1 && poprnd == 0) {
+ /* RTS; */
+ dc->is_jmp = DISAS_JUMP;
+ dc->hwloop_callback = gen_hwloop_br_direct;
+ dc->hwloop_data = &cpu_rets;
+ } else if (prgfunc == 1 && poprnd == 1) {
+ /* RTI; */
+ cec_require_supervisor(dc);
+ } else if (prgfunc == 1 && poprnd == 2) {
+ /* RTX; */
+ cec_require_supervisor(dc);
+ } else if (prgfunc == 1 && poprnd == 3) {
+ /* RTN; */
+ cec_require_supervisor(dc);
+ } else if (prgfunc == 1 && poprnd == 4) {
+ /* RTE; */
+ cec_require_supervisor(dc);
+ } else if (prgfunc == 2 && poprnd == 0) {
+ /* IDLE; */
+ /* just NOP it */;
+ } else if (prgfunc == 2 && poprnd == 3) {
+ /* CSYNC; */
+ /* just NOP it */;
+ } else if (prgfunc == 2 && poprnd == 4) {
+ /* SSYNC; */
+ /* just NOP it */;
+ } else if (prgfunc == 2 && poprnd == 5) {
+ /* EMUEXCPT; */
+ cec_exception(dc, EXCP_DEBUG);
+ } else if (prgfunc == 3 && poprnd < 8) {
+ /* CLI Dreg{poprnd}; */
+ cec_require_supervisor(dc);
+ } else if (prgfunc == 4 && poprnd < 8) {
+ /* STI Dreg{poprnd}; */
+ cec_require_supervisor(dc);
+ } else if (prgfunc == 5 && poprnd < 8) {
+ /* JUMP (Preg{poprnd}); */
+ dc->is_jmp = DISAS_JUMP;
+ dc->hwloop_callback = gen_hwloop_br_direct;
+ dc->hwloop_data = &cpu_preg[poprnd];
+ } else if (prgfunc == 6 && poprnd < 8) {
+ /* CALL (Preg{poprnd}); */
+ dc->is_jmp = DISAS_CALL;
+ dc->hwloop_callback = gen_hwloop_br_direct;
+ dc->hwloop_data = &cpu_preg[poprnd];
+ } else if (prgfunc == 7 && poprnd < 8) {
+ /* CALL (PC + Preg{poprnd}); */
+ dc->is_jmp = DISAS_CALL;
+ dc->hwloop_callback = gen_hwloop_br_pcrel;
+ dc->hwloop_data = &cpu_preg[poprnd];
+ } else if (prgfunc == 8 && poprnd < 8) {
+ /* JUMP (PC + Preg{poprnd}); */
+ dc->is_jmp = DISAS_JUMP;
+ dc->hwloop_callback = gen_hwloop_br_pcrel;
+ dc->hwloop_data = &cpu_preg[poprnd];
+ } else if (prgfunc == 9) {
+ /* RAISE imm{poprnd}; */
+ /* int raise = uimm4 (poprnd); */
+ cec_require_supervisor(dc);
+ } else if (prgfunc == 10) {
+ /* EXCPT imm{poprnd}; */
+ int excpt = uimm4 (poprnd);
+ cec_exception(dc, excpt);
+ } else if (prgfunc == 11 && poprnd < 6) {
+ /* TESTSET (Preg{poprnd}); */
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_qemu_ld8u(tmp, cpu_preg[poprnd], dc->mem_idx);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_cc, tmp, 0);
+ tcg_gen_ori_tl(tmp, tmp, 0x80);
+ tcg_gen_qemu_st8(tmp, cpu_preg[poprnd], dc->mem_idx);
+ tcg_temp_free(tmp);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_CaCTRL_0(DisasContext *dc, uint16_t iw0)
+{
+ /* CaCTRL
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |.a.|.op....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int a = ((iw0 >> CaCTRL_a_bits) & CaCTRL_a_mask);
+ int op = ((iw0 >> CaCTRL_op_bits) & CaCTRL_op_mask);
+ int reg = ((iw0 >> CaCTRL_reg_bits) & CaCTRL_reg_mask);
+
+ TRACE_EXTRACT("a:%i op:%i reg:%i", a, op, reg);
+
+ /*
+ * PREFETCH [Preg{reg}];
+ * PREFETCH [Preg{reg}++{a}];
+ * FLUSHINV [Preg{reg}];
+ * FLUSHINV [Preg{reg}++{a}];
+ * FLUSH [Preg{reg}];
+ * FLUSH [Preg{reg}++{a}];
+ * IFLUSH [Preg{reg}];
+ * IFLUSH [Preg{reg}++{a}];
+ */
+
+ /* No cache simulation, and we'll ignore the implicit CPLB aspects */
+
+ if (a) {
+ tcg_gen_addi_tl(cpu_preg[reg], cpu_preg[reg], BFIN_L1_CACHE_BYTES);
+ }
+}
+
+static void
+decode_PushPopReg_0(DisasContext *dc, uint16_t iw0)
+{
+ /* PushPopReg
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.W.|.grp.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int W = ((iw0 >> PushPopReg_W_bits) & PushPopReg_W_mask);
+ int grp = ((iw0 >> PushPopReg_grp_bits) & PushPopReg_grp_mask);
+ int reg = ((iw0 >> PushPopReg_reg_bits) & PushPopReg_reg_mask);
+ TCGv treg, tmp;
+ TCGv_i64 tmp64;
+
+ TRACE_EXTRACT("W:%i grp:%i reg:%i", W, grp, reg);
+
+ /* Can't push/pop reserved registers */
+ /*if (reg_is_reserved(grp, reg))
+ illegal_instruction(dc);*/
+
+ reg_check_sup(dc, grp, reg);
+
+ /* Everything here needs to be aligned, so check once */
+ gen_align_check(dc, cpu_spreg, 4, false);
+
+ if (W == 0) {
+ /* Dreg and Preg are not supported by this instruction */
+ /*if (grp == 0 || grp == 1)
+ illegal_instruction(dc);*/
+
+ /* genreg{grp,reg} [SP++]; */
+ if (grp == 4 && reg == 6) {
+ /* Pop ASTAT */
+ tmp = tcg_temp_new();
+ tcg_gen_qemu_ld32u(tmp, cpu_spreg, dc->mem_idx);
+ gen_astat_store(dc, tmp);
+ tcg_temp_free(tmp);
+ } else if (grp == 4 && (reg == 0 || reg == 2)) {
+ /* Pop A#.X */
+ tmp = tcg_temp_new();
+ tcg_gen_qemu_ld32u(tmp, cpu_spreg, dc->mem_idx);
+ tcg_gen_andi_tl(tmp, tmp, 0xff);
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, tmp);
+ tcg_temp_free(tmp);
+
+ tcg_gen_andi_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], 0xffffffff);
+ tcg_gen_shli_i64(tmp64, tmp64, 32);
+ tcg_gen_or_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else if (grp == 4 && (reg == 1 || reg == 3)) {
+ /* Pop A#.W */
+ tcg_gen_andi_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], 0xff00000000);
+ tmp = tcg_temp_new();
+ tcg_gen_qemu_ld32u(tmp, cpu_spreg, dc->mem_idx);
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, tmp);
+ tcg_temp_free(tmp);
+ tcg_gen_or_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else {
+ treg = get_allreg(dc, grp, reg);
+ tcg_gen_qemu_ld32u(treg, cpu_spreg, dc->mem_idx);
+
+ if (grp == 6 && (reg == 1 || reg == 4)) {
+ /* LT loads auto clear the LSB */
+ tcg_gen_andi_tl(treg, treg, ~1);
+ }
+ }
+
+ tcg_gen_addi_tl(cpu_spreg, cpu_spreg, 4);
+ gen_maybe_lb_exit_tb(dc, treg);
+ } else {
+ /* [--SP] = genreg{grp,reg}; */
+
+ tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
+ if (grp == 4 && reg == 6) {
+ /* Push ASTAT */
+ tmp = tcg_temp_new();
+ gen_astat_load(dc, tmp);
+ tcg_gen_qemu_st32(tmp, cpu_spreg, dc->mem_idx);
+ tcg_temp_free(tmp);
+ } else if (grp == 4 && (reg == 0 || reg == 2)) {
+ /* Push A#.X */
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_shri_i64(tmp64, cpu_areg[reg >> 1], 32);
+ tmp = tcg_temp_new();
+ tcg_gen_trunc_i64_i32(tmp, tmp64);
+ tcg_temp_free_i64(tmp64);
+ tcg_gen_andi_tl(tmp, tmp, 0xff);
+ tcg_gen_qemu_st32(tmp, cpu_spreg, dc->mem_idx);
+ tcg_temp_free(tmp);
+ } else if (grp == 4 && (reg == 1 || reg == 3)) {
+ /* Push A#.W */
+ tmp = tcg_temp_new();
+ tcg_gen_trunc_i64_i32(tmp, cpu_areg[reg >> 1]);
+ tcg_gen_qemu_st32(tmp, cpu_spreg, dc->mem_idx);
+ tcg_temp_free(tmp);
+ } else {
+ treg = get_allreg(dc, grp, reg);
+ tcg_gen_qemu_st32(treg, cpu_spreg, dc->mem_idx);
+ }
+ }
+}
+
+static void
+decode_PushPopMultiple_0(DisasContext *dc, uint16_t iw0)
+{
+ /* PushPopMultiple
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 1 | 0 |.d.|.p.|.W.|.dr........|.pr........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int p = ((iw0 >> PushPopMultiple_p_bits) & PushPopMultiple_p_mask);
+ int d = ((iw0 >> PushPopMultiple_d_bits) & PushPopMultiple_d_mask);
+ int W = ((iw0 >> PushPopMultiple_W_bits) & PushPopMultiple_W_mask);
+ int dr = ((iw0 >> PushPopMultiple_dr_bits) & PushPopMultiple_dr_mask);
+ int pr = ((iw0 >> PushPopMultiple_pr_bits) & PushPopMultiple_pr_mask);
+ int i;
+
+ TRACE_EXTRACT("d:%i p:%i W:%i dr:%i pr:%i", d, p, W, dr, pr);
+
+ if ((d == 0 && p == 0) || (p && imm5(pr) > 5) ||
+ (d && !p && pr) || (p && !d && dr)) {
+ illegal_instruction(dc);
+ }
+
+ /* Everything here needs to be aligned, so check once */
+ gen_align_check(dc, cpu_spreg, 4, false);
+
+ if (W == 1) {
+ /* [--SP] = ({d}R7:imm{dr}, {p}P5:imm{pr}); */
+ if (d) {
+ for (i = dr; i < 8; i++) {
+ tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
+ tcg_gen_qemu_st32(cpu_dreg[i], cpu_spreg, dc->mem_idx);
+ }
+ }
+ if (p) {
+ for (i = pr; i < 6; i++) {
+ tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
+ tcg_gen_qemu_st32(cpu_preg[i], cpu_spreg, dc->mem_idx);
+ }
+ }
+ } else {
+ /* ({d}R7:imm{dr}, {p}P5:imm{pr}) = [SP++]; */
+ if (p) {
+ for (i = 5; i >= pr; i--) {
+ tcg_gen_qemu_ld32u(cpu_preg[i], cpu_spreg, dc->mem_idx);
+ tcg_gen_addi_tl(cpu_spreg, cpu_spreg, 4);
+ }
+ }
+ if (d) {
+ for (i = 7; i >= dr; i--) {
+ tcg_gen_qemu_ld32u(cpu_dreg[i], cpu_spreg, dc->mem_idx);
+ tcg_gen_addi_tl(cpu_spreg, cpu_spreg, 4);
+ }
+ }
+ }
+}
+
+static void
+decode_ccMV_0(DisasContext *dc, uint16_t iw0)
+{
+ /* ccMV
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.T.|.d.|.s.|.dst.......|.src.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int s = ((iw0 >> CCmv_s_bits) & CCmv_s_mask);
+ int d = ((iw0 >> CCmv_d_bits) & CCmv_d_mask);
+ int T = ((iw0 >> CCmv_T_bits) & CCmv_T_mask);
+ int src = ((iw0 >> CCmv_src_bits) & CCmv_src_mask);
+ int dst = ((iw0 >> CCmv_dst_bits) & CCmv_dst_mask);
+ int l;
+ TCGv reg_src, reg_dst;
+
+ TRACE_EXTRACT("T:%i d:%i s:%i dst:%i src:%i",
+ T, d, s, dst, src);
+
+ /* IF !{T} CC DPreg{d,dst} = DPreg{s,src}; */
+ reg_src = get_allreg(dc, s, src);
+ reg_dst = get_allreg(dc, d, dst);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc, T, l);
+ tcg_gen_mov_tl(reg_dst, reg_src);
+ gen_set_label(l);
+}
+
+static void
+decode_CCflag_0(DisasContext *dc, uint16_t iw0)
+{
+ /* CCflag
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 1 |.I.|.opc.......|.G.|.y.........|.x.........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int x = ((iw0 >> CCflag_x_bits) & CCflag_x_mask);
+ int y = ((iw0 >> CCflag_y_bits) & CCflag_y_mask);
+ int I = ((iw0 >> CCflag_I_bits) & CCflag_I_mask);
+ int G = ((iw0 >> CCflag_G_bits) & CCflag_G_mask);
+ int opc = ((iw0 >> CCflag_opc_bits) & CCflag_opc_mask);
+
+ TRACE_EXTRACT("I:%i opc:%i G:%i y:%i x:%i",
+ I, opc, G, y, x);
+
+ if (opc > 4) {
+ TCGv_i64 tmp64;
+ TCGCond cond;
+
+ /*if (x != 0 || y != 0)
+ illegal_instruction(dc);*/
+
+ if (opc == 5 && I == 0 && G == 0) {
+ /* CC = A0 == A1; */
+ cond = TCG_COND_EQ;
+ } else if (opc == 6 && I == 0 && G == 0) {
+ /* CC = A0 < A1; */
+ cond = TCG_COND_LT;
+ } else if (opc == 7 && I == 0 && G == 0) {
+ /* CC = A0 <= A1; */
+ cond = TCG_COND_LE;
+ } else {
+ illegal_instruction(dc);
+ }
+
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_setcond_i64(cond, tmp64, cpu_areg[0], cpu_areg[1]);
+ tcg_gen_trunc_i64_i32(cpu_cc, tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else {
+ int issigned = opc < 3;
+ uint32_t dst_imm = issigned ? imm3(y) : uimm3(y);
+ TCGv src_reg = G ? cpu_preg[x] : cpu_dreg[x];
+ TCGv dst_reg = G ? cpu_preg[y] : cpu_dreg[y];
+ TCGv tmp;
+ TCGCond cond;
+ enum astat_ops astat_op;
+
+ switch (opc) {
+ default: /* shutup useless gcc warnings */
+ case 0: /* signed == */
+ cond = TCG_COND_EQ;
+ break;
+ case 1: /* signed < */
+ cond = TCG_COND_LT;
+ break;
+ case 2: /* signed <= */
+ cond = TCG_COND_LE;
+ break;
+ case 3: /* unsigned < */
+ cond = TCG_COND_LTU;
+ break;
+ case 4: /* unsigned <= */
+ cond = TCG_COND_LEU;
+ break;
+ }
+ if (issigned) {
+ astat_op = ASTAT_OP_COMPARE_SIGNED;
+ } else {
+ astat_op = ASTAT_OP_COMPARE_UNSIGNED;
+ }
+
+ if (I) {
+ /* Compare to an immediate rather than a reg */
+ tmp = tcg_const_tl(dst_imm);
+ dst_reg = tmp;
+ }
+ tcg_gen_setcond_tl(cond, cpu_cc, src_reg, dst_reg);
+
+ /* Pointer compares only touch CC. */
+ if (!G) {
+ astat_queue_state2(dc, astat_op, src_reg, dst_reg);
+ }
+
+ if (I) {
+ tcg_temp_free(tmp);
+ }
+ }
+}
+
+static void
+decode_CC2dreg_0(DisasContext *dc, uint16_t iw0)
+{
+ /* CC2dreg
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |.op....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> CC2dreg_op_bits) & CC2dreg_op_mask);
+ int reg = ((iw0 >> CC2dreg_reg_bits) & CC2dreg_reg_mask);
+
+ TRACE_EXTRACT("op:%i reg:%i", op, reg);
+
+ if (op == 0) {
+ /* Dreg{reg} = CC; */
+ tcg_gen_mov_tl(cpu_dreg[reg], cpu_cc);
+ } else if (op == 1) {
+ /* CC = Dreg{reg}; */
+ tcg_gen_setcondi_tl(TCG_COND_NE, cpu_cc, cpu_dreg[reg], 0);
+ } else if (op == 3 && reg == 0) {
+ /* CC = !CC; */
+ tcg_gen_xori_tl(cpu_cc, cpu_cc, 1);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_CC2stat_0(DisasContext *dc, uint16_t iw0)
+{
+ /* CC2stat
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |.D.|.op....|.cbit..............|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int D = ((iw0 >> CC2stat_D_bits) & CC2stat_D_mask);
+ int op = ((iw0 >> CC2stat_op_bits) & CC2stat_op_mask);
+ int cbit = ((iw0 >> CC2stat_cbit_bits) & CC2stat_cbit_mask);
+ TCGv tmp;
+
+ TRACE_EXTRACT("D:%i op:%i cbit:%i", D, op, cbit);
+
+ /* CC = CC; is invalid. */
+ if (cbit == 5)
+ illegal_instruction(dc);
+
+ gen_astat_update(dc, true);
+
+ if (D == 0) {
+ switch (op) {
+ case 0: /* CC = ASTAT[cbit] */
+ tcg_gen_ld_tl(cpu_cc, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ break;
+ case 1: /* CC |= ASTAT[cbit] */
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_gen_or_tl(cpu_cc, cpu_cc, tmp);
+ tcg_temp_free(tmp);
+ break;
+ case 2: /* CC &= ASTAT[cbit] */
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_gen_and_tl(cpu_cc, cpu_cc, tmp);
+ tcg_temp_free(tmp);
+ break;
+ case 3: /* CC ^= ASTAT[cbit] */
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_gen_xor_tl(cpu_cc, cpu_cc, tmp);
+ tcg_temp_free(tmp);
+ break;
+ }
+ } else {
+ switch (op) {
+ case 0: /* ASTAT[cbit] = CC */
+ tcg_gen_st_tl(cpu_cc, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ break;
+ case 1: /* ASTAT[cbit] |= CC */
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_gen_or_tl(tmp, tmp, cpu_cc);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_temp_free(tmp);
+ break;
+ case 2: /* ASTAT[cbit] &= CC */
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_gen_and_tl(tmp, tmp, cpu_cc);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_temp_free(tmp);
+ break;
+ case 3: /* ASTAT[cbit] ^= CC */
+ tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_gen_xor_tl(tmp, tmp, cpu_cc);
+ tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUArchState, astat[cbit]));
+ tcg_temp_free(tmp);
+ break;
+ }
+ }
+}
+
+static void
+decode_BRCC_0(DisasContext *dc, uint16_t iw0)
+{
+ /* BRCC
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 0 | 1 |.T.|.B.|.offset................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int B = ((iw0 >> BRCC_B_bits) & BRCC_B_mask);
+ int T = ((iw0 >> BRCC_T_bits) & BRCC_T_mask);
+ int offset = ((iw0 >> BRCC_offset_bits) & BRCC_offset_mask);
+ int pcrel = pcrel10(offset);
+
+ TRACE_EXTRACT("T:%i B:%i offset:%#x", T, B, offset);
+
+ /* IF !{T} CC JUMP imm{offset} (bp){B}; */
+ dc->hwloop_callback = gen_hwloop_br_pcrel_cc;
+ dc->hwloop_data = (void *)(unsigned long)(pcrel | T);
+}
+
+static void
+decode_UJUMP_0(DisasContext *dc, uint16_t iw0)
+{
+ /* UJUMP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 1 | 0 |.offset........................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int offset = ((iw0 >> UJump_offset_bits) & UJump_offset_mask);
+ int pcrel = pcrel12(offset);
+
+ TRACE_EXTRACT("offset:%#x", offset);
+
+ /* JUMP.S imm{offset}; */
+ dc->is_jmp = DISAS_JUMP;
+ dc->hwloop_callback = gen_hwloop_br_pcrel_imm;
+ dc->hwloop_data = (void *)(unsigned long)pcrel;
+}
+
+static void
+decode_REGMV_0(DisasContext *dc, uint16_t iw0)
+{
+ /* REGMV
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 0 | 1 | 1 |.gd........|.gs........|.dst.......|.src.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int gs = ((iw0 >> RegMv_gs_bits) & RegMv_gs_mask);
+ int gd = ((iw0 >> RegMv_gd_bits) & RegMv_gd_mask);
+ int src = ((iw0 >> RegMv_src_bits) & RegMv_src_mask);
+ int dst = ((iw0 >> RegMv_dst_bits) & RegMv_dst_mask);
+ TCGv reg_src, reg_dst, tmp;
+ TCGv_i64 tmp64;
+ bool istmp;
+
+ TRACE_EXTRACT("gd:%i gs:%i dst:%i src:%i",
+ gd, gs, dst, src);
+
+ /* genreg{gd,dst} = genreg{gs,src}; */
+
+ reg_check_sup(dc, gs, src);
+ reg_check_sup(dc, gd, dst);
+
+ if (gs == 4 && src == 6) {
+ /* Reads of ASTAT */
+ tmp = tcg_temp_new();
+ gen_astat_load(dc, tmp);
+ reg_src = tmp;
+ istmp = true;
+ } else if (gs == 4 && (src == 0 || src == 2)) {
+ /* Reads of A#.X */
+ tmp = tcg_temp_new();
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_shri_i64(tmp64, cpu_areg[src >> 1], 32);
+ tcg_gen_trunc_i64_i32(tmp, tmp64);
+ tcg_temp_free_i64(tmp64);
+ tcg_gen_ext8s_tl(tmp, tmp);
+ reg_src = tmp;
+ istmp = true;
+ } else if (gs == 4 && (src == 1 || src == 3)) {
+ /* Reads of A#.W */
+ tmp = tcg_temp_new();
+ tcg_gen_trunc_i64_i32(tmp, cpu_areg[src >> 1]);
+ reg_src = tmp;
+ istmp = true;
+ } else {
+ reg_src = get_allreg(dc, gs, src);
+ istmp = false;
+ }
+
+ if (gd == 4 && dst == 6) {
+ /* Writes to ASTAT */
+ gen_astat_store(dc, reg_src);
+ } else if (gd == 4 && (dst == 0 || dst == 2)) {
+ /* Writes to A#.X */
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_andi_i64(cpu_areg[dst >> 1], cpu_areg[dst >> 1], 0xffffffff);
+ tcg_gen_extu_i32_i64(tmp64, reg_src);
+ tcg_gen_andi_i64(tmp64, tmp64, 0xff);
+ tcg_gen_shli_i64(tmp64, tmp64, 32);
+ tcg_gen_or_i64(cpu_areg[dst >> 1], cpu_areg[dst >> 1], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else if (gd == 4 && (dst == 1 || dst == 3)) {
+ /* Writes to A#.W */
+ tcg_gen_andi_i64(cpu_areg[dst >> 1], cpu_areg[dst >> 1], 0xff00000000);
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, reg_src);
+ tcg_gen_or_i64(cpu_areg[dst >> 1], cpu_areg[dst >> 1], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else if (gd == 6 && (dst == 1 || dst == 4)) {
+ /* Writes to LT# */
+ /* LT loads auto clear the LSB */
+ tcg_gen_andi_tl(cpu_ltreg[dst >> 2], reg_src, ~1);
+ } else {
+ reg_dst = get_allreg(dc, gd, dst);
+ tcg_gen_mov_tl(reg_dst, reg_src);
+ gen_maybe_lb_exit_tb(dc, reg_dst);
+ }
+
+ if (istmp)
+ tcg_temp_free(tmp);
+}
+
+static void
+decode_ALU2op_0(DisasContext *dc, uint16_t iw0)
+{
+ /* ALU2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 0 | 0 |.opc...........|.src.......|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> ALU2op_src_bits) & ALU2op_src_mask);
+ int opc = ((iw0 >> ALU2op_opc_bits) & ALU2op_opc_mask);
+ int dst = ((iw0 >> ALU2op_dst_bits) & ALU2op_dst_mask);
+ int l;
+ TCGv tmp;
+
+ TRACE_EXTRACT("opc:%i src:%i dst:%i", opc, src, dst);
+
+ if (opc == 0) {
+ /* Dreg{dst} >>>= Dreg{src}; */
+ l = gen_new_label();
+ tmp = tcg_temp_local_new();
+
+ /* Clip the shift magnitude to 31 bits */
+ tcg_gen_mov_tl(tmp, cpu_dreg[src]);
+ tcg_gen_brcondi_tl(TCG_COND_LEU, tmp, 31, l);
+ tcg_gen_movi_tl(tmp, 31);
+ gen_set_label(l);
+
+ tcg_gen_sar_tl(cpu_dreg[dst], cpu_dreg[dst], tmp);
+
+ tcg_temp_free(tmp);
+
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT_RT32, cpu_dreg[dst]);
+ } else if (opc == 1) {
+ /* Dreg{dst} >>= Dreg{src}; */
+ l = gen_new_label();
+ tmp = tcg_temp_local_new();
+
+ /* Clip the shift magnitude to 31 bits */
+ tcg_gen_mov_tl(tmp, cpu_dreg[src]);
+ tcg_gen_brcondi_tl(TCG_COND_LEU, tmp, 31, l);
+ tcg_gen_movi_tl(tmp, 0);
+ tcg_gen_mov_tl(cpu_dreg[dst], tmp);
+ gen_set_label(l);
+
+ tcg_gen_shr_tl(cpu_dreg[dst], cpu_dreg[dst], tmp);
+
+ tcg_temp_free(tmp);
+
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT_RT32, cpu_dreg[dst]);
+ } else if (opc == 2) {
+ /* Dreg{dst} <<= Dreg{src}; */
+ l = gen_new_label();
+ tmp = tcg_temp_local_new();
+
+ /* Clip the shift magnitude to 31 bits */
+ tcg_gen_mov_tl(tmp, cpu_dreg[src]);
+ tcg_gen_brcondi_tl(TCG_COND_LEU, tmp, 31, l);
+ tcg_gen_movi_tl(tmp, 0);
+ tcg_gen_mov_tl(cpu_dreg[dst], tmp);
+ gen_set_label(l);
+
+ tcg_gen_shl_tl(cpu_dreg[dst], cpu_dreg[dst], tmp);
+
+ tcg_temp_free(tmp);
+
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT32, cpu_dreg[dst]);
+ } else if (opc == 3) {
+ /* Dreg{dst} *= Dreg{src}; */
+ tcg_gen_mul_tl(cpu_dreg[dst], cpu_dreg[dst], cpu_dreg[src]);
+ } else if (opc == 4 || opc == 5) {
+ /* Dreg{dst} = (Dreg{dst} + Dreg{src}) << imm{opc}; */
+ tcg_gen_add_tl(cpu_dreg[dst], cpu_dreg[dst], cpu_dreg[src]);
+ tcg_gen_shli_tl(cpu_dreg[dst], cpu_dreg[dst], (opc - 3));
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT32, cpu_dreg[dst]);
+ } else if (opc == 8) {
+ /* DIVQ (Dreg, Dreg); */
+ gen_divq(cpu_dreg[dst], cpu_dreg[src]);
+ } else if (opc == 9) {
+ /* DIVS (Dreg, Dreg); */
+ gen_divs(cpu_dreg[dst], cpu_dreg[src]);
+ } else if (opc == 10) {
+ /* Dreg{dst} = Dreg_lo{src} (X); */
+ tcg_gen_ext16s_tl(cpu_dreg[dst], cpu_dreg[src]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 11) {
+ /* Dreg{dst} = Dreg_lo{src} (Z); */
+ tcg_gen_ext16u_tl(cpu_dreg[dst], cpu_dreg[src]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 12) {
+ /* Dreg{dst} = Dreg_byte{src} (X); */
+ tcg_gen_ext8s_tl(cpu_dreg[dst], cpu_dreg[src]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 13) {
+ /* Dreg{dst} = Dreg_byte{src} (Z); */
+ tcg_gen_ext8u_tl(cpu_dreg[dst], cpu_dreg[src]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 14) {
+ /* Dreg{dst} = -Dreg{src}; */
+ /* XXX: Documentation isn't entirely clear about av0 and av1. */
+ tcg_gen_neg_tl(cpu_dreg[dst], cpu_dreg[src]);
+ astat_queue_state1(dc, ASTAT_OP_NEGATE, cpu_dreg[dst]);
+ } else if (opc == 15) {
+ /* Dreg = ~Dreg; */
+ tcg_gen_not_tl(cpu_dreg[dst], cpu_dreg[src]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ }
+}
+
+static void
+decode_PTR2op_0(DisasContext *dc, uint16_t iw0)
+{
+ /* PTR2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 0 | 1 | 0 |.opc.......|.src.......|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> PTR2op_src_bits) & PTR2op_dst_mask);
+ int opc = ((iw0 >> PTR2op_opc_bits) & PTR2op_opc_mask);
+ int dst = ((iw0 >> PTR2op_dst_bits) & PTR2op_dst_mask);
+
+ TRACE_EXTRACT("opc:%i src:%i dst:%i", opc, src, dst);
+
+ if (opc == 0) {
+ /* Preg{dst} -= Preg{src}; */
+ tcg_gen_sub_tl(cpu_preg[dst], cpu_preg[dst], cpu_preg[src]);
+ } else if (opc == 1) {
+ /* Preg{dst} = Preg{src} << 2; */
+ tcg_gen_shli_tl(cpu_preg[dst], cpu_preg[src], 2);
+ } else if (opc == 3) {
+ /* Preg{dst} = Preg{src} >> 2; */
+ tcg_gen_shri_tl(cpu_preg[dst], cpu_preg[src], 2);
+ } else if (opc == 4) {
+ /* Preg{dst} = Preg{src} >> 1; */
+ tcg_gen_shri_tl(cpu_preg[dst], cpu_preg[src], 1);
+ } else if (opc == 5) {
+ /* Preg{dst} += Preg{src} (BREV); */
+ gen_helper_add_brev(cpu_preg[dst], cpu_preg[dst], cpu_preg[src]);
+ } else /*if (opc == 6 || opc == 7)*/ {
+ /* Preg{dst} = (Preg{dst} + Preg{src}) << imm{opc}; */
+ tcg_gen_add_tl(cpu_preg[dst], cpu_preg[dst], cpu_preg[src]);
+ tcg_gen_shli_tl(cpu_preg[dst], cpu_preg[dst], (opc - 5));
+ }
+}
+
+static void
+decode_LOGI2op_0(DisasContext *dc, uint16_t iw0)
+{
+ /* LOGI2op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 0 | 1 |.opc.......|.src...............|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src = ((iw0 >> LOGI2op_src_bits) & LOGI2op_src_mask);
+ int opc = ((iw0 >> LOGI2op_opc_bits) & LOGI2op_opc_mask);
+ int dst = ((iw0 >> LOGI2op_dst_bits) & LOGI2op_dst_mask);
+ int uimm = uimm5(src);
+ TCGv tmp;
+
+ TRACE_EXTRACT("opc:%i src:%i dst:%i", opc, src, dst);
+
+ if (opc == 0) {
+ /* CC = ! BITTST (Dreg{dst}, imm{uimm}); */
+ tmp = tcg_temp_new();
+ tcg_gen_movi_tl(tmp, 1 << uimm);
+ tcg_gen_and_tl(tmp, tmp, cpu_dreg[dst]);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_cc, tmp, 0);
+ tcg_temp_free(tmp);
+ } else if (opc == 1) {
+ /* CC = BITTST (Dreg{dst}, imm{uimm}); */
+ tmp = tcg_temp_new();
+ tcg_gen_movi_tl(tmp, 1 << uimm);
+ tcg_gen_and_tl(tmp, tmp, cpu_dreg[dst]);
+ tcg_gen_setcondi_tl(TCG_COND_NE, cpu_cc, tmp, 0);
+ tcg_temp_free(tmp);
+ } else if (opc == 2) {
+ /* BITSET (Dreg{dst}, imm{uimm}); */
+ tcg_gen_ori_tl(cpu_dreg[dst], cpu_dreg[dst], 1 << uimm);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 3) {
+ /* BITTGL (Dreg{dst}, imm{uimm}); */
+ tcg_gen_xori_tl(cpu_dreg[dst], cpu_dreg[dst], 1 << uimm);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 4) {
+ /* BITCLR (Dreg{dst}, imm{uimm}); */
+ tcg_gen_andi_tl(cpu_dreg[dst], cpu_dreg[dst], ~(1 << uimm));
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 5) {
+ /* Dreg{dst} >>>= imm{uimm}; */
+ tcg_gen_sari_tl(cpu_dreg[dst], cpu_dreg[dst], uimm);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT_RT32, cpu_dreg[dst]);
+ } else if (opc == 6) {
+ /* Dreg{dst} >>= imm{uimm}; */
+ tcg_gen_shri_tl(cpu_dreg[dst], cpu_dreg[dst], uimm);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT_RT32, cpu_dreg[dst]);
+ } else /*if (opc == 7)*/ {
+ /* Dreg{dst} <<= imm{uimm}; */
+ tcg_gen_shli_tl(cpu_dreg[dst], cpu_dreg[dst], uimm);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT32, cpu_dreg[dst]);
+ }
+}
+
+static void
+decode_COMP3op_0(DisasContext *dc, uint16_t iw0)
+{
+ /* COMP3op
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 0 | 1 |.opc.......|.dst.......|.src1......|.src0......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int opc = ((iw0 >> COMP3op_opc_bits) & COMP3op_opc_mask);
+ int dst = ((iw0 >> COMP3op_dst_bits) & COMP3op_dst_mask);
+ int src0 = ((iw0 >> COMP3op_src0_bits) & COMP3op_src0_mask);
+ int src1 = ((iw0 >> COMP3op_src1_bits) & COMP3op_src1_mask);
+ TCGv tmp;
+
+ TRACE_EXTRACT("opc:%i dst:%i src1:%i src0:%i",
+ opc, dst, src1, src0);
+
+ tmp = tcg_temp_local_new();
+ if (opc == 0) {
+ /* Dreg{dst} = Dreg{src0} + Dreg{src1}; */
+ tcg_gen_add_tl(tmp, cpu_dreg[src0], cpu_dreg[src1]);
+ astat_queue_state3(dc, ASTAT_OP_ADD32, tmp, cpu_dreg[src0], cpu_dreg[src1]);
+ tcg_gen_mov_tl(cpu_dreg[dst], tmp);
+ } else if (opc == 1) {
+ /* Dreg{dst} = Dreg{src0} - Dreg{src1}; */
+ tcg_gen_sub_tl(tmp, cpu_dreg[src0], cpu_dreg[src1]);
+ astat_queue_state3(dc, ASTAT_OP_SUB32, tmp, cpu_dreg[src0], cpu_dreg[src1]);
+ tcg_gen_mov_tl(cpu_dreg[dst], tmp);
+ } else if (opc == 2) {
+ /* Dreg{dst} = Dreg{src0} & Dreg{src1}; */
+ tcg_gen_and_tl(cpu_dreg[dst], cpu_dreg[src0], cpu_dreg[src1]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 3) {
+ /* Dreg{dst} = Dreg{src0} | Dreg{src1}; */
+ tcg_gen_or_tl(cpu_dreg[dst], cpu_dreg[src0], cpu_dreg[src1]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 4) {
+ /* Dreg{dst} = Dreg{src0} ^ Dreg{src1}; */
+ tcg_gen_xor_tl(cpu_dreg[dst], cpu_dreg[src0], cpu_dreg[src1]);
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst]);
+ } else if (opc == 5) {
+ /* Preg{dst} = Preg{src0} + Preg{src1}; */
+ /* If src0 == src1 this is disassembled as a shift by 1, but this
+ distinction doesn't matter for our purposes */
+ tcg_gen_add_tl(cpu_preg[dst], cpu_preg[src0], cpu_preg[src1]);
+ } else /*if (opc == 6 || opc == 7)*/ {
+ /* Preg{dst} = Preg{src0} + Preg{src1} << imm{opc}; */
+ /* The dst/src0/src1 might all be the same register, so we need
+ the temp here to avoid clobbering source values too early.
+ This could be optimized a little, but for now we'll leave it. */
+ tcg_gen_shli_tl(tmp, cpu_preg[src1], (opc - 5));
+ tcg_gen_add_tl(cpu_preg[dst], cpu_preg[src0], tmp);
+ }
+ tcg_temp_free(tmp);
+}
+
+static void
+decode_COMPI2opD_0(DisasContext *dc, uint16_t iw0)
+{
+ /* COMPI2opD
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 1 | 0 | 0 |.op|..src......................|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> COMPI2opD_op_bits) & COMPI2opD_op_mask);
+ int dst = ((iw0 >> COMPI2opD_dst_bits) & COMPI2opD_dst_mask);
+ int src = ((iw0 >> COMPI2opD_src_bits) & COMPI2opD_src_mask);
+ int imm = imm7(src);
+ TCGv tmp;
+
+ TRACE_EXTRACT("op:%i src:%i dst:%i", op, src, dst);
+
+ if (op == 0) {
+ /* Dreg{dst} = imm{src} (X); */
+ tcg_gen_movi_tl(cpu_dreg[dst], imm);
+ } else {
+ /* Dreg{dst} += imm{src}; */
+ tmp = tcg_const_tl(imm);
+ tcg_gen_mov_tl(cpu_astat_arg[1], cpu_dreg[dst]);
+ tcg_gen_add_tl(cpu_dreg[dst], cpu_astat_arg[1], tmp);
+ astat_queue_state3(dc, ASTAT_OP_ADD32, cpu_dreg[dst], cpu_astat_arg[1], tmp);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void
+decode_COMPI2opP_0(DisasContext *dc, uint16_t iw0)
+{
+ /* COMPI2opP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 0 | 1 | 1 | 0 | 1 |.op|.src.......................|.dst.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op = ((iw0 >> COMPI2opP_op_bits) & COMPI2opP_op_mask);
+ int src = ((iw0 >> COMPI2opP_src_bits) & COMPI2opP_src_mask);
+ int dst = ((iw0 >> COMPI2opP_dst_bits) & COMPI2opP_dst_mask);
+ int imm = imm7(src);
+
+ TRACE_EXTRACT("op:%i src:%i dst:%i", op, src, dst);
+
+ if (op == 0) {
+ /* Preg{dst} = imm{src}; */
+ tcg_gen_movi_tl(cpu_preg[dst], imm);
+ } else {
+ /* Preg{dst} += imm{src}; */
+ tcg_gen_addi_tl(cpu_preg[dst], cpu_preg[dst], imm);
+ }
+}
+
+static void
+decode_LDSTpmod_0(DisasContext *dc, uint16_t iw0)
+{
+ /* LDSTpmod
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
+ int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
+ int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
+ int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
+ int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
+ TCGv tmp;
+
+ TRACE_EXTRACT("W:%i aop:%i reg:%i idx:%i ptr:%i",
+ W, aop, reg, idx, ptr);
+
+ if (aop == 1 && W == 0 && idx == ptr) {
+ /* Dreg_lo{reg} = W[Preg{ptr}]; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_andi_tl(cpu_dreg[reg], cpu_dreg[reg], 0xffff0000);
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_preg[ptr]);
+ tcg_gen_or_tl(cpu_dreg[reg], cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ } else if (aop == 2 && W == 0 && idx == ptr) {
+ /* Dreg_hi{reg} = W[Preg{ptr}]; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_andi_tl(cpu_dreg[reg], cpu_dreg[reg], 0xffff);
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_preg[ptr]);
+ tcg_gen_shli_tl(tmp, tmp, 16);
+ tcg_gen_or_tl(cpu_dreg[reg], cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ } else if (aop == 1 && W == 1 && idx == ptr) {
+ /* W[Preg{ptr}] = Dreg_lo{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ } else if (aop == 2 && W == 1 && idx == ptr) {
+ /* W[Preg{ptr}] = Dreg_hi{reg}; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_shri_tl(tmp, cpu_dreg[reg], 16);
+ gen_aligned_qemu_st16(dc, tmp, cpu_preg[ptr]);
+ tcg_temp_free(tmp);
+ } else if (aop == 0 && W == 0) {
+ /* Dreg{reg} = [Preg{ptr} ++ Preg{idx}]; */
+ gen_aligned_qemu_ld32u(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ } else if (aop == 1 && W == 0) {
+ /* Dreg_lo{reg} = W[Preg{ptr} ++ Preg{idx}]; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_andi_tl(cpu_dreg[reg], cpu_dreg[reg], 0xffff0000);
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_preg[ptr]);
+ tcg_gen_or_tl(cpu_dreg[reg], cpu_dreg[reg], tmp);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ tcg_temp_free(tmp);
+ } else if (aop == 2 && W == 0) {
+ /* Dreg_hi{reg} = W[Preg{ptr} ++ Preg{idx}]; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_andi_tl(cpu_dreg[reg], cpu_dreg[reg], 0xffff);
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_preg[ptr]);
+ tcg_gen_shli_tl(tmp, tmp, 16);
+ tcg_gen_or_tl(cpu_dreg[reg], cpu_dreg[reg], tmp);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ tcg_temp_free(tmp);
+ } else if (aop == 3 && W == 0) {
+ /* R%i = W[Preg{ptr} ++ Preg{idx}] (Z); */
+ gen_aligned_qemu_ld16u(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ } else if (aop == 3 && W == 1) {
+ /* R%i = W[Preg{ptr} ++ Preg{idx}] (X); */
+ gen_aligned_qemu_ld16s(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ } else if (aop == 0 && W == 1) {
+ /* [Preg{ptr} ++ Preg{idx}] = R%i; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ } else if (aop == 1 && W == 1) {
+ /* W[Preg{ptr} ++ Preg{idx}] = Dreg_lo{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ } else if (aop == 2 && W == 1) {
+ /* W[Preg{ptr} ++ Preg{idx}] = Dreg_hi{reg}; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_shri_tl(tmp, cpu_dreg[reg], 16);
+ gen_aligned_qemu_st16(dc, tmp, cpu_preg[ptr]);
+ if (ptr != idx) {
+ tcg_gen_add_tl(cpu_preg[ptr], cpu_preg[ptr], cpu_preg[idx]);
+ }
+ tcg_temp_free(tmp);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_dagMODim_0(DisasContext *dc, uint16_t iw0)
+{
+ /* dagMODim
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
+ int m = ((iw0 >> DagMODim_m_bits) & DagMODim_m_mask);
+ int br = ((iw0 >> DagMODim_br_bits) & DagMODim_br_mask);
+ int op = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
+
+ TRACE_EXTRACT("br:%i op:%i m:%i i:%i", br, op, m, i);
+
+ if (op == 0 && br == 1) {
+ /* Ireg{i} += Mreg{m} (BREV); */
+ gen_helper_add_brev(cpu_ireg[i], cpu_ireg[i], cpu_mreg[m]);
+ } else if (op == 0) {
+ /* Ireg{i} += Mreg{m}; */
+ gen_dagadd(dc, i, cpu_mreg[m]);
+ } else if (op == 1 && br == 0) {
+ /* Ireg{i} -= Mreg{m}; */
+ gen_dagsub(dc, i, cpu_mreg[m]);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_dagMODik_0(DisasContext *dc, uint16_t iw0)
+{
+ /* dagMODik
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
+ int op = ((iw0 >> DagMODik_op_bits) & DagMODik_op_mask);
+ int mod = (op & 2) + 2;
+
+ TRACE_EXTRACT("op:%i i:%i", op, i);
+
+ if (op & 1) {
+ /* Ireg{i} -= 2 or 4; */
+ gen_dagsubi(dc, i, mod);
+ } else {
+ /* Ireg{i} += 2 or 4; */
+ gen_dagaddi(dc, i, mod);
+ }
+}
+
+static void
+disalgnexcpt_ld32u(DisasContext *dc, TCGv ret, TCGv addr)
+{
+ if (dc->disalgnexcpt) {
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_andi_tl(tmp, addr, ~0x3);
+ tcg_gen_qemu_ld32u(ret, tmp, dc->mem_idx);
+ tcg_temp_free(tmp);
+ } else {
+ gen_aligned_qemu_ld32u(dc, ret, addr);
+ }
+}
+
+static void
+decode_dspLDST_0(DisasContext *dc, uint16_t iw0)
+{
+ /* dspLDST
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
+ int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
+ int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
+ int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
+ int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
+ TCGv tmp;
+
+ TRACE_EXTRACT("aop:%i m:%i i:%i reg:%i", aop, m, i, reg);
+
+ if (aop == 0 && W == 0 && m == 0) {
+ /* Dreg{reg} = [Ireg{i}++]; */
+ disalgnexcpt_ld32u(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagaddi(dc, i, 4);
+ } else if (aop == 0 && W == 0 && m == 1) {
+ /* Dreg_lo{reg} = W[Ireg{i}++]; */
+ tmp = tcg_temp_local_new();
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_ireg[i]);
+ gen_mov_l_tl(cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ gen_dagaddi(dc, i, 2);
+ } else if (aop == 0 && W == 0 && m == 2) {
+ /* Dreg_hi{reg} = W[Ireg{i}++]; */
+ tmp = tcg_temp_local_new();
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_ireg[i]);
+ gen_mov_h_tl(cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ gen_dagaddi(dc, i, 2);
+ } else if (aop == 1 && W == 0 && m == 0) {
+ /* Dreg{reg} = [Ireg{i}--]; */
+ disalgnexcpt_ld32u(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagsubi(dc, i, 4);
+ } else if (aop == 1 && W == 0 && m == 1) {
+ /* Dreg_lo{reg} = W[Ireg{i}--]; */
+ tmp = tcg_temp_local_new();
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_ireg[i]);
+ gen_mov_l_tl(cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ gen_dagsubi(dc, i, 2);
+ } else if (aop == 1 && W == 0 && m == 2) {
+ /* Dreg_hi{reg} = W[Ireg{i}--]; */
+ tmp = tcg_temp_local_new();
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_ireg[i]);
+ gen_mov_h_tl(cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ gen_dagsubi(dc, i, 2);
+ } else if (aop == 2 && W == 0 && m == 0) {
+ /* Dreg{reg} = [Ireg{i}]; */
+ disalgnexcpt_ld32u(dc, cpu_dreg[reg], cpu_ireg[i]);
+ } else if (aop == 2 && W == 0 && m == 1) {
+ /* Dreg_lo{reg} = W[Ireg{i}]; */
+ tmp = tcg_temp_local_new();
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_ireg[i]);
+ gen_mov_l_tl(cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ } else if (aop == 2 && W == 0 && m == 2) {
+ /* Dreg_hi{reg} = W[Ireg{i}]; */
+ tmp = tcg_temp_local_new();
+ gen_aligned_qemu_ld16u(dc, tmp, cpu_ireg[i]);
+ gen_mov_h_tl(cpu_dreg[reg], tmp);
+ tcg_temp_free(tmp);
+ } else if (aop == 0 && W == 1 && m == 0) {
+ /* [Ireg{i}++] = Dreg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagaddi(dc, i, 4);
+ } else if (aop == 0 && W == 1 && m == 1) {
+ /* W[Ireg{i}++] = Dreg_lo{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagaddi(dc, i, 2);
+ } else if (aop == 0 && W == 1 && m == 2) {
+ /* W[Ireg{i}++] = Dreg_hi{reg}; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_shri_tl(tmp, cpu_dreg[reg], 16);
+ gen_aligned_qemu_st16(dc, tmp, cpu_ireg[i]);
+ tcg_temp_free(tmp);
+ gen_dagaddi(dc, i, 2);
+ } else if (aop == 1 && W == 1 && m == 0) {
+ /* [Ireg{i}--] = Dreg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagsubi(dc, i, 4);
+ } else if (aop == 1 && W == 1 && m == 1) {
+ /* W[Ireg{i}--] = Dreg_lo{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagsubi(dc, i, 2);
+ } else if (aop == 1 && W == 1 && m == 2) {
+ /* W[Ireg{i}--] = Dreg_hi{reg}; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_shri_tl(tmp, cpu_dreg[reg], 16);
+ gen_aligned_qemu_st16(dc, tmp, cpu_ireg[i]);
+ tcg_temp_free(tmp);
+ gen_dagsubi(dc, i, 2);
+ } else if (aop == 2 && W == 1 && m == 0) {
+ /* [Ireg{i}] = Dreg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], cpu_ireg[i]);
+ } else if (aop == 2 && W == 1 && m == 1) {
+ /* W[Ireg{i}] = Dreg_lo{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], cpu_ireg[i]);
+ } else if (aop == 2 && W == 1 && m == 2) {
+ /* W[Ireg{i}] = Dreg_hi{reg}; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_shri_tl(tmp, cpu_dreg[reg], 16);
+ gen_aligned_qemu_st16(dc, tmp, cpu_ireg[i]);
+ tcg_temp_free(tmp);
+ } else if (aop == 3 && W == 0) {
+ /* Dreg{reg} = [Ireg{i} ++ Mreg{m}]; */
+ disalgnexcpt_ld32u(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagadd(dc, i, cpu_mreg[m]);
+ } else if (aop == 3 && W == 1) {
+ /* [Ireg{i} ++ Mreg{m}] = Dreg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], cpu_ireg[i]);
+ gen_dagadd(dc, i, cpu_mreg[m]);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_LDST_0(DisasContext *dc, uint16_t iw0)
+{
+ /* LDST
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
+ int W = ((iw0 >> LDST_W_bits) & LDST_W_mask);
+ int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
+ int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
+ int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
+ int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask);
+
+ TRACE_EXTRACT("sz:%i W:%i aop:%i Z:%i ptr:%i reg:%i",
+ sz, W, aop, Z, ptr, reg);
+
+ if (aop == 3) {
+ illegal_instruction(dc);
+ }
+
+ if (W == 0) {
+ if (sz == 0 && Z == 0) {
+ /* Dreg{reg} = [Preg{ptr}{aop}]; */
+ gen_aligned_qemu_ld32u(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ } else if (sz == 0 && Z == 1) {
+ /* Preg{reg} = [Preg{ptr}{aop}]; */
+ /*if (aop < 2 && ptr == reg)
+ illegal_instruction_combination(dc);*/
+ gen_aligned_qemu_ld32u(dc, cpu_preg[reg], cpu_preg[ptr]);
+ } else if (sz == 1 && Z == 0) {
+ /* Dreg{reg} = W[Preg{ptr}{aop}] (Z); */
+ gen_aligned_qemu_ld16u(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ } else if (sz == 1 && Z == 1) {
+ /* Dreg{reg} = W[Preg{ptr}{aop}] (X); */
+ gen_aligned_qemu_ld16s(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ } else if (sz == 2 && Z == 0) {
+ /* Dreg{reg} = B[Preg{ptr}{aop}] (Z); */
+ tcg_gen_qemu_ld8u(cpu_dreg[reg], cpu_preg[ptr], dc->mem_idx);
+ } else if (sz == 2 && Z == 1) {
+ /* Dreg{reg} = B[Preg{ptr}{aop}] (X); */
+ tcg_gen_qemu_ld8s(cpu_dreg[reg], cpu_preg[ptr], dc->mem_idx);
+ } else {
+ illegal_instruction(dc);
+ }
+ } else {
+ if (sz == 0 && Z == 0) {
+ /* [Preg{ptr}{aop}] = Dreg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ } else if (sz == 0 && Z == 1) {
+ /* [Preg{ptr}{aop}] = Preg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_preg[reg], cpu_preg[ptr]);
+ } else if (sz == 1 && Z == 0) {
+ /* W[Preg{ptr}{aop}] = Dreg{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], cpu_preg[ptr]);
+ } else if (sz == 2 && Z == 0) {
+ /* B[Preg{ptr}{aop}] = Dreg{reg}; */
+ tcg_gen_qemu_st8(cpu_dreg[reg], cpu_preg[ptr], dc->mem_idx);
+ } else {
+ illegal_instruction(dc);
+ }
+ }
+
+ if (aop == 0) {
+ tcg_gen_addi_tl(cpu_preg[ptr], cpu_preg[ptr], 1 << (2 - sz));
+ }
+ if (aop == 1) {
+ tcg_gen_subi_tl(cpu_preg[ptr], cpu_preg[ptr], 1 << (2 - sz));
+ }
+}
+
+static void
+decode_LDSTiiFP_0(DisasContext *dc, uint16_t iw0)
+{
+ /* LDSTiiFP
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ /* This isn't exactly a grp:reg as this insn only supports Dregs & Pregs,
+ but for our usage, its functionality the same thing. */
+ int grp = ((iw0 >> 3) & 0x1);
+ int reg = ((iw0 >> LDSTiiFP_reg_bits) & 0x7 /*LDSTiiFP_reg_mask*/);
+ int offset = ((iw0 >> LDSTiiFP_offset_bits) & LDSTiiFP_offset_mask);
+ int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
+ uint32_t imm = negimm5s4(offset);
+ TCGv treg = get_allreg(dc, grp, reg);
+ TCGv ea;
+
+ TRACE_EXTRACT("W:%i offset:%#x grp:%i reg:%i",
+ W, offset, grp, reg);
+
+ ea = tcg_temp_local_new();
+ tcg_gen_addi_tl(ea, cpu_fpreg, imm);
+ gen_align_check(dc, ea, 4, false);
+ if (W == 0) {
+ /* DPreg{reg} = [FP + imm{offset}]; */
+ tcg_gen_qemu_ld32u(treg, ea, dc->mem_idx);
+ } else {
+ /* [FP + imm{offset}] = DPreg{reg}; */
+ tcg_gen_qemu_st32(treg, ea, dc->mem_idx);
+ }
+ tcg_temp_free(ea);
+}
+
+static void
+decode_LDSTii_0(DisasContext *dc, uint16_t iw0)
+{
+ /* LDSTii
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
+ int ptr = ((iw0 >> LDSTii_ptr_bit) & LDSTii_ptr_mask);
+ int offset = ((iw0 >> LDSTii_offset_bit) & LDSTii_offset_mask);
+ int op = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
+ int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
+ uint32_t imm;
+ TCGv ea;
+
+ TRACE_EXTRACT("W:%i op:%i offset:%#x ptr:%i reg:%i",
+ W, op, offset, ptr, reg);
+
+ if (op == 0 || op == 3) {
+ imm = uimm4s4(offset);
+ } else {
+ imm = uimm4s2(offset);
+ }
+
+ ea = tcg_temp_local_new();
+ tcg_gen_addi_tl(ea, cpu_preg[ptr], imm);
+ if (W == 0) {
+ if (op == 0) {
+ /* Dreg{reg} = [Preg{ptr} + imm{offset}]; */
+ gen_aligned_qemu_ld32u(dc, cpu_dreg[reg], ea);
+ } else if (op == 1) {
+ /* Dreg{reg} = W[Preg{ptr} + imm{offset}] (Z); */
+ gen_aligned_qemu_ld16u(dc, cpu_dreg[reg], ea);
+ } else if (op == 2) {
+ /* Dreg{reg} = W[Preg{ptr} + imm{offset}] (X); */
+ gen_aligned_qemu_ld16s(dc, cpu_dreg[reg], ea);
+ } else if (op == 3) {
+ /* P%i = [Preg{ptr} + imm{offset}]; */
+ gen_aligned_qemu_ld32u(dc, cpu_preg[reg], ea);
+ }
+ } else {
+ if (op == 0) {
+ /* [Preg{ptr} + imm{offset}] = Dreg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], ea);
+ } else if (op == 1) {
+ /* W[Preg{ptr} + imm{offset}] = Dreg{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], ea);
+ } else if (op == 3) {
+ /* [Preg{ptr} + imm{offset}] = P%i; */
+ gen_aligned_qemu_st32(dc, cpu_preg[reg], ea);
+ } else {
+ illegal_instruction(dc);
+ }
+ }
+ tcg_temp_free(ea);
+}
+
+static void
+decode_LoopSetup_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* LoopSetup
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |.rop...|.c.|.soffset.......|
+ |.reg...........| - | - |.eoffset...............................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int c = ((iw0 >> (LoopSetup_c_bits - 16)) & LoopSetup_c_mask);
+ int reg = ((iw1 >> LoopSetup_reg_bits) & LoopSetup_reg_mask);
+ int rop = ((iw0 >> (LoopSetup_rop_bits - 16)) & LoopSetup_rop_mask);
+ int soffset = ((iw0 >> (LoopSetup_soffset_bits - 16)) & LoopSetup_soffset_mask);
+ int eoffset = ((iw1 >> LoopSetup_eoffset_bits) & LoopSetup_eoffset_mask);
+ int spcrel = pcrel4(soffset);
+ int epcrel = lppcrel10(eoffset);
+
+ TRACE_EXTRACT("rop:%i c:%i soffset:%i reg:%i eoffset:%i",
+ rop, c, soffset, reg, eoffset);
+
+ if (rop == 0) {
+ /* LSETUP (imm{soffset}, imm{eoffset}) LCreg{c}; */;
+ } else if (rop == 1 && reg <= 7) {
+ /* LSETUP (imm{soffset}, imm{eoffset}) LCreg{c} = Preg{reg}; */
+ tcg_gen_mov_tl(cpu_lcreg[c], cpu_preg[reg]);
+ } else if (rop == 3 && reg <= 7) {
+ /* LSETUP (imm{soffset}, imm{eoffset}) LCreg{c} = Preg{reg} >> 1; */
+ tcg_gen_shri_tl(cpu_lcreg[c], cpu_preg[reg], 1);
+ } else {
+ illegal_instruction(dc);
+ }
+
+ tcg_gen_movi_tl(cpu_ltreg[c], dc->pc + spcrel);
+ tcg_gen_movi_tl(cpu_lbreg[c], dc->pc + epcrel);
+ gen_gotoi_tb(dc, 0, dc->pc + 4);
+}
+
+static void
+decode_LDIMMhalf_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* LDIMMhalf
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |.Z.|.H.|.S.|.grp...|.reg.......|
+ |.hword.........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int H = ((iw0 >> (LDIMMhalf_H_bits - 16)) & LDIMMhalf_H_mask);
+ int Z = ((iw0 >> (LDIMMhalf_Z_bits - 16)) & LDIMMhalf_Z_mask);
+ int S = ((iw0 >> (LDIMMhalf_S_bits - 16)) & LDIMMhalf_S_mask);
+ int reg = ((iw0 >> (LDIMMhalf_reg_bits - 16)) & LDIMMhalf_reg_mask);
+ int grp = ((iw0 >> (LDIMMhalf_grp_bits - 16)) & LDIMMhalf_grp_mask);
+ int hword = ((iw1 >> LDIMMhalf_hword_bits) & LDIMMhalf_hword_mask);
+ uint32_t val;
+ TCGv treg;
+
+ TRACE_EXTRACT("Z:%i H:%i S:%i grp:%i reg:%i hword:%#x",
+ Z, H, S, grp, reg, hword);
+
+ treg = get_allreg(dc, grp, reg);
+ if (S == 1) {
+ val = imm16(hword);
+ } else {
+ val = luimm16(hword);
+ }
+
+ if (H == 0 && S == 1 && Z == 0) {
+ /* genreg{grp,reg} = imm{hword} (X); */
+ /* Take care of immediate sign extension ourselves */
+ tcg_gen_movi_i32(treg, (int16_t)val);
+ } else if (H == 0 && S == 0 && Z == 1) {
+ /* genreg{grp,reg} = imm{hword} (Z); */
+ tcg_gen_movi_i32(treg, val);
+ } else if (H == 0 && S == 0 && Z == 0) {
+ /* genreg_lo{grp,reg} = imm{hword}; */
+ /* XXX: Convert this to a helper. */
+ tcg_gen_andi_tl(treg, treg, 0xffff0000);
+ tcg_gen_ori_tl(treg, treg, val);
+ } else if (H == 1 && S == 0 && Z == 0) {
+ /* genreg_hi{grp,reg} = imm{hword}; */
+ /* XXX: Convert this to a helper. */
+ tcg_gen_andi_tl(treg, treg, 0xffff);
+ tcg_gen_ori_tl(treg, treg, val << 16);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_CALLa_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* CALLa
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 0 | 1 |.S.|.msw...........................|
+ |.lsw...........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int S = ((iw0 >> (CALLa_S_bits - 16)) & CALLa_S_mask);
+ int lsw = ((iw1 >> 0) & 0xffff);
+ int msw = ((iw0 >> 0) & 0xff);
+ int pcrel = pcrel24((msw << 16) | lsw);
+
+ TRACE_EXTRACT("S:%i msw:%#x lsw:%#x", S, msw, lsw);
+
+ if (S == 1) {
+ /* CALL imm{pcrel}; */
+ dc->is_jmp = DISAS_CALL;
+ } else {
+ /* JUMP.L imm{pcrel}; */
+ dc->is_jmp = DISAS_JUMP;
+ }
+ dc->hwloop_callback = gen_hwloop_br_pcrel_imm;
+ dc->hwloop_data = (void *)(unsigned long)pcrel;
+}
+
+static void
+decode_LDSTidxI_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* LDSTidxI
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 0 | 1 |.W.|.Z.|.sz....|.ptr.......|.reg.......|
+ |.offset........................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int Z = ((iw0 >> (LDSTidxI_Z_bits - 16)) & LDSTidxI_Z_mask);
+ int W = ((iw0 >> (LDSTidxI_W_bits - 16)) & LDSTidxI_W_mask);
+ int sz = ((iw0 >> (LDSTidxI_sz_bits - 16)) & LDSTidxI_sz_mask);
+ int reg = ((iw0 >> (LDSTidxI_reg_bits - 16)) & LDSTidxI_reg_mask);
+ int ptr = ((iw0 >> (LDSTidxI_ptr_bits - 16)) & LDSTidxI_ptr_mask);
+ int offset = ((iw1 >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask);
+ uint32_t imm_16s4 = imm16s4(offset);
+ uint32_t imm_16s2 = imm16s2(offset);
+ uint32_t imm_16 = imm16(offset);
+ TCGv ea;
+
+ TRACE_EXTRACT("W:%i Z:%i sz:%i ptr:%i reg:%i offset:%#x",
+ W, Z, sz, ptr, reg, offset);
+
+ ea = tcg_temp_local_new();
+ if (sz == 0) {
+ tcg_gen_addi_tl(ea, cpu_preg[ptr], imm_16s4);
+ } else if (sz == 1) {
+ tcg_gen_addi_tl(ea, cpu_preg[ptr], imm_16s2);
+ } else if (sz == 2) {
+ tcg_gen_addi_tl(ea, cpu_preg[ptr], imm_16);
+ } else {
+ illegal_instruction(dc);
+ }
+
+ if (W == 0) {
+ if (sz == 0 && Z == 0) {
+ /* Dreg{reg} = [Preg{ptr] + imm{offset}]; */
+ gen_aligned_qemu_ld32u(dc, cpu_dreg[reg], ea);
+ } else if (sz == 0 && Z == 1) {
+ /* Preg{reg} = [Preg{ptr] + imm{offset}]; */
+ gen_aligned_qemu_ld32u(dc, cpu_preg[reg], ea);
+ } else if (sz == 1 && Z == 0) {
+ /* Dreg{reg} = W[Preg{ptr] + imm{offset}] (Z); */
+ gen_aligned_qemu_ld16u(dc, cpu_dreg[reg], ea);
+ } else if (sz == 1 && Z == 1) {
+ /* Dreg{reg} = W[Preg{ptr} imm{offset}] (X); */
+ gen_aligned_qemu_ld16s(dc, cpu_dreg[reg], ea);
+ } else if (sz == 2 && Z == 0) {
+ /* Dreg{reg} = B[Preg{ptr} + imm{offset}] (Z); */
+ tcg_gen_qemu_ld8u(cpu_dreg[reg], ea, dc->mem_idx);
+ } else if (sz == 2 && Z == 1) {
+ /* Dreg{reg} = B[Preg{ptr} + imm{offset}] (X); */
+ tcg_gen_qemu_ld8s(cpu_dreg[reg], ea, dc->mem_idx);
+ }
+ } else {
+ if (sz == 0 && Z == 0) {
+ /* [Preg{ptr} + imm{offset}] = Dreg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_dreg[reg], ea);
+ } else if (sz == 0 && Z == 1) {
+ /* [Preg{ptr} + imm{offset}] = Preg{reg}; */
+ gen_aligned_qemu_st32(dc, cpu_preg[reg], ea);
+ } else if (sz == 1 && Z == 0) {
+ /* W[Preg{ptr} + imm{offset}] = Dreg{reg}; */
+ gen_aligned_qemu_st16(dc, cpu_dreg[reg], ea);
+ } else if (sz == 2 && Z == 0) {
+ /* B[Preg{ptr} + imm{offset}] = Dreg{reg}; */
+ tcg_gen_qemu_st8(cpu_dreg[reg], ea, dc->mem_idx);
+ } else {
+ illegal_instruction(dc);
+ }
+ }
+
+ tcg_temp_free(ea);
+}
+
+static void
+decode_linkage_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* linkage
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |.R.|
+ |.framesize.....................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int R = ((iw0 >> (Linkage_R_bits - 16)) & Linkage_R_mask);
+ int framesize = ((iw1 >> Linkage_framesize_bits) & Linkage_framesize_mask);
+
+ TRACE_EXTRACT("R:%i framesize:%#x", R, framesize);
+
+ /* XXX: Should do alignment checks of fp/sp */
+
+ if (R == 0) {
+ /* LINK imm{framesize}; */
+ int size = uimm16s4(framesize);
+ tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
+ tcg_gen_qemu_st32(cpu_rets, cpu_spreg, dc->mem_idx);
+ tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
+ tcg_gen_qemu_st32(cpu_fpreg, cpu_spreg, dc->mem_idx);
+ tcg_gen_mov_tl(cpu_fpreg, cpu_spreg);
+ tcg_gen_subi_tl(cpu_spreg, cpu_spreg, size);
+ } else if (framesize == 0) {
+ /* UNLINK; */
+ /* Restore SP from FP. */
+ tcg_gen_mov_tl(cpu_spreg, cpu_fpreg);
+ tcg_gen_qemu_ld32u(cpu_fpreg, cpu_spreg, dc->mem_idx);
+ tcg_gen_addi_tl(cpu_spreg, cpu_spreg, 4);
+ tcg_gen_qemu_ld32u(cpu_rets, cpu_spreg, dc->mem_idx);
+ tcg_gen_addi_tl(cpu_spreg, cpu_spreg, 4);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_dsp32mac_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* XXX: Very incomplete. */
+ /* dsp32mac
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
+ |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
+ int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+ int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+ int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
+ int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+ int M = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
+ int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+ int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
+ int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
+ int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+ int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
+ int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
+ int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
+ int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
+ int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
+
+ int v_i = 0;
+ TCGv res;
+
+ TRACE_EXTRACT("M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
+ "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
+ M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
+ dst, src0, src1);
+
+ res = tcg_temp_local_new();
+ tcg_gen_mov_tl(res, cpu_dreg[dst]);
+ if (w1 == 1 || op1 != 3) {
+ TCGv res1 = decode_macfunc (dc, 1, op1, h01, h11, src0, src1, mmod, MM, P, &v_i);
+ if (w1) {
+ if (P) {
+ tcg_gen_mov_tl(cpu_dreg[dst + 1], res1);
+ } else {
+ gen_mov_h_tl(res, res1);
+ }
+ }
+ tcg_temp_free(res1);
+ }
+ if (w0 == 1 || op0 != 3) {
+ TCGv res0 = decode_macfunc (dc, 0, op0, h00, h10, src0, src1, mmod, 0, P, &v_i);
+ if (w0) {
+ if (P) {
+ tcg_gen_mov_tl(cpu_dreg[dst], res0);
+ } else {
+ gen_mov_l_tl(res, res0);
+ }
+ }
+ tcg_temp_free(res0);
+ }
+
+ if (!P && (w0 || w1)) {
+ tcg_gen_mov_tl(cpu_dreg[dst], res);
+ }
+
+ tcg_temp_free(res);
+}
+
+static void
+decode_dsp32mult_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* XXX: Very incomplete. */
+
+ /* dsp32mult
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
+ |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
+ int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+ int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+ int MM = ((iw0 >> (DSP32Mac_MM_bits - 16)) & DSP32Mac_MM_mask);
+ int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+ int M = ((iw0 >> (DSP32Mac_M_bits - 16)) & DSP32Mac_M_mask);
+ int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+ int src0 = ((iw1 >> DSP32Mac_src0_bits) & DSP32Mac_src0_mask);
+ int src1 = ((iw1 >> DSP32Mac_src1_bits) & DSP32Mac_src1_mask);
+ int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+ int h10 = ((iw1 >> DSP32Mac_h10_bits) & DSP32Mac_h10_mask);
+ int h00 = ((iw1 >> DSP32Mac_h00_bits) & DSP32Mac_h00_mask);
+ int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
+ int h11 = ((iw1 >> DSP32Mac_h11_bits) & DSP32Mac_h11_mask);
+ int h01 = ((iw1 >> DSP32Mac_h01_bits) & DSP32Mac_h01_mask);
+
+ TCGv res;
+ TCGv sat0, sat1;
+
+ TRACE_EXTRACT("M:%i mmod:%i MM:%i P:%i w1:%i op1:%i h01:%i h11:%i "
+ "w0:%i op0:%i h00:%i h10:%i dst:%i src0:%i src1:%i",
+ M, mmod, MM, P, w1, op1, h01, h11, w0, op0, h00, h10,
+ dst, src0, src1);
+
+ if (w1 == 0 && w0 == 0) {
+ illegal_instruction(dc);
+ }
+ if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0) {
+ illegal_instruction(dc);
+ }
+ if (P && ((dst & 1) || (op1 != 0) || (op0 != 0) || !is_macmod_pmove (mmod))) {
+ illegal_instruction(dc);
+ }
+ if (!P && ((op1 != 0) || (op0 != 0) || !is_macmod_hmove (mmod))) {
+ illegal_instruction(dc);
+ }
+
+ res = tcg_temp_local_new();
+ tcg_gen_mov_tl(res, cpu_dreg[dst]);
+
+ sat1 = tcg_temp_local_new();
+
+ if (w1) {
+ TCGv res1 = decode_multfunc_tl(dc, h01, h11, src0, src1, mmod, MM, sat1);
+ if (P) {
+ tcg_gen_mov_tl(cpu_dreg[dst + 1], res1);
+ } else {
+ gen_mov_h_tl(res, res1);
+ }
+ tcg_temp_free(res1);
+ }
+
+ sat0 = tcg_temp_local_new();
+
+ if (w0) {
+ TCGv res0 = decode_multfunc_tl(dc, h00, h10, src0, src1, mmod, 0, sat0);
+ if (P) {
+ tcg_gen_mov_tl(cpu_dreg[dst], res0);
+ } else {
+ gen_mov_l_tl(res, res0);
+ }
+ tcg_temp_free(res0);
+ }
+
+ if (!P && (w0 || w1)) {
+ tcg_gen_mov_tl(cpu_dreg[dst], res);
+ }
+
+ tcg_temp_free(sat0);
+ tcg_temp_free(sat1);
+ tcg_temp_free(res);
+}
+
+static void
+decode_dsp32alu_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* dsp32alu
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
+ |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
+ int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
+ int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
+ int src0 = ((iw1 >> DSP32Alu_src0_bits) & DSP32Alu_src0_mask);
+ int src1 = ((iw1 >> DSP32Alu_src1_bits) & DSP32Alu_src1_mask);
+ int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
+ int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
+ int M = ((iw0 >> (DSP32Alu_M_bits - 16)) & DSP32Alu_M_mask);
+ int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
+ int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
+ TCGv tmp;
+ TCGv_i64 tmp64;
+
+ TRACE_EXTRACT("M:%i HL:%i aopcde:%i aop:%i s:%i x:%i dst0:%i "
+ "dst1:%i src0:%i src1:%i",
+ M, HL, aopcde, aop, s, x, dst0, dst1, src0, src1);
+
+ if ((aop == 0 || aop == 2) && aopcde == 9 && HL == 0 && s == 0) {
+ int a = aop >> 1;
+ /* Areg_lo{a} = Dreg_lo{src0}; */
+ tcg_gen_andi_i64(cpu_areg[a], cpu_areg[a], ~0xffff);
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, cpu_dreg[src0]);
+ tcg_gen_andi_i64(tmp64, tmp64, 0xffff);
+ tcg_gen_or_i64(cpu_areg[a], cpu_areg[a], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else if ((aop == 0 || aop == 2) && aopcde == 9 && HL == 1 && s == 0) {
+ int a = aop >> 1;
+ /* Areg_hi{a} = Dreg_hi{src0}; */
+ tcg_gen_andi_i64(cpu_areg[a], cpu_areg[a], 0xff0000ffff);
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, cpu_dreg[src0]);
+ tcg_gen_andi_i64(tmp64, tmp64, 0xffff0000);
+ tcg_gen_or_i64(cpu_areg[a], cpu_areg[a], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else if ((aop == 1 || aop == 0) && aopcde == 5) {
+ /* Dreg{dst0}_hi{HL==0} = Dreg{src0} +{aop==0} Dreg{src1} (RND12); */
+ /* Dreg{dst0}_lo{HL==1} = Dreg{src0} +{aop==0} Dreg{src1} (RND12); */
+ /* Dreg{dst0}_hi{HL==0} = Dreg{src0} -{aop==1} Dreg{src1} (RND12); */
+ /* Dreg{dst0}_lo{HL==1} = Dreg{src0} -{aop==1} Dreg{src1} (RND12); */
+ unhandled_instruction(dc, "Dreg +/- RND12");
+ } else if ((aop == 2 || aop == 3) && aopcde == 5) {
+ /* Dreg{dst0}_hi{HL==0} = Dreg{src0} +{aop==0} Dreg{src1} (RND20); */
+ /* Dreg{dst0}_lo{HL==1} = Dreg{src0} +{aop==0} Dreg{src1} (RND20); */
+ /* Dreg{dst0}_hi{HL==0} = Dreg{src0} -{aop==1} Dreg{src1} (RND20); */
+ /* Dreg{dst0}_lo{HL==1} = Dreg{src0} -{aop==1} Dreg{src1} (RND20); */
+ unhandled_instruction(dc, "Dreg +/- RND20");
+ } else if (aopcde == 2 || aopcde == 3) {
+ /* Dreg{dst0}_lo{HL==0} = Dreg{src0}_lo{!aop&2} +{aopcde==2} Dreg{src1}_lo{!aop&1} (amod1(s,x)); */
+ /* Dreg{dst0}_hi{HL==1} = Dreg{src0}_hi{aop&2} -{aopcde==3} Dreg{src1}_hi{aop&1} (amod1(s,x)); */
+ TCGv s1, s2, d;
+
+ s1 = tcg_temp_new();
+ if (aop & 2) {
+ tcg_gen_shri_tl(s1, cpu_dreg[src0], 16);
+ } else {
+ tcg_gen_ext16u_tl(s1, cpu_dreg[src0]);
+ }
+
+ s2 = tcg_temp_new();
+ if (aop & 1) {
+ tcg_gen_shri_tl(s2, cpu_dreg[src1], 16);
+ } else {
+ tcg_gen_ext16u_tl(s2, cpu_dreg[src1]);
+ }
+
+ d = tcg_temp_new();
+ if (aopcde == 2) {
+ tcg_gen_add_tl(d, s1, s2);
+ } else {
+ tcg_gen_sub_tl(d, s1, s2);
+ }
+ tcg_gen_andi_tl(d, d, 0xffff);
+
+ tcg_temp_free(s1);
+ tcg_temp_free(s2);
+
+ if (HL) {
+ tcg_gen_andi_tl(cpu_dreg[dst0], cpu_dreg[dst0], 0xffff);
+ tcg_gen_shli_tl(d, d, 16);
+ tcg_gen_or_tl(cpu_dreg[dst0], cpu_dreg[dst0], d);
+ } else {
+ tcg_gen_andi_tl(cpu_dreg[dst0], cpu_dreg[dst0], 0xffff0000);
+ tcg_gen_or_tl(cpu_dreg[dst0], cpu_dreg[dst0], d);
+ }
+ tcg_temp_free(d);
+
+ /* XXX: missing ASTAT update */
+ } else if ((aop == 0 || aop == 2) && aopcde == 9 && s == 1) {
+ int a = aop >> 1;
+ /* Areg{a} = Dreg{src0}; */
+ tcg_gen_ext_i32_i64(cpu_areg[a], cpu_dreg[src0]);
+ } else if ((aop == 1 || aop == 3) && aopcde == 9 && s == 0) {
+ int a = aop >> 1;
+ /* Areg_x{a} = Dreg_lo{src0}; */
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, cpu_dreg[src0]);
+ tcg_gen_ext8u_i64(tmp64, tmp64);
+ tcg_gen_shli_i64(tmp64, tmp64, 32);
+ tcg_gen_andi_i64(cpu_areg[a], cpu_areg[a], 0xffffffff);
+ tcg_gen_or_i64(cpu_areg[a], cpu_areg[a], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else if (aop == 3 && aopcde == 11 && (s == 0 || s == 1)) {
+ /* A0 -= A0 (W32){s==1}; */
+ tcg_gen_sub_i64(cpu_areg[0], cpu_areg[0], cpu_areg[1]);
+
+ if (s == 1) {
+ unhandled_instruction(dc, "A0 -= A1 (W32)");
+ }
+ /* XXX: missing ASTAT update */
+ } else if ((aop == 0 || aop == 1) && aopcde == 22) {
+ /* Dreg{dst0} = BYTEOP2P (Dreg{src0+1}:Dreg{src0}, Dreg{src1+1}:Dreg{src1} (mode); */
+ /* modes[HL + (aop << 1)] = { rndl, rndh, tl, th }; */
+ /* (modes, r) s==1 */
+ unhandled_instruction(dc, "BYTEOP2P");
+ } else if ((aop == 0 || aop == 1) && s == 0 && aopcde == 8) {
+ /* Areg{aop} = 0; */
+ tcg_gen_movi_i64(cpu_areg[0], 0);
+ } else if (aop == 2 && s == 0 && aopcde == 8) {
+ /* A1 = A0 = 0; */
+ tcg_gen_movi_i64(cpu_areg[0], 0);
+ tcg_gen_mov_i64(cpu_areg[1], cpu_areg[0]);
+ } else if ((aop == 0 || aop == 1 || aop == 2) && s == 1 && aopcde == 8) {
+ /* A0 = A0 (S); {aop==0} */
+ /* A1 = A1 (S); {aop==1} */
+ /* A1 = A1 (S), A0 = A0 (S); {aop==2} */
+ TCGv sat0, sat1;
+
+ sat0 = tcg_temp_local_new();
+ tcg_gen_movi_tl(sat0, 0);
+ if (aop == 0 || aop == 2) {
+ gen_extend_acc(cpu_areg[0]);
+ saturate_s32(cpu_areg[0], sat0);
+ tcg_gen_ext32s_i64(cpu_areg[0], cpu_areg[0]);
+ }
+
+ sat1 = tcg_temp_local_new();
+ tcg_gen_movi_tl(sat1, 0);
+ if (aop == 1 || aop == 2) {
+ gen_extend_acc(cpu_areg[1]);
+ saturate_s32(cpu_areg[1], sat1);
+ tcg_gen_ext32s_i64(cpu_areg[0], cpu_areg[0]);
+ }
+
+ tcg_temp_free(sat1);
+ tcg_temp_free(sat0);
+
+ /* XXX: missing ASTAT update */
+ } else if (aop == 3 && (s == 0 || s == 1) && aopcde == 8) {
+ /* Areg{s} = Areg{!s}; */
+ tcg_gen_mov_i64(cpu_areg[s], cpu_areg[!s]);
+ } else if (aop == 3 && HL == 0 && aopcde == 16) {
+ /* A1 = ABS A1 , A0 = ABS A0; */
+ int i;
+ /* XXX: Missing ASTAT updates and saturation */
+ for (i = 0; i < 2; ++i) {
+ gen_abs_i64(cpu_areg[i], cpu_areg[i]);
+ }
+ } else if (aop == 0 && aopcde == 23) {
+ unhandled_instruction(dc, "BYTEOP3P");
+ } else if ((aop == 0 || aop == 1) && aopcde == 16) {
+ /* Areg{HL} = ABS Areg{aop}; */
+
+ /* XXX: Missing ASTAT updates */
+ /* XXX: Missing saturation */
+ gen_abs_i64(cpu_areg[aop], cpu_areg[aop]);
+ } else if (aop == 3 && aopcde == 12) {
+ /* Dreg{dst0}_lo{HL==0} = Dreg{src0} (RND); */
+ /* Dreg{dst0}_hi{HL==1} = Dreg{src0} (RND); */
+ unhandled_instruction(dc, "Dreg (RND)");
+ } else if (aop == 3 && HL == 0 && aopcde == 15) {
+ /* Dreg{dst0} = -Dreg{src0} (V); */
+ unhandled_instruction(dc, "Dreg = -Dreg (V)");
+ } else if (aop == 3 && HL == 0 && aopcde == 14) {
+ /* A1 = -A1 , A0 = -A0; */
+ tcg_gen_neg_i64(cpu_areg[1], cpu_areg[1]);
+ tcg_gen_neg_i64(cpu_areg[0], cpu_areg[0]);
+ /* XXX: what ASTAT flags need updating ? */
+ } else if ((aop == 0 || aop == 1) && (HL == 0 || HL == 1) && aopcde == 14) {
+ /* Areg{HL} = -Areg{aop}; */
+ tcg_gen_neg_i64(cpu_areg[HL], cpu_areg[aop]);
+ /* XXX: Missing ASTAT updates */
+ } else if (aop == 0 && aopcde == 12) {
+ /* Dreg_lo{dst0} = Dreg_hi{dst0} =
+ SIGN(Dreg_hi{src0} * Dreg_hi{src1} +
+ SIGN(Dreg_lo{src0} * Dreg_lo{src1} */
+ int l;
+ TCGv tmp1_hi, tmp1_lo;
+
+ tmp1_hi = tcg_temp_local_new();
+ /* if ((src0_hi >> 15) & 1) tmp1_hi = -src1_hi; */
+ tcg_gen_sari_tl(tmp1_hi, cpu_dreg[src1], 16);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_GE, cpu_dreg[src0], 0, l);
+ tcg_gen_neg_tl(tmp1_hi, tmp1_hi);
+ gen_set_label(l);
+
+ tmp = tcg_temp_local_new();
+ tmp1_lo = tcg_temp_local_new();
+ /* if ((src0_lo >> 15) & 1) tmp1_lo = -src1_lo; */
+ tcg_gen_ext16s_tl(tmp, cpu_dreg[src0]);
+ tcg_gen_ext16s_tl(tmp1_lo, cpu_dreg[src1]);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_GE, tmp, 0, l);
+ tcg_gen_neg_tl(tmp1_lo, tmp1_lo);
+ gen_set_label(l);
+
+ tcg_temp_free(tmp);
+
+ tcg_gen_add_tl(tmp1_hi, tmp1_hi, tmp1_lo);
+ tcg_gen_shli_tl(cpu_dreg[dst0], tmp1_hi, 16);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp1_hi);
+
+ tcg_temp_free(tmp1_lo);
+ tcg_temp_free(tmp1_hi);
+ } else if (aopcde == 0) {
+ /* Dreg{dst0} = Dreg{src0} -{aop&2}+{!aop&2}|-{aop&1}+{!aop&1}
+ Dreg{src1} (amod0); */
+ TCGv s0, s1, t0, t1;
+
+ if (s || x) {
+ unhandled_instruction(dc, "S/CO/SCO with +|+/-|-");
+ }
+
+ s0 = tcg_temp_local_new();
+ s1 = tcg_temp_local_new();
+
+ t0 = tcg_temp_local_new();
+ tcg_gen_shri_tl(s0, cpu_dreg[src0], 16);
+ tcg_gen_shri_tl(s1, cpu_dreg[src1], 16);
+ if (aop & 2) {
+ tcg_gen_sub_tl(t0, s0, s1);
+ } else {
+ tcg_gen_add_tl(t0, s0, s1);
+ }
+
+ t1 = tcg_temp_local_new();
+ tcg_gen_andi_tl(s0, cpu_dreg[src0], 0xffff);
+ tcg_gen_andi_tl(s1, cpu_dreg[src1], 0xffff);
+ if (aop & 1) {
+ tcg_gen_sub_tl(t1, s0, s1);
+ } else {
+ tcg_gen_add_tl(t1, s0, s1);
+ }
+
+ tcg_temp_free(s1);
+ tcg_temp_free(s0);
+
+ astat_queue_state2(dc, ASTAT_OP_VECTOR_ADD_ADD + aop, t0, t1);
+
+ if (x) {
+ /* dst0.h = t1; dst0.l = t0 */
+ tcg_gen_ext16u_tl(cpu_dreg[dst0], t0);
+ tcg_gen_shli_tl(t1, t1, 16);
+ tcg_gen_or_tl(cpu_dreg[dst0], cpu_dreg[dst0], t1);
+ } else {
+ /* dst0.h = t0; dst0.l = t1 */
+ tcg_gen_ext16u_tl(cpu_dreg[dst0], t1);
+ tcg_gen_shli_tl(t0, t0, 16);
+ tcg_gen_or_tl(cpu_dreg[dst0], cpu_dreg[dst0], t0);
+ }
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ /* XXX: missing ASTAT update */
+ } else if (aop == 1 && aopcde == 12) {
+ /* Dreg{dst1} = A1.L + A1.H, Dreg{dst0} = A0.L + A0.H; */
+ TCGv al, ah;
+
+ /*if (dst0 == dst1)
+ illegal_instruction_combination(dc);*/
+
+ al = tcg_temp_local_new();
+ ah = tcg_temp_local_new();
+ tcg_gen_trunc_i64_i32(ah, cpu_areg[0]);
+ tcg_gen_ext16u_tl(al, ah);
+ tcg_gen_shri_tl(ah, ah, 16);
+ tcg_gen_add_tl(cpu_dreg[dst0], al, ah);
+ tcg_temp_free(al);
+ tcg_temp_free(ah);
+ tcg_gen_ext16s_tl(cpu_dreg[dst0], cpu_dreg[dst0]);
+
+ al = tcg_temp_local_new();
+ ah = tcg_temp_local_new();
+ tcg_gen_trunc_i64_i32(ah, cpu_areg[1]);
+ tcg_gen_ext16u_tl(al, ah);
+ tcg_gen_shri_tl(ah, ah, 16);
+ tcg_gen_add_tl(cpu_dreg[dst1], al, ah);
+ tcg_temp_free(al);
+ tcg_temp_free(ah);
+ tcg_gen_ext16s_tl(cpu_dreg[dst1], cpu_dreg[dst1]);
+
+ /* XXX: ASTAT ? */
+ } else if (aopcde == 1) {
+ /* XXX: missing ASTAT update */
+ unhandled_instruction(dc, "Dreg +|+ Dreg, Dreg -|- Dreg");
+ } else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 11) {
+ /* Dreg{dst0} = (A0 += A1); {aop==0} */
+ /* Dreg{dst0}_lo{HL==0} = (A0 += A1); {aop==1} */
+ /* Dreg{dst0}_hi{HL==1} = (A0 += A1); {aop==1} */
+ /* (A0 += A1); {aop==2} */
+ tcg_gen_add_i64(cpu_areg[0], cpu_areg[0], cpu_areg[1]);
+
+ if (aop == 2 && s == 1) {
+ unhandled_instruction(dc, "A0 += A1 (W32)");
+ }
+
+ /* XXX: missing saturation support */
+ if (aop == 0) {
+ /* Dregs = A0 += A1 */
+ tcg_gen_trunc_i64_i32(cpu_dreg[dst0], cpu_areg[0]);
+ } else if (aop == 1) {
+ /* Dregs_lo = A0 += A1 */
+ tmp = tcg_temp_new();
+ tcg_gen_trunc_i64_i32(tmp, cpu_areg[0]);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ }
+ } else if ((aop == 0 || aop == 1) && aopcde == 10) {
+ /* Dreg_lo{dst0} = Areg_x{aop}; */
+ tmp = tcg_temp_new();
+ tmp64 = tcg_temp_new_i64();
+ tcg_gen_shri_i64(tmp64, cpu_areg[aop], 32);
+ tcg_gen_trunc_i64_i32(tmp, tmp64);
+ tcg_temp_free_i64(tmp64);
+ tcg_gen_ext8s_tl(tmp, tmp);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ } else if (aop == 0 && aopcde == 4) {
+ /* Dreg{dst0} = Dreg{src0} + Dreg{src1} (amod1(s,x)); */
+ tcg_gen_add_tl(cpu_dreg[dst0], cpu_dreg[src0], cpu_dreg[src1]);
+ astat_queue_state3(dc, ASTAT_OP_ADD32, cpu_dreg[dst0], cpu_dreg[src0], cpu_dreg[src1]);
+ } else if (aop == 1 && aopcde == 4) {
+ /* Dreg{dst0} = Dreg{src0} - Dreg{src1} (amod1(s,x)); */
+ tcg_gen_sub_tl(cpu_dreg[dst0], cpu_dreg[src0], cpu_dreg[src1]);
+ astat_queue_state3(dc, ASTAT_OP_SUB32, cpu_dreg[dst0], cpu_dreg[src0], cpu_dreg[src1]);
+ } else if (aop == 2 && aopcde == 4) {
+ /* Dreg{dst1} = Dreg{src0} + Dreg{src1}, Dreg{dst0} = Dreg{src0} - Dreg{src1} (amod1(s,x)); */
+
+ /*if (dst0 == dst1)
+ illegal_instruction_combination(dc);*/
+
+ if (dst1 == src0 || dst1 == src1) {
+ tmp = tcg_temp_new();
+ } else {
+ tmp = cpu_dreg[dst1];
+ }
+ tcg_gen_add_tl(tmp, cpu_dreg[src0], cpu_dreg[src1]);
+ tcg_gen_sub_tl(cpu_dreg[dst0], cpu_dreg[src0], cpu_dreg[src1]);
+ if (dst1 == src0 || dst1 == src1) {
+ tcg_gen_mov_tl(cpu_dreg[dst1], tmp);
+ tcg_temp_free(tmp);
+ }
+ /* XXX: Missing ASTAT updates */
+ } else if ((aop == 0 || aop == 1) && aopcde == 17) {
+ unhandled_instruction(dc, "Dreg = Areg + Areg, Dreg = Areg - Areg");
+ } else if (aop == 0 && aopcde == 18) {
+ unhandled_instruction(dc, "SAA");
+ } else if (aop == 3 && aopcde == 18) {
+ dc->disalgnexcpt = true;
+ } else if ((aop == 0 || aop == 1) && aopcde == 20) {
+ unhandled_instruction(dc, "BYTEOP1P");
+ } else if (aop == 0 && aopcde == 21) {
+ unhandled_instruction(dc, "BYTEOP16P");
+ } else if (aop == 1 && aopcde == 21) {
+ unhandled_instruction(dc, "BYTEOP16M");
+ } else if ((aop == 0 || aop == 1) && aopcde == 7) {
+ /* Dreg{dst0} = MIN{aop==1} (Dreg{src0}, Dreg{src1}); */
+ /* Dreg{dst0} = MAX{aop==0} (Dreg{src0}, Dreg{src1}); */
+ int l, _src0, _src1;
+ TCGCond cond;
+
+ if (aop == 0) {
+ cond = TCG_COND_LT;
+ } else {
+ cond = TCG_COND_GE;
+ }
+
+ /* src/dst regs might be the same, so we need to handle that */
+ if (dst0 == src1) {
+ _src0 = src1, _src1 = src0;
+ } else {
+ _src0 = src0, _src1 = src1;
+ }
+
+ l = gen_new_label();
+ tcg_gen_mov_tl(cpu_dreg[dst0], cpu_dreg[_src0]);
+ tcg_gen_brcond_tl(cond, cpu_dreg[_src1], cpu_dreg[_src0], l);
+ tcg_gen_mov_tl(cpu_dreg[dst0], cpu_dreg[_src1]);
+ gen_set_label(l);
+
+ astat_queue_state1(dc, ASTAT_OP_MIN_MAX, cpu_dreg[dst0]);
+ } else if (aop == 2 && aopcde == 7) {
+ /* Dreg{dst0} = ABS Dreg{src0}; */
+
+ /* XXX: Missing saturation support (and ASTAT V/VS) */
+ gen_abs_tl(cpu_dreg[dst0], cpu_dreg[src0]);
+
+ astat_queue_state2(dc, ASTAT_OP_ABS, cpu_dreg[dst0], cpu_dreg[src0]);
+ } else if (aop == 3 && aopcde == 7) {
+ /* Dreg{dst0} = -Dreg{src0} (amod1(s,0)); */
+ int l, endl;
+
+ l = gen_new_label();
+ endl = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, cpu_dreg[src0], 0x80000000, l);
+ if (s) {
+ tcg_gen_movi_tl(cpu_dreg[dst0], 0x7fffffff);
+ tmp = tcg_const_tl(1);
+ _gen_astat_store(ASTAT_V, tmp);
+ _gen_astat_store(ASTAT_V_COPY, tmp);
+ _gen_astat_store(ASTAT_VS, tmp);
+ tcg_temp_free(tmp);
+ } else {
+ tcg_gen_movi_tl(cpu_dreg[dst0], 0x80000000);
+ }
+
+ gen_set_label(l);
+ tcg_gen_neg_tl(cpu_dreg[dst0], cpu_dreg[src0]);
+ gen_set_label(endl);
+ astat_queue_state2(dc, ASTAT_OP_NEGATE, cpu_dreg[dst0], cpu_dreg[src0]);
+ } else if (aop == 2 && aopcde == 6) {
+ /* Dreg{dst0} = ABS Dreg{src0} (V); */
+ TCGv tmp0;
+
+ tmp = tcg_temp_local_new();
+ tcg_gen_sari_tl(tmp, cpu_dreg[src0], 16);
+ gen_abs_tl(tmp, tmp);
+
+ tmp0 = tcg_temp_local_new();
+ tcg_gen_ext16s_tl(tmp0, cpu_dreg[src0]);
+ gen_abs_tl(tmp0, tmp0);
+
+ astat_queue_state2(dc, ASTAT_OP_ABS_VECTOR, tmp0, tmp);
+
+ tcg_gen_shli_tl(tmp, tmp, 16);
+ tcg_gen_andi_tl(tmp0, tmp0, 0xffff);
+ tcg_gen_or_tl(cpu_dreg[dst0], tmp, tmp0);
+
+ tcg_temp_free(tmp0);
+ tcg_temp_free(tmp);
+ } else if ((aop == 0 || aop == 1) && aopcde == 6) {
+ /* Dreg{dst0} = MAX{aop==0} (Dreg{src0}, Dreg{src1}) (V); */
+ /* Dreg{dst0} = MIN{aop==1} (Dreg{src0}, Dreg{src1}) (V); */
+ /* src/dst regs might be the same, so we need to handle that */
+ int l;
+ TCGCond cond;
+ TCGv tmp0, tmp1;
+
+ cond = aop == 1 ? TCG_COND_LE : TCG_COND_GE;
+
+ tmp = tcg_temp_local_new();
+ tmp0 = tcg_temp_local_new();
+ tmp1 = tcg_temp_local_new();
+
+ /* First do top 16bit pair */
+ l = gen_new_label();
+ tcg_gen_andi_tl(tmp0, cpu_dreg[src0], 0xffff0000);
+ tcg_gen_andi_tl(tmp1, cpu_dreg[src1], 0xffff0000);
+ tcg_gen_brcond_tl(cond, tmp0, tmp1, l);
+ tcg_gen_mov_tl(tmp0, tmp1);
+ gen_set_label(l);
+
+ /* Then bottom 16bit pair */
+ l = gen_new_label();
+ tcg_gen_ext16s_tl(tmp, cpu_dreg[src0]);
+ tcg_gen_ext16s_tl(tmp1, cpu_dreg[src1]);
+ tcg_gen_brcond_tl(cond, tmp, tmp1, l);
+ tcg_gen_mov_tl(tmp, tmp1);
+ gen_set_label(l);
+
+ astat_queue_state2(dc, ASTAT_OP_MIN_MAX_VECTOR, tmp0, tmp);
+
+ /* Then combine them */
+ tcg_gen_andi_tl(tmp, tmp, 0xffff);
+ tcg_gen_or_tl(cpu_dreg[dst0], tmp0, tmp);
+
+ tcg_temp_free(tmp1);
+ tcg_temp_free(tmp0);
+ tcg_temp_free(tmp);
+ } else if (aop == 0 && aopcde == 24) {
+ TCGv dst;
+ /* Dreg{dst0} BYTEPACK (Dreg{src0}, Dreg{src1}); */
+
+ /* XXX: could optimize a little if dst0 is diff from src0 or src1 */
+ /* dst |= (((src0 >> 0) & 0xff) << 0) */
+ dst = tcg_temp_new();
+ tcg_gen_andi_tl(dst, cpu_dreg[src0], 0xff);
+ tmp = tcg_temp_new();
+ /* dst |= (((src0 >> 16) & 0xff) << 8) */
+ tcg_gen_andi_tl(tmp, cpu_dreg[src0], 0xff0000);
+ tcg_gen_shri_tl(tmp, tmp, 8);
+ tcg_gen_or_tl(dst, dst, tmp);
+ /* dst |= (((src1 >> 0) & 0xff) << 16) */
+ tcg_gen_andi_tl(tmp, cpu_dreg[src1], 0xff);
+ tcg_gen_shli_tl(tmp, tmp, 16);
+ tcg_gen_or_tl(dst, dst, tmp);
+ /* dst |= (((src1 >> 16) & 0xff) << 24) */
+ tcg_gen_andi_tl(tmp, cpu_dreg[src1], 0xff0000);
+ tcg_gen_shli_tl(tmp, tmp, 8);
+ tcg_gen_or_tl(cpu_dreg[dst0], dst, tmp);
+ tcg_temp_free(tmp);
+ tcg_temp_free(dst);
+ } else if (aop == 1 && aopcde == 24) {
+ /* (Dreg{dst1}, Dreg{dst0} = BYTEUNPACK Dreg{src0+1}:{src0} (R){s}; */
+ TCGv lo, hi;
+ TCGv_i64 tmp64_2;
+
+ /*if (dst0 == dst1)
+ illegal_instruction_combination(dc);*/
+
+ if (s) {
+ hi = cpu_dreg[src0], lo = cpu_dreg[src0 + 1];
+ } else {
+ hi = cpu_dreg[src0 + 1], lo = cpu_dreg[src0];
+ }
+
+ /* Create one field of the two regs */
+ tmp64 = tcg_temp_local_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, hi);
+ tcg_gen_shli_i64(tmp64, tmp64, 32);
+ tmp64_2 = tcg_temp_local_new_i64();
+ tcg_gen_extu_i32_i64(tmp64_2, lo);
+ tcg_gen_or_i64(tmp64, tmp64, tmp64_2);
+
+ /* Adjust the two regs field by the Ireg[0] order */
+ tcg_gen_extu_i32_i64(tmp64_2, cpu_ireg[0]);
+ tcg_gen_andi_i64(tmp64_2, tmp64_2, 0x3);
+ tcg_gen_shli_i64(tmp64_2, tmp64_2, 3); /* multiply by 8 */
+ tcg_gen_shr_i64(tmp64, tmp64, tmp64_2);
+ tcg_temp_free_i64(tmp64_2);
+
+ /* Now that the 4 bytes we want are in the low 32bit, truncate */
+ tmp = tcg_temp_local_new();
+ tcg_gen_trunc_i64_i32(tmp, tmp64);
+ tcg_temp_free_i64(tmp64);
+
+ /* Load bytea into dst0 */
+ tcg_gen_andi_tl(cpu_dreg[dst0], tmp, 0xff);
+ /* Load byted into dst1 */
+ tcg_gen_shri_tl(cpu_dreg[dst1], tmp, 8);
+ tcg_gen_andi_tl(cpu_dreg[dst1], cpu_dreg[dst1], 0xff0000);
+ /* Load byteb into dst0 */
+ tcg_gen_shli_tl(tmp, tmp, 8);
+ tcg_gen_or_tl(cpu_dreg[dst0], cpu_dreg[dst0], tmp);
+ tcg_gen_andi_tl(cpu_dreg[dst0], cpu_dreg[dst0], 0xff00ff);
+ /* Load bytec into dst1 */
+ tcg_gen_shri_tl(tmp, tmp, 24);
+ tcg_gen_or_tl(cpu_dreg[dst1], cpu_dreg[dst1], tmp);
+ tcg_gen_andi_tl(cpu_dreg[dst1], cpu_dreg[dst1], 0xff00ff);
+ tcg_temp_free(tmp);
+ } else if (aopcde == 13) {
+ int l;
+ TCGv a_lo;
+ TCGCond conds[] = {
+ /* GT */ TCG_COND_LE,
+ /* GE */ TCG_COND_LT,
+ /* LT */ TCG_COND_GE,
+ /* LE */ TCG_COND_GT,
+ };
+
+ /* (Dreg{dst1}, Dreg{dst0}) = SEARCH Dreg{src0} (mode{aop}); */
+
+ /*if (dst0 == dst1)
+ illegal_instruction_combination(dc);*/
+
+ a_lo = tcg_temp_local_new();
+ tmp = tcg_temp_local_new();
+
+ /* Compare A1 to Dreg_hi{src0} */
+ tcg_gen_trunc_i64_i32(a_lo, cpu_areg[1]);
+ tcg_gen_ext16s_tl(a_lo, a_lo);
+ tcg_gen_sari_tl(tmp, cpu_dreg[src0], 16);
+
+ l = gen_new_label();
+ tcg_gen_brcond_tl(conds[aop], tmp, a_lo, l);
+ /* Move Dreg_hi{src0} into A0 */
+ tcg_gen_ext_i32_i64(cpu_areg[1], tmp);
+ /* Move Preg{0} into Dreg{dst1} */
+ tcg_gen_mov_tl(cpu_dreg[dst1], cpu_preg[0]);
+ gen_set_label(l);
+
+ /* Compare A0 to Dreg_lo{src0} */
+ tcg_gen_trunc_i64_i32(a_lo, cpu_areg[0]);
+ tcg_gen_ext16s_tl(a_lo, a_lo);
+ tcg_gen_ext16s_tl(tmp, cpu_dreg[src0]);
+
+ l = gen_new_label();
+ tcg_gen_brcond_tl(conds[aop], tmp, a_lo, l);
+ /* Move Dreg_lo{src0} into A0 */
+ tcg_gen_ext_i32_i64(cpu_areg[0], tmp);
+ /* Move Preg{0} into Dreg{dst0} */
+ tcg_gen_mov_tl(cpu_dreg[dst0], cpu_preg[0]);
+ gen_set_label(l);
+
+ tcg_temp_free(a_lo);
+ tcg_temp_free(tmp);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_dsp32shift_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* dsp32shift
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
+ |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
+ int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
+ int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
+ int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
+ int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
+ int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
+ int M = ((iw0 >> (DSP32Shift_M_bits - 16)) & DSP32Shift_M_mask);
+ TCGv tmp;
+ TCGv_i64 tmp64;
+
+ TRACE_EXTRACT("M:%i sopcde:%i sop:%i HLs:%i dst0:%i src0:%i src1:%i",
+ M, sopcde, sop, HLs, dst0, src0, src1);
+
+ if ((sop == 0 || sop == 1) && sopcde == 0) {
+ int l, endl;
+ TCGv val;
+
+ /* Dreg{dst0}_hi{HLs&2} = ASHIFT Dreg{src1}_hi{HLs&1} BY Dreg_lo{src0} (S){sop==1}; */
+ /* Dreg{dst0}_lo{!HLs&2} = ASHIFT Dreg{src1}_lo{!HLs&1} BY Dreg_lo{src0} (S){sop==1}; */
+
+ tmp = tcg_temp_local_new();
+ gen_extNsi_tl(tmp, cpu_dreg[src0], 6);
+
+ val = tcg_temp_local_new();
+ if (HLs & 1) {
+ tcg_gen_sari_tl(val, cpu_dreg[src1], 16);
+ } else {
+ tcg_gen_ext16s_tl(val, cpu_dreg[src1]);
+ }
+
+ /* Positive shift magnitudes produce Logical Left shifts.
+ * Negative shift magnitudes produce Arithmetic Right shifts.
+ */
+ endl = gen_new_label();
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_GE, tmp, 0, l);
+ tcg_gen_neg_tl(tmp, tmp);
+ tcg_gen_sar_tl(val, val, tmp);
+ astat_queue_state1(dc, ASTAT_OP_ASHIFT16, val);
+ tcg_gen_br(endl);
+ gen_set_label(l);
+ tcg_gen_shl_tl(val, val, tmp);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT16, val);
+ gen_set_label(endl);
+
+ if (HLs & 2) {
+ gen_mov_h_tl(cpu_dreg[dst0], val);
+ } else {
+ gen_mov_l_tl(cpu_dreg[dst0], val);
+ }
+
+ tcg_temp_free(val);
+ tcg_temp_free(tmp);
+
+ /* XXX: Missing V updates */
+ } else if (sop == 2 && sopcde == 0) {
+ int l, endl;
+ TCGv val;
+
+ /* Dreg{dst0}_hi{HLs&2} = LSHIFT Dreg{src1}_hi{HLs&1} BY Dreg_lo{src0}; */
+ /* Dreg{dst0}_lo{!HLs&2} = LSHIFT Dreg{src1}_lo{!HLs&1} BY Dreg_lo{src0}; */
+
+ tmp = tcg_temp_local_new();
+ gen_extNsi_tl(tmp, cpu_dreg[src0], 6);
+
+ val = tcg_temp_local_new();
+ if (HLs & 1) {
+ tcg_gen_shri_tl(val, cpu_dreg[src1], 16);
+ } else {
+ tcg_gen_ext16u_tl(val, cpu_dreg[src1]);
+ }
+
+ /* Negative shift magnitudes means shift right */
+ endl = gen_new_label();
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_GE, tmp, 0, l);
+ tcg_gen_neg_tl(tmp, tmp);
+ tcg_gen_shr_tl(val, val, tmp);
+ tcg_gen_br(endl);
+ gen_set_label(l);
+ tcg_gen_shl_tl(val, val, tmp);
+ gen_set_label(endl);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT16, val);
+
+ if (HLs & 2) {
+ gen_mov_h_tl(cpu_dreg[dst0], val);
+ } else {
+ gen_mov_l_tl(cpu_dreg[dst0], val);
+ }
+
+ tcg_temp_free(val);
+ tcg_temp_free(tmp);
+
+ /* XXX: Missing AZ/AN/V updates */
+ } else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0)) {
+ /* Areg{HLs} = ROT Areg{HLs} BY Dreg_lo{src0}; */
+ tmp64 = tcg_temp_local_new_i64();
+ tcg_gen_extu_i32_i64(tmp64, cpu_dreg[src0]);
+ tcg_gen_ext16s_i64(tmp64, tmp64);
+ gen_rot_i64(cpu_areg[HLs], cpu_areg[HLs], tmp64);
+ tcg_temp_free_i64(tmp64);
+ } else if (sop == 0 && sopcde == 3 && (HLs == 0 || HLs == 1)) {
+ /* Areg{HLs} = ASHIFT Areg{HLs} BY Dregs_lo{src0}; */
+ unhandled_instruction(dc, "ASHIFT ACC");
+ } else if (sop == 1 && sopcde == 3 && (HLs == 0 || HLs == 1)) {
+ /* Areg{HLs} = LSHIFT Areg{HLs} BY Dregs_lo{src0}; */
+ unhandled_instruction(dc, "LSHIFT ACC");
+ } else if ((sop == 0 || sop == 1) && sopcde == 1) {
+ /* Dreg{dst0} = ASHIFT Dreg{src1} BY Dreg{src0} (V){sop==0}; */
+ /* Dreg{dst0} = ASHIFT Dreg{src1} BY Dreg{src0} (V,S){sop==1}; */
+ unhandled_instruction(dc, "ASHIFT V");
+ } else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 2) {
+ /* Dreg{dst0} = [LA]SHIFT Dreg{src1} BY Dreg_lo{src0} (opt_S); */
+ /* sop == 1 : opt_S */
+ int l, endl;
+
+ /* XXX: Missing V/VS update */
+ if (sop == 1) {
+ unhandled_instruction(dc, "[AL]SHIFT with (S)");
+ }
+
+ tmp = tcg_temp_local_new();
+ gen_extNsi_tl(tmp, cpu_dreg[src0], 6);
+
+ /* Negative shift means logical or arith shift right */
+ endl = gen_new_label();
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_GE, tmp, 0, l);
+ tcg_gen_neg_tl(tmp, tmp);
+ if (sop == 2) {
+ tcg_gen_shr_tl(cpu_dreg[dst0], cpu_dreg[src1], tmp);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT_RT32, cpu_dreg[dst0]);
+ } else {
+ tcg_gen_sar_tl(cpu_dreg[dst0], cpu_dreg[src1], tmp);
+ astat_queue_state1(dc, ASTAT_OP_ASHIFT32, cpu_dreg[dst0]);
+ }
+ tcg_gen_br(endl);
+
+ /* Positive shift is a logical left shift */
+ gen_set_label(l);
+ tcg_gen_shl_tl(cpu_dreg[dst0], cpu_dreg[src1], tmp);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT32, cpu_dreg[dst0]);
+ gen_set_label(endl);
+
+ tcg_temp_free(tmp);
+ } else if (sop == 3 && sopcde == 2) {
+ /* Dreg{dst0} = ROT Dreg{src1} BY Dreg_lo{src0}; */
+ tmp = tcg_temp_local_new();
+ tcg_gen_ext16s_tl(tmp, cpu_dreg[src0]);
+ gen_rot_tl(cpu_dreg[dst0], cpu_dreg[src1], tmp);
+ tcg_temp_free(tmp);
+ } else if (sop == 2 && sopcde == 1) {
+ /* Dreg{dst0} = LSHIFT Dreg{src1} BY Dreg_lo{src0} (V); */
+ unhandled_instruction(dc, "LSHIFT (V)");
+ } else if (sopcde == 4) {
+ /* Dreg{dst0} = PACK (Dreg{src1}_hi{sop&2}, Dreg{src0}_hi{sop&1}); */
+ /* Dreg{dst0} = PACK (Dreg{src1}_lo{!sop&2}, Dreg{src0}_lo{!sop&1}); */
+ TCGv tmph;
+ tmp = tcg_temp_new();
+ if (sop & 1) {
+ tcg_gen_shri_tl(tmp, cpu_dreg[src0], 16);
+ } else {
+ tcg_gen_andi_tl(tmp, cpu_dreg[src0], 0xffff);
+ }
+ tmph = tcg_temp_new();
+ if (sop & 2) {
+ tcg_gen_andi_tl(tmph, cpu_dreg[src1], 0xffff0000);
+ } else {
+ tcg_gen_shli_tl(tmph, cpu_dreg[src1], 16);
+ }
+ tcg_gen_or_tl(cpu_dreg[dst0], tmph, tmp);
+ tcg_temp_free(tmph);
+ tcg_temp_free(tmp);
+ } else if (sop == 0 && sopcde == 5) {
+ /* Dreg_lo{dst0} = SIGNBITS Dreg{src1}; */
+ tmp = tcg_temp_new();
+ gen_signbitsi_tl(tmp, cpu_dreg[src1], 32);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ } else if (sop == 1 && sopcde == 5) {
+ /* Dreg_lo{dst0} = SIGNBITS Dreg_lo{src1}; */
+ tmp = tcg_temp_new();
+ gen_signbitsi_tl(tmp, cpu_dreg[src1], 16);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ } else if (sop == 2 && sopcde == 5) {
+ /* Dreg_lo{dst0} = SIGNBITS Dreg_hi{src1}; */
+ tmp = tcg_temp_new();
+ tcg_gen_shri_tl(tmp, cpu_dreg[src1], 16);
+ gen_signbitsi_tl(tmp, tmp, 16);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ } else if ((sop == 0 || sop == 1) && sopcde == 6) {
+ /* Dreg_lo{dst0} = SIGNBITS Areg{sop}; */
+ tmp = tcg_temp_new();
+ gen_signbitsi_i64_i32(tmp, cpu_areg[sop], 40);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ } else if (sop == 3 && sopcde == 6) {
+ /* Dreg_lo{dst0} = ONES Dreg{src1}; */
+ tmp = tcg_temp_new();
+ gen_helper_ones(tmp, cpu_dreg[src1]);
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ } else if (sop == 0 && sopcde == 7) {
+ /* Dreg_lo{dst0} = EXPADJ( Dreg{src1}, Dreg_lo{src0}); */
+ unhandled_instruction(dc, "EXPADJ");
+ } else if (sop == 1 && sopcde == 7) {
+ /* Dreg_lo{dst0} = EXPADJ( Dreg{src1}, Dreg_lo{src0}) (V); */
+ unhandled_instruction(dc, "EXPADJ (V)");
+ } else if (sop == 2 && sopcde == 7) {
+ /* Dreg_lo{dst0} = EXPADJ( Dreg_lo{src1}, Dreg_lo{src0}) (V); */
+ unhandled_instruction(dc, "EXPADJ");
+ } else if (sop == 3 && sopcde == 7) {
+ /* Dreg_lo{dst0} = EXPADJ( Dreg_hi{src1}, Dreg_lo{src0}); */
+ unhandled_instruction(dc, "EXPADJ");
+ } else if (sop == 0 && sopcde == 8) {
+ /* BITMUX (Dreg{src0}, Dreg{src1}, A0) (ASR); */
+ unhandled_instruction(dc, "BITMUX");
+ } else if (sop == 1 && sopcde == 8) {
+ /* BITMUX (Dreg{src0}, Dreg{src1}, A0) (ASL); */
+ unhandled_instruction(dc, "BITMUX");
+ } else if ((sop == 0 || sop == 1) && sopcde == 9) {
+ /* Dreg_lo{dst0} = VIT_MAX (Dreg{src1}) (ASL){sop==0}; */
+ /* Dreg_lo{dst0} = VIT_MAX (Dreg{src1}) (ASR){sop==1}; */
+ TCGv sl, sh;
+ int l;
+
+ gen_extend_acc(cpu_areg[0]);
+ if (sop & 1) {
+ tcg_gen_shri_i64(cpu_areg[0], cpu_areg[0], 1);
+ } else {
+ tcg_gen_shli_i64(cpu_areg[0], cpu_areg[0], 1);
+ }
+
+ sl = tcg_temp_local_new();
+ sh = tcg_temp_local_new();
+ tmp = tcg_temp_local_new();
+
+ tcg_gen_ext16s_tl(sl, cpu_dreg[src1]);
+ tcg_gen_sari_tl(sh, cpu_dreg[src1], 16);
+ /* Hrm, can't this sub be inlined in the branch ? */
+ tcg_gen_sub_tl(tmp, sh, sl);
+ tcg_gen_andi_tl(tmp, tmp, 0x8000);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 0, l);
+ tcg_gen_mov_tl(sl, sh);
+ tcg_gen_ori_i64(cpu_areg[0], cpu_areg[0], (sop & 1) ? 0x80000000 : 1);
+ gen_set_label(l);
+
+ gen_mov_l_tl(cpu_dreg[dst0], sl);
+
+ tcg_temp_free(tmp);
+ tcg_temp_free(sh);
+ tcg_temp_free(sl);
+ } else if ((sop == 2 || sop == 3) && sopcde == 9) {
+ /* Dreg{dst0} = VIT_MAX (Dreg{src1}, Dreg{src0}) (ASL){sop==0}; */
+ /* Dreg{dst0} = VIT_MAX (Dreg{src1}, Dreg{src0}) (ASR){sop==1}; */
+ TCGv sl, sh, dst;
+ int l;
+
+ gen_extend_acc(cpu_areg[0]);
+ if (sop & 1) {
+ tcg_gen_shri_i64(cpu_areg[0], cpu_areg[0], 2);
+ } else {
+ tcg_gen_shli_i64(cpu_areg[0], cpu_areg[0], 2);
+ }
+
+ sl = tcg_temp_local_new();
+ sh = tcg_temp_local_new();
+ tmp = tcg_temp_local_new();
+
+ tcg_gen_ext16s_tl(sl, cpu_dreg[src1]);
+ tcg_gen_sari_tl(sh, cpu_dreg[src1], 16);
+
+ /* Hrm, can't this sub be inlined in the branch ? */
+ tcg_gen_sub_tl(tmp, sh, sl);
+ tcg_gen_andi_tl(tmp, tmp, 0x8000);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 0, l);
+ tcg_gen_mov_tl(sl, sh);
+ tcg_gen_ori_i64(cpu_areg[0], cpu_areg[0], (sop & 1) ? 0x80000000 : 1);
+ gen_set_label(l);
+
+ /* The dst might be a src reg */
+ if (dst0 == src0) {
+ dst = tcg_temp_local_new();
+ } else {
+ dst = cpu_dreg[dst0];
+ }
+
+ tcg_gen_shli_tl(dst, sl, 16);
+
+ tcg_gen_ext16s_tl(sl, cpu_dreg[src0]);
+ tcg_gen_sari_tl(sh, cpu_dreg[src0], 16);
+ /* Hrm, can't this sub be inlined in the branch ? */
+ tcg_gen_sub_tl(tmp, sh, sl);
+ tcg_gen_andi_tl(tmp, tmp, 0x8000);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 0, l);
+ tcg_gen_mov_tl(sl, sh);
+ tcg_gen_ori_i64(cpu_areg[0], cpu_areg[0], (sop & 1) ? 0x40000000 : 2);
+ gen_set_label(l);
+
+ gen_mov_l_tl(dst, sl);
+
+ if (dst0 == src0) {
+ tcg_gen_mov_tl(cpu_dreg[dst0], dst);
+ tcg_temp_free(dst);
+ }
+
+ tcg_temp_free(tmp);
+ tcg_temp_free(sh);
+ tcg_temp_free(sl);
+ } else if ((sop == 0 || sop == 1) && sopcde == 10) {
+ /* Dreg{dst0} = EXTRACT (Dreg{src1}, Dreg_lo{src0}) (X{sop==1}); */
+ /* Dreg{dst0} = EXTRACT (Dreg{src1}, Dreg_lo{src0}) (Z{sop==0}); */
+ TCGv mask, x, sgn;
+
+ /* mask = 1 << (src0 & 0x1f) */
+ tmp = tcg_temp_new();
+ tcg_gen_andi_tl(tmp, cpu_dreg[src0], 0x1f);
+ mask = tcg_temp_local_new();
+ tcg_gen_movi_tl(mask, 1);
+ tcg_gen_shl_tl(mask, mask, tmp);
+ tcg_temp_free(tmp);
+ if (sop) {
+ /* sgn = mask >> 1 */
+ sgn = tcg_temp_local_new();
+ tcg_gen_shri_tl(sgn, mask, 1);
+ }
+ /* mask -= 1 */
+ tcg_gen_subi_tl(mask, mask, 1);
+
+ /* x = src1 >> ((src0 >> 8) & 0x1f) */
+ tmp = tcg_temp_new();
+ x = tcg_temp_new();
+ tcg_gen_shri_tl(tmp, cpu_dreg[src0], 8);
+ tcg_gen_andi_tl(tmp, tmp, 0x1f);
+ tcg_gen_shr_tl(x, cpu_dreg[src1], tmp);
+ tcg_temp_free(tmp);
+ /* dst0 = x & mask */
+ tcg_gen_and_tl(cpu_dreg[dst0], x, mask);
+ tcg_temp_free(x);
+
+ if (sop) {
+ /* if (dst0 & sgn) dst0 |= ~mask */
+ int l;
+ l = gen_new_label();
+ tmp = tcg_temp_new();
+ tcg_gen_and_tl(tmp, cpu_dreg[dst0], sgn);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, tmp, 0, l);
+ tcg_gen_not_tl(mask, mask);
+ tcg_gen_or_tl(cpu_dreg[dst0], cpu_dreg[dst0], mask);
+ gen_set_label(l);
+ tcg_temp_free(sgn);
+ tcg_temp_free(tmp);
+ }
+
+ tcg_temp_free(mask);
+
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst0]);
+ } else if ((sop == 2 || sop == 3) && sopcde == 10) {
+ /* The first dregs is the "background" while the second dregs is the
+ * "foreground". The fg reg is used to overlay the bg reg and is:
+ * | nnnn nnnn | nnnn nnnn | xxxp pppp | xxxL LLLL |
+ * n = the fg bit field
+ * p = bit position in bg reg to start LSB of fg field
+ * L = number of fg bits to extract
+ * Using (X) sign-extends the fg bit field.
+ */
+ TCGv fg, bg, len, mask, fgnd, shft;
+
+ /* Dreg{dst0} = DEPOSIT (Dreg{src1}, Dreg{src0}) (X){sop==3}; */
+ fg = cpu_dreg[src0];
+ bg = cpu_dreg[src1];
+
+ len = tcg_temp_new();
+ tcg_gen_andi_tl(len, fg, 0x1f);
+
+ mask = tcg_temp_new();
+ tcg_gen_movi_tl(mask, 1);
+ tcg_gen_shl_tl(mask, mask, len);
+ tcg_gen_subi_tl(mask, mask, 1);
+ tcg_gen_andi_tl(mask, mask, 0xffff);
+
+ fgnd = tcg_temp_new();
+ tcg_gen_shri_tl(fgnd, fg, 16);
+ tcg_gen_and_tl(fgnd, fgnd, mask);
+
+ shft = tcg_temp_new();
+ tcg_gen_shri_tl(shft, fg, 8);
+ tcg_gen_andi_tl(shft, shft, 0x1f);
+
+ if (sop == 3) {
+ /* Sign extend the fg bit field. */
+ tcg_gen_movi_tl(mask, -1);
+ gen_extNs_tl(fgnd, fgnd, len);
+ }
+ tcg_gen_shl_tl(fgnd, fgnd, shft);
+ tcg_gen_shl_tl(mask, mask, shft);
+ tcg_gen_not_tl(mask, mask);
+ tcg_gen_and_tl(mask, bg, mask);
+
+ tcg_gen_or_tl(cpu_dreg[dst0], mask, fgnd);
+
+ tcg_temp_free(shft);
+ tcg_temp_free(fgnd);
+ tcg_temp_free(mask);
+ tcg_temp_free(len);
+
+ astat_queue_state1(dc, ASTAT_OP_LOGICAL, cpu_dreg[dst0]);
+ } else if (sop == 0 && sopcde == 11) {
+ /* Dreg_lo{dst0} = CC = BXORSHIFT (A0, Dreg{src0}); */
+ unhandled_instruction(dc, "BXORSHIFT");
+ } else if (sop == 1 && sopcde == 11) {
+ /* Dreg_lo{dst0} = CC = BXOR (A0, Dreg{src0}); */
+ unhandled_instruction(dc, "BXOR");
+ } else if (sop == 0 && sopcde == 12) {
+ /* A0 = BXORSHIFT (A0, A1, CC); */
+ unhandled_instruction(dc, "BXORSHIFT");
+ } else if (sop == 1 && sopcde == 12) {
+ /* Dreg_lo{dst0} = CC = BXOR (A0, A1, CC); */
+ unhandled_instruction(dc, "CC = BXOR");
+ } else if ((sop == 0 || sop == 1 || sop == 2) && sopcde == 13) {
+ int shift = (sop + 1) * 8;
+ TCGv tmp2;
+ /* Dreg{dst0} = ALIGN{shift} (Dreg{src1}, Dreg{src0}); */
+ /* XXX: could be optimized a bit if dst0 is not src1 or src0 */
+ tmp = tcg_temp_new();
+ tmp2 = tcg_temp_new();
+ tcg_gen_shli_tl(tmp, cpu_dreg[src1], 32 - shift);
+ tcg_gen_shri_tl(tmp2, cpu_dreg[src0], shift);
+ tcg_gen_or_tl(cpu_dreg[dst0], tmp, tmp2);
+ tcg_temp_free(tmp2);
+ tcg_temp_free(tmp);
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_dsp32shiftimm_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* dsp32shiftimm
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
+ |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int src1 = ((iw1 >> DSP32ShiftImm_src1_bits) & DSP32ShiftImm_src1_mask);
+ int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
+ int bit8 = ((iw1 >> 8) & 0x1);
+ int immag = ((iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
+ int newimmag = (-(iw1 >> DSP32ShiftImm_immag_bits) & DSP32ShiftImm_immag_mask);
+ int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
+ int M = ((iw0 >> (DSP32ShiftImm_M_bits - 16)) & DSP32ShiftImm_M_mask);
+ int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
+ int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
+ TCGv tmp;
+
+ TRACE_EXTRACT("M:%i sopcde:%i sop:%i HLs:%i dst0:%i immag:%#x src1:%i",
+ M, sopcde, sop, HLs, dst0, immag, src1);
+
+ if (sopcde == 0) {
+ tmp = tcg_temp_new();
+
+ if (HLs & 1) {
+ if (sop == 0) {
+ tcg_gen_sari_tl(tmp, cpu_dreg[src1], 16);
+ } else {
+ tcg_gen_shri_tl(tmp, cpu_dreg[src1], 16);
+ }
+ } else {
+ if (sop == 0) {
+ tcg_gen_ext16s_tl(tmp, cpu_dreg[src1]);
+ } else {
+ tcg_gen_ext16u_tl(tmp, cpu_dreg[src1]);
+ }
+ }
+
+ if (sop == 0) {
+ /* dregs_hi/lo = dregs_hi/lo >>> imm4 */
+ tcg_gen_sari_tl(tmp, tmp, newimmag);
+ astat_queue_state1(dc, ASTAT_OP_ASHIFT16, tmp);
+ } else if (sop == 1 && bit8 == 0) {
+ /* dregs_hi/lo = dregs_hi/lo << imm4 (S) */
+ tcg_gen_shli_tl(tmp, tmp, immag);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT16, tmp);
+ } else if (sop == 1 && bit8) {
+ /* dregs_hi/lo = dregs_hi/lo >>> imm4 (S) */
+ tcg_gen_shri_tl(tmp, tmp, immag);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT16, tmp);
+ } else if (sop == 2 && bit8) {
+ /* dregs_hi/lo = dregs_hi/lo >> imm4 */
+ tcg_gen_shri_tl(tmp, tmp, newimmag);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT16, tmp);
+ } else if (sop == 2 && bit8 == 0) {
+ /* dregs_hi/lo = dregs_hi/lo << imm4 */
+ tcg_gen_shli_tl(tmp, tmp, immag);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT16, tmp);
+ } else {
+ illegal_instruction(dc);
+ }
+
+ if (HLs & 2) {
+ gen_mov_h_tl(cpu_dreg[dst0], tmp);
+ } else {
+ gen_mov_l_tl(cpu_dreg[dst0], tmp);
+ }
+
+ tcg_temp_free(tmp);
+ } else if (sop == 2 && sopcde == 3 && (HLs == 1 || HLs == 0)) {
+ /* Areg{HLs} = ROT Areg{HLs} BY imm{immag}; */
+ int shift = imm6(immag);
+ gen_roti_i64(cpu_areg[HLs], cpu_areg[HLs], shift);
+ } else if (sop == 0 && sopcde == 3 && bit8 == 1) {
+ /* Arithmetic shift, so shift in sign bit copies */
+ int shift = uimm5(newimmag);
+ HLs = !!HLs;
+
+ /* Areg{HLs} = Aregs{HLs} >>> imm{newimmag}; */
+ tcg_gen_sari_i64(cpu_areg[HLs], cpu_areg[HLs], shift);
+ } else if ((sop == 0 && sopcde == 3 && bit8 == 0) ||
+ (sop == 1 && sopcde == 3)) {
+ int shiftup = uimm5(immag);
+ int shiftdn = uimm5(newimmag);
+ HLs = !!HLs;
+
+ if (sop == 0) {
+ /* Areg{HLs} = Aregs{HLs} <<{sop} imm{immag}; */
+ tcg_gen_shli_i64(cpu_areg[HLs], cpu_areg[HLs], shiftup);
+ } else {
+ /* Areg{HLs} = Aregs{HLs} >>{sop} imm{newimmag}; */
+ tcg_gen_shri_i64(cpu_areg[HLs], cpu_areg[HLs], shiftdn);
+ }
+
+ /* XXX: Missing ASTAT update */
+ } else if (sop == 1 && sopcde == 1 && bit8 == 0) {
+ /* Dreg{dst0} = Dreg{src1} << imm{immag} (V, S); */
+ unhandled_instruction(dc, "Dreg = Dreg << imm (V,S)");
+ } else if (sop == 2 && sopcde == 1 && bit8 == 1) {
+ /* Dreg{dst0} = Dreg{src1} >> imm{count} (V); */
+ int count = imm5(newimmag);
+
+ /* XXX: No ASTAT handling */
+ if (count > 0 && count <= 15) {
+ tcg_gen_shri_tl(cpu_dreg[dst0], cpu_dreg[src1], count);
+ tcg_gen_andi_tl(cpu_dreg[dst0], cpu_dreg[dst0],
+ 0xffff0000 | ((1 << (16 - count)) - 1));
+ } else if (count) {
+ tcg_gen_movi_tl(cpu_dreg[dst0], 0);
+ }
+ } else if (sop == 2 && sopcde == 1 && bit8 == 0) {
+ /* Dreg{dst0} = Dreg{src1} << imm{count} (V); */
+ int count = imm5(immag);
+
+ /* XXX: No ASTAT handling */
+ if (count > 0 && count <= 15) {
+ tcg_gen_shli_tl(cpu_dreg[dst0], cpu_dreg[src1], count);
+ tcg_gen_andi_tl(cpu_dreg[dst0], cpu_dreg[dst0],
+ ~(((1 << count) - 1) << 16));
+ } else if (count) {
+ tcg_gen_movi_tl(cpu_dreg[dst0], 0);
+ }
+ } else if (sopcde == 1 && (sop == 0 || (sop == 1 && bit8 == 1))) {
+ /* Dreg{dst0} = Dreg{src1} >>> imm{newimmag} (V){sop==0}; */
+ /* Dreg{dst0} = Dreg{src1} >>> imm{newimmag} (V,S){sop==1}; */
+ int count = uimm5(newimmag);
+
+ if (sop == 1) {
+ unhandled_instruction(dc, "ashiftrt (S)");
+ }
+
+ /* XXX: No ASTAT handling */
+ if (count > 0 && count <= 15) {
+ tmp = tcg_temp_new();
+ tcg_gen_ext16s_tl(tmp, cpu_dreg[src1]);
+ tcg_gen_sari_tl(tmp, tmp, count);
+ tcg_gen_andi_tl(tmp, tmp, 0xffff);
+ tcg_gen_sari_tl(cpu_dreg[dst0], cpu_dreg[src1], count);
+ tcg_gen_andi_tl(cpu_dreg[dst0], cpu_dreg[dst0], 0xffff0000);
+ tcg_gen_or_tl(cpu_dreg[dst0], cpu_dreg[dst0], tmp);
+ tcg_temp_free(tmp);
+ } else if (count) {
+ unhandled_instruction(dc, "ashiftrt (S)");
+ }
+ } else if (sop == 1 && sopcde == 2) {
+ /* Dreg{dst0} = Dreg{src1} << imm{count} (S); */
+ int count = imm6(immag);
+ tcg_gen_shli_tl(cpu_dreg[dst0], cpu_dreg[src1], -count);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT32, cpu_dreg[dst0]);
+ } else if (sop == 2 && sopcde == 2) {
+ /* Dreg{dst0} = Dreg{src1} >> imm{count}; */
+ int count = imm6(newimmag);
+ if (count < 0) {
+ tcg_gen_shli_tl(cpu_dreg[dst0], cpu_dreg[src1], -count);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT32, cpu_dreg[dst0]);
+ } else {
+ tcg_gen_shri_tl(cpu_dreg[dst0], cpu_dreg[src1], count);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT_RT32, cpu_dreg[dst0]);
+ }
+ } else if (sop == 3 && sopcde == 2) {
+ /* Dreg{dst0} = ROT Dreg{src1} BY imm{shift}; */
+ int shift = imm6(immag);
+ gen_roti_tl(cpu_dreg[dst0], cpu_dreg[src1], shift);
+ } else if (sop == 0 && sopcde == 2) {
+ /* Dreg{dst0} = Dreg{src1} >>> imm{count}; */
+ int count = imm6(newimmag);
+
+ /* Negative shift magnitudes produce Logical Left shifts.
+ * Positive shift magnitudes produce Arithmetic Right shifts.
+ */
+ if (count < 0) {
+ tcg_gen_shli_tl(cpu_dreg[dst0], cpu_dreg[src1], -count);
+ astat_queue_state1(dc, ASTAT_OP_LSHIFT32, cpu_dreg[dst0]);
+ } else {
+ tcg_gen_sari_tl(cpu_dreg[dst0], cpu_dreg[src1], count);
+ astat_queue_state1(dc, ASTAT_OP_ASHIFT32, cpu_dreg[dst0]);
+ }
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_psedoDEBUG_0(DisasContext *dc, uint16_t iw0)
+{
+ /* psedoDEBUG
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |.fn....|.grp.......|.reg.......|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int fn = ((iw0 >> PseudoDbg_fn_bits) & PseudoDbg_fn_mask);
+ int grp = ((iw0 >> PseudoDbg_grp_bits) & PseudoDbg_grp_mask);
+ int reg = ((iw0 >> PseudoDbg_reg_bits) & PseudoDbg_reg_mask);
+
+ TRACE_EXTRACT("fn:%i grp:%i reg:%i", fn, grp, reg);
+
+ if ((reg == 0 || reg == 1) && fn == 3) {
+ /* DBG Areg{reg}; */
+ TCGv tmp = tcg_const_tl(reg);
+ gen_helper_dbg_areg(cpu_areg[reg], tmp);
+ tcg_temp_free(tmp);
+ } else if (reg == 3 && fn == 3) {
+ /* ABORT; */
+ cec_exception(dc, EXCP_ABORT);
+ } else if (reg == 4 && fn == 3) {
+ /* HLT; */
+ cec_exception(dc, EXCP_HLT);
+ } else if (reg == 5 && fn == 3) {
+ unhandled_instruction(dc, "DBGHALT");
+ } else if (reg == 6 && fn == 3) {
+ unhandled_instruction(dc, "DBGCMPLX (dregs)");
+ } else if (reg == 7 && fn == 3) {
+ unhandled_instruction(dc, "DBG");
+ } else if (grp == 0 && fn == 2) {
+ /* OUTC Dreg{reg}; */
+ gen_helper_outc(cpu_dreg[reg]);
+ } else if (fn == 0) {
+ /* DBG allreg{grp,reg}; */
+ bool istmp;
+ TCGv tmp;
+ TCGv tmp_grp = tcg_const_tl(grp);
+ TCGv tmp_reg = tcg_const_tl(reg);
+
+ if (grp == 4 && reg == 6) {
+ /* ASTAT */
+ tmp = tcg_temp_new();
+ gen_astat_load(dc, tmp);
+ istmp = true;
+ } else {
+ tmp = get_allreg(dc, grp, reg);
+ istmp = false;
+ }
+
+ gen_helper_dbg(tmp, tmp_grp, tmp_reg);
+
+ if (istmp) {
+ tcg_temp_free(tmp);
+ }
+ tcg_temp_free(tmp_reg);
+ tcg_temp_free(tmp_grp);
+ } else if (fn == 1) {
+ unhandled_instruction(dc, "PRNT allregs");
+ } else {
+ illegal_instruction(dc);
+ }
+}
+
+static void
+decode_psedoOChar_0(DisasContext *dc, uint16_t iw0)
+{
+ /* psedoOChar
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |.ch............................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int ch = ((iw0 >> PseudoChr_ch_bits) & PseudoChr_ch_mask);
+ TCGv tmp;
+
+ TRACE_EXTRACT("ch:%#x", ch);
+
+ /* OUTC imm{ch}; */
+ tmp = tcg_temp_new();
+ tcg_gen_movi_tl(tmp, ch);
+ gen_helper_outc(tmp);
+ tcg_temp_free(tmp);
+}
+
+static void
+decode_psedodbg_assert_0(DisasContext *dc, uint16_t iw0, uint16_t iw1)
+{
+ /* psedodbg_assert
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+ | 1 | 1 | 1 | 1 | 0 | - | - | - | dbgop |.grp.......|.regtest...|
+ |.expected......................................................|
+ +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
+ int expected = ((iw1 >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask);
+ int dbgop = ((iw0 >> (PseudoDbg_Assert_dbgop_bits - 16)) & PseudoDbg_Assert_dbgop_mask);
+ int grp = ((iw0 >> (PseudoDbg_Assert_grp_bits - 16)) & PseudoDbg_Assert_grp_mask);
+ int regtest = ((iw0 >> (PseudoDbg_Assert_regtest_bits - 16)) & PseudoDbg_Assert_regtest_mask);
+ TCGv reg, exp, pc;
+ bool istmp;
+
+ TRACE_EXTRACT("dbgop:%i grp:%i regtest:%i expected:%#x",
+ dbgop, grp, regtest, expected);
+
+ if (dbgop == 0 || dbgop == 2) {
+ /* DBGA (genreg_lo{grp,regtest}, imm{expected} */
+ /* DBGAL (genreg{grp,regtest}, imm{expected} */
+ } else if (dbgop == 1 || dbgop == 3) {
+ /* DBGA (genreg_hi{grp,regtest}, imm{expected} */
+ /* DBGAH (genreg{grp,regtest}, imm{expected} */
+ } else {
+ illegal_instruction(dc);
+ }
+
+ if (grp == 4 && regtest == 6) {
+ /* ASTAT */
+ reg = tcg_temp_new();
+ gen_astat_load(dc, reg);
+ istmp = true;
+ } else if (grp == 4 && (regtest == 0 || regtest == 2)) {
+ /* A#.X */
+ TCGv_i64 tmp64 = tcg_temp_new_i64();
+ reg = tcg_temp_new();
+ tcg_gen_shri_i64(tmp64, cpu_areg[regtest >> 1], 32);
+ tcg_gen_andi_i64(tmp64, tmp64, 0xff);
+ tcg_gen_trunc_i64_i32(reg, tmp64);
+ tcg_temp_free_i64(tmp64);
+ istmp = true;
+ } else if (grp == 4 && (regtest == 1 || regtest == 3)) {
+ /* A#.W */
+ reg = tcg_temp_new();
+ tcg_gen_trunc_i64_i32(reg, cpu_areg[regtest >> 1]);
+ istmp = true;
+ } else {
+ reg = get_allreg(dc, grp, regtest);
+ istmp = false;
+ }
+
+ exp = tcg_const_tl(expected);
+ pc = tcg_const_tl(dc->pc);
+ if (dbgop & 1) {
+ gen_helper_dbga_h(cpu_env, pc, reg, exp);
+ } else {
+ gen_helper_dbga_l(cpu_env, pc, reg, exp);
+ }
+
+ if (istmp) {
+ tcg_temp_free(reg);
+ }
+ tcg_temp_free(pc);
+ tcg_temp_free(exp);
+}
+
+#include "linux-fixed-code.h"
+
+static uint32_t bfin_lduw_code(DisasContext *dc, target_ulong pc)
+{
+#ifdef CONFIG_USER_ONLY
+ /* Intercept jump to the magic kernel page */
+ if (((dc->env->personality & 0xff/*PER_MASK*/) == 0/*PER_LINUX*/) &&
+ (pc & 0xFFFFFF00) == 0x400) {
+ uint32_t off = pc - 0x400;
+ if (off < sizeof(bfin_linux_fixed_code)) {
+ return ((uint16_t)bfin_linux_fixed_code[off + 1] << 8) |
+ bfin_linux_fixed_code[off];
+ }
+ }
+#endif
+
+ return cpu_lduw_code(dc->env, pc);
+}
+
+/* Interpret a single 16bit/32bit insn; no parallel insn handling */
+static void
+_interp_insn_bfin(DisasContext *dc, target_ulong pc)
+{
+ uint16_t iw0, iw1;
+
+ iw0 = bfin_lduw_code(dc, pc);
+ if ((iw0 & 0xc000) != 0xc000) {
+ /* 16-bit opcode */
+ dc->insn_len = 2;
+
+ TRACE_EXTRACT("iw0:%#x", iw0);
+ if ((iw0 & 0xFF00) == 0x0000) {
+ decode_ProgCtrl_0(dc, iw0);
+ } else if ((iw0 & 0xFFC0) == 0x0240) {
+ decode_CaCTRL_0(dc, iw0);
+ } else if ((iw0 & 0xFF80) == 0x0100) {
+ decode_PushPopReg_0(dc, iw0);
+ } else if ((iw0 & 0xFE00) == 0x0400) {
+ decode_PushPopMultiple_0(dc, iw0);
+ } else if ((iw0 & 0xFE00) == 0x0600) {
+ decode_ccMV_0(dc, iw0);
+ } else if ((iw0 & 0xF800) == 0x0800) {
+ decode_CCflag_0(dc, iw0);
+ } else if ((iw0 & 0xFFE0) == 0x0200) {
+ decode_CC2dreg_0(dc, iw0);
+ } else if ((iw0 & 0xFF00) == 0x0300) {
+ decode_CC2stat_0(dc, iw0);
+ } else if ((iw0 & 0xF000) == 0x1000) {
+ decode_BRCC_0(dc, iw0);
+ } else if ((iw0 & 0xF000) == 0x2000) {
+ decode_UJUMP_0(dc, iw0);
+ } else if ((iw0 & 0xF000) == 0x3000) {
+ decode_REGMV_0(dc, iw0);
+ } else if ((iw0 & 0xFC00) == 0x4000) {
+ decode_ALU2op_0(dc, iw0);
+ } else if ((iw0 & 0xFE00) == 0x4400) {
+ decode_PTR2op_0(dc, iw0);
+ } else if ((iw0 & 0xF800) == 0x4800) {
+ decode_LOGI2op_0(dc, iw0);
+ } else if ((iw0 & 0xF000) == 0x5000) {
+ decode_COMP3op_0(dc, iw0);
+ } else if ((iw0 & 0xF800) == 0x6000) {
+ decode_COMPI2opD_0(dc, iw0);
+ } else if ((iw0 & 0xF800) == 0x6800) {
+ decode_COMPI2opP_0(dc, iw0);
+ } else if ((iw0 & 0xF000) == 0x8000) {
+ decode_LDSTpmod_0(dc, iw0);
+ } else if ((iw0 & 0xFF60) == 0x9E60) {
+ decode_dagMODim_0(dc, iw0);
+ } else if ((iw0 & 0xFFF0) == 0x9F60) {
+ decode_dagMODik_0(dc, iw0);
+ } else if ((iw0 & 0xFC00) == 0x9C00) {
+ decode_dspLDST_0(dc, iw0);
+ } else if ((iw0 & 0xF000) == 0x9000) {
+ decode_LDST_0(dc, iw0);
+ } else if ((iw0 & 0xFC00) == 0xB800) {
+ decode_LDSTiiFP_0(dc, iw0);
+ } else if ((iw0 & 0xE000) == 0xA000) {
+ decode_LDSTii_0(dc, iw0);
+ } else {
+ TRACE_EXTRACT("no matching 16-bit pattern");
+ illegal_instruction(dc);
+ }
+ return;
+ }
+
+ /* Grab the next 16 bits to determine if it's a 32-bit or 64-bit opcode */
+ iw1 = bfin_lduw_code(dc, pc + 2);
+ if ((iw0 & BIT_MULTI_INS) && (iw0 & 0xe800) != 0xe800 /* not linkage */) {
+ dc->insn_len = 8;
+ } else {
+ dc->insn_len = 4;
+ }
+
+ TRACE_EXTRACT("iw0:%#x iw1:%#x insn_len:%i",
+ iw0, iw1, dc->insn_len);
+
+ if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800) {
+ /* MNOP; */;
+ } else if (((iw0 & 0xFF80) == 0xE080) && ((iw1 & 0x0C00) == 0x0000)) {
+ decode_LoopSetup_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xFF00) == 0xE100) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_LDIMMhalf_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xFE00) == 0xE200) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_CALLa_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xFC00) == 0xE400) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_LDSTidxI_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xFFFE) == 0xE800) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_linkage_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xF600) == 0xC000) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_dsp32mac_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xF600) == 0xC200) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_dsp32mult_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xF7C0) == 0xC400) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_dsp32alu_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xF7E0) == 0xC600) && ((iw1 & 0x01C0) == 0x0000)) {
+ decode_dsp32shift_0(dc, iw0, iw1);
+ } else if (((iw0 & 0xF7E0) == 0xC680) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_dsp32shiftimm_0(dc, iw0, iw1);
+ } else if ((iw0 & 0xFF00) == 0xF800) {
+ decode_psedoDEBUG_0(dc, iw0), dc->insn_len = 2;
+ } else if ((iw0 & 0xFF00) == 0xF900) {
+ decode_psedoOChar_0(dc, iw0), dc->insn_len = 2;
+ } else if (((iw0 & 0xFF00) == 0xF000) && ((iw1 & 0x0000) == 0x0000)) {
+ decode_psedodbg_assert_0(dc, iw0, iw1);
+ } else {
+ TRACE_EXTRACT("no matching 32-bit pattern");
+ illegal_instruction(dc);
+ }
+}
+
+/* Interpret a single Blackfin insn; breaks up parallel insns */
+static void
+interp_insn_bfin(DisasContext *dc)
+{
+ _interp_insn_bfin(dc, dc->pc);
+
+ /* Proper display of multiple issue instructions */
+ if (dc->insn_len == 8) {
+ _interp_insn_bfin(dc, dc->pc + 4);
+ _interp_insn_bfin(dc, dc->pc + 6);
+ dc->disalgnexcpt = 0;
+ /* Reset back for higher levels to process branches */
+ dc->insn_len = 8;
+ }
+}
diff --git a/target-bfin/bfin-tdep.h b/target-bfin/bfin-tdep.h
new file mode 100644
index 0000000..ef6d325
--- /dev/null
+++ b/target-bfin/bfin-tdep.h
@@ -0,0 +1,94 @@
+/* Target-dependent code for Analog Devices Blackfin processer, for GDB.
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Contributed by Analog Devices.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+enum gdb_regnum {
+ /* Core Registers */
+ BFIN_R0_REGNUM = 0,
+ BFIN_R1_REGNUM,
+ BFIN_R2_REGNUM,
+ BFIN_R3_REGNUM,
+ BFIN_R4_REGNUM,
+ BFIN_R5_REGNUM,
+ BFIN_R6_REGNUM,
+ BFIN_R7_REGNUM,
+ BFIN_P0_REGNUM,
+ BFIN_P1_REGNUM,
+ BFIN_P2_REGNUM,
+ BFIN_P3_REGNUM,
+ BFIN_P4_REGNUM,
+ BFIN_P5_REGNUM,
+ BFIN_SP_REGNUM,
+ BFIN_FP_REGNUM,
+ BFIN_I0_REGNUM,
+ BFIN_I1_REGNUM,
+ BFIN_I2_REGNUM,
+ BFIN_I3_REGNUM,
+ BFIN_M0_REGNUM,
+ BFIN_M1_REGNUM,
+ BFIN_M2_REGNUM,
+ BFIN_M3_REGNUM,
+ BFIN_B0_REGNUM,
+ BFIN_B1_REGNUM,
+ BFIN_B2_REGNUM,
+ BFIN_B3_REGNUM,
+ BFIN_L0_REGNUM,
+ BFIN_L1_REGNUM,
+ BFIN_L2_REGNUM,
+ BFIN_L3_REGNUM,
+ BFIN_A0_DOT_X_REGNUM,
+ BFIN_A0_DOT_W_REGNUM,
+ BFIN_A1_DOT_X_REGNUM,
+ BFIN_A1_DOT_W_REGNUM,
+ BFIN_ASTAT_REGNUM,
+ BFIN_RETS_REGNUM,
+ BFIN_LC0_REGNUM,
+ BFIN_LT0_REGNUM,
+ BFIN_LB0_REGNUM,
+ BFIN_LC1_REGNUM,
+ BFIN_LT1_REGNUM,
+ BFIN_LB1_REGNUM,
+ BFIN_CYCLES_REGNUM,
+ BFIN_CYCLES2_REGNUM,
+ BFIN_USP_REGNUM,
+ BFIN_SEQSTAT_REGNUM,
+ BFIN_SYSCFG_REGNUM,
+ BFIN_RETI_REGNUM,
+ BFIN_RETX_REGNUM,
+ BFIN_RETN_REGNUM,
+ BFIN_RETE_REGNUM,
+
+ /* Pseudo Registers */
+ BFIN_PC_REGNUM,
+ BFIN_CC_REGNUM,
+ BFIN_TEXT_ADDR, /* Address of .text section. */
+ BFIN_TEXT_END_ADDR, /* Address of the end of .text section. */
+ BFIN_DATA_ADDR, /* Address of .data section. */
+
+ BFIN_FDPIC_EXEC_REGNUM,
+ BFIN_FDPIC_INTERP_REGNUM,
+
+ /* MMRs */
+ BFIN_IPEND_REGNUM,
+
+ /* LAST ENTRY SHOULD NOT BE CHANGED. */
+ BFIN_NUM_REGS /* The number of all registers. */
+};
diff --git a/target-bfin/cpu-qom.h b/target-bfin/cpu-qom.h
new file mode 100644
index 0000000..697797b
--- /dev/null
+++ b/target-bfin/cpu-qom.h
@@ -0,0 +1,61 @@
+/*
+ * QEMU Blackfin CPU
+ *
+ * Copyright 2007-2013 Mike Frysinger
+ * Copyright 2007-2011 Analog Devices, Inc.
+ *
+ * Licensed under the Lesser GPL 2 or later.
+ */
+
+#ifndef QEMU_BFIN_CPU_QOM_H
+#define QEMU_BFIN_CPU_QOM_H
+
+#include "qom/cpu.h"
+
+#define TYPE_BFIN_CPU "bfin-cpu"
+
+#define BFIN_CPU_CLASS(klass) \
+ OBJECT_CLASS_CHECK(BfinCPUClass, (klass), TYPE_BFIN_CPU)
+#define BFIN_CPU(obj) \
+ OBJECT_CHECK(BfinCPU, (obj), TYPE_BFIN_CPU)
+#define BFIN_CPU_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(BfinCPUClass, (obj), TYPE_BFIN_CPU)
+
+/**
+ * BfinCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An Bfin CPU model.
+ */
+typedef struct BfinCPUClass {
+ /*< private >*/
+ CPUClass parent_class;
+ /*< public >*/
+
+ void (*parent_reset)(CPUState *cpu);
+} BfinCPUClass;
+
+/**
+ * BfinCPU:
+ * @env: #CPUArchState
+ *
+ * An Bfin CPU.
+ */
+typedef struct BfinCPU {
+ /*< private >*/
+ CPUState parent_obj;
+ /*< public >*/
+
+ CPUArchState env;
+} BfinCPU;
+
+static inline BfinCPU *bfin_env_get_cpu(CPUArchState *env)
+{
+ return BFIN_CPU(container_of(env, BfinCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(bfin_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(BfinCPU, env)
+
+#endif
diff --git a/target-bfin/cpu.c b/target-bfin/cpu.c
new file mode 100644
index 0000000..871a1a1
--- /dev/null
+++ b/target-bfin/cpu.c
@@ -0,0 +1,55 @@
+/*
+ * QEMU Blackfin CPU
+ *
+ * Copyright 2007-2013 Mike Frysinger
+ * Copyright 2007-2011 Analog Devices, Inc.
+ *
+ * Licensed under the Lesser GPL 2 or later.
+ */
+
+#include "cpu.h"
+#include "qemu-common.h"
+
+
+/* CPUClass::reset() */
+static void bfin_cpu_reset(CPUState *s)
+{
+ BfinCPU *cpu = BFIN_CPU(s);
+ CPUArchState *env = &cpu->env;
+
+ env->pc = 0xEF000000;
+}
+
+static void bfin_cpu_initfn(Object *obj)
+{
+ CPUState *cs = CPU(obj);
+ BfinCPU *cpu = BFIN_CPU(obj);
+ CPUArchState *env = &cpu->env;
+
+ cs->env_ptr = env;
+ cpu_exec_init(env);
+}
+
+static void bfin_cpu_class_init(ObjectClass *oc, void *data)
+{
+ CPUClass *cc = CPU_CLASS(oc);
+
+ cc->reset = bfin_cpu_reset;
+}
+
+static const TypeInfo bfin_cpu_type_info = {
+ .name = TYPE_BFIN_CPU,
+ .parent = TYPE_CPU,
+ .instance_size = sizeof(BfinCPU),
+ .instance_init = bfin_cpu_initfn,
+ .abstract = false,
+ .class_size = sizeof(BfinCPUClass),
+ .class_init = bfin_cpu_class_init,
+};
+
+static void bfin_cpu_register_types(void)
+{
+ type_register_static(&bfin_cpu_type_info);
+}
+
+type_init(bfin_cpu_register_types)
diff --git a/target-bfin/cpu.h b/target-bfin/cpu.h
new file mode 100644
index 0000000..d288197
--- /dev/null
+++ b/target-bfin/cpu.h
@@ -0,0 +1,236 @@
+/*
+ * Blackfin emulation
+ *
+ * Copyright 2007-2013 Mike Frysinger
+ * Copyright 2007-2011 Analog Devices, Inc.
+ *
+ * Licensed under the Lesser GPL 2 or later.
+ */
+
+#ifndef CPU_BFIN_H
+#define CPU_BFIN_H
+
+struct DisasContext;
+
+#define TARGET_LONG_BITS 32
+
+#define ELF_MACHINE EM_BLACKFIN
+
+#define CPUArchState struct CPUBfinState
+
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/cpu-defs.h"
+
+#define TARGET_HAS_ICE 1
+
+#define EXCP_SYSCALL 0
+#define EXCP_SOFT_BP 1
+#define EXCP_STACK_OVERFLOW 3
+#define EXCP_SINGLE_STEP 0x10
+#define EXCP_TRACE_FULL 0x11
+#define EXCP_UNDEF_INST 0x21
+#define EXCP_ILL_INST 0x22
+#define EXCP_DCPLB_VIOLATE 0x23
+#define EXCP_DATA_MISALGIN 0x24
+#define EXCP_UNRECOVERABLE 0x25
+#define EXCP_DCPLB_MISS 0x26
+#define EXCP_DCPLB_MULT 0x27
+#define EXCP_EMU_WATCH 0x28
+#define EXCP_MISALIG_INST 0x2a
+#define EXCP_ICPLB_PROT 0x2b
+#define EXCP_ICPLB_MISS 0x2c
+#define EXCP_ICPLB_MULT 0x2d
+#define EXCP_ILL_SUPV 0x2e
+#define EXCP_ABORT 0x100
+#define EXCP_DBGA 0x101
+#define EXCP_OUTC 0x102
+
+#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_1
+
+#define BFIN_L1_CACHE_BYTES 32
+
+/* Blackfin does 1K/4K/1M/4M, but for now only support 4k */
+#define TARGET_PAGE_BITS 12
+#define NB_MMU_MODES 2
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+
+#define cpu_init cpu_bfin_init
+#define cpu_exec cpu_bfin_exec
+#define cpu_gen_code cpu_bfin_gen_code
+#define cpu_signal_handler cpu_bfin_signal_handler
+
+/* Indexes into astat array; matches bitpos in hardware too */
+enum {
+ ASTAT_AZ = 0,
+ ASTAT_AN,
+ ASTAT_AC0_COPY,
+ ASTAT_V_COPY,
+ ASTAT_CC = 5,
+ ASTAT_AQ,
+ ASTAT_RND_MOD = 8,
+ ASTAT_AC0 = 12,
+ ASTAT_AC1,
+ ASTAT_AV0 = 16,
+ ASTAT_AV0S,
+ ASTAT_AV1,
+ ASTAT_AV1S,
+ ASTAT_V = 24,
+ ASTAT_VS
+};
+
+typedef struct CPUBfinState {
+ CPU_COMMON
+ int personality;
+
+ uint32_t dreg[8];
+ uint32_t preg[8];
+ uint32_t ireg[4];
+ uint32_t mreg[4];
+ uint32_t breg[4];
+ uint32_t lreg[4];
+ uint64_t areg[2];
+ uint32_t rets;
+ uint32_t lcreg[2], ltreg[2], lbreg[2];
+ uint32_t cycles[2];
+ uint32_t uspreg;
+ uint32_t seqstat;
+ uint32_t syscfg;
+ uint32_t reti;
+ uint32_t retx;
+ uint32_t retn;
+ uint32_t rete;
+ uint32_t emudat;
+ uint32_t pc;
+
+ /* ASTAT bits; broken up for speeeeeeeed */
+ uint32_t astat[32];
+ /* ASTAT delayed helpers */
+ uint32_t astat_op, astat_arg[3];
+} CPUBfinState;
+#define spreg preg[6]
+#define fpreg preg[7]
+
+static inline uint32_t bfin_astat_read(CPUArchState *env)
+{
+ unsigned int i, ret;
+
+ ret = 0;
+ for (i = 0; i < 32; ++i)
+ ret |= (env->astat[i] << i);
+
+ return ret;
+}
+
+static inline void bfin_astat_write(CPUArchState *env, uint32_t astat)
+{
+ unsigned int i;
+ for (i = 0; i < 32; ++i)
+ env->astat[i] = !!(astat & (1 << i));
+}
+
+enum astat_ops {
+ ASTAT_OP_NONE,
+ ASTAT_OP_DYNAMIC,
+ ASTAT_OP_ABS,
+ ASTAT_OP_ABS_VECTOR,
+ ASTAT_OP_ADD16,
+ ASTAT_OP_ADD32,
+ ASTAT_OP_ASHIFT16,
+ ASTAT_OP_ASHIFT32,
+ ASTAT_OP_COMPARE_SIGNED,
+ ASTAT_OP_COMPARE_UNSIGNED,
+ ASTAT_OP_LOGICAL,
+ ASTAT_OP_LSHIFT16,
+ ASTAT_OP_LSHIFT32,
+ ASTAT_OP_LSHIFT_RT16,
+ ASTAT_OP_LSHIFT_RT32,
+ ASTAT_OP_MIN_MAX,
+ ASTAT_OP_MIN_MAX_VECTOR,
+ ASTAT_OP_NEGATE,
+ ASTAT_OP_SUB16,
+ ASTAT_OP_SUB32,
+ ASTAT_OP_VECTOR_ADD_ADD, /* +|+ */
+ ASTAT_OP_VECTOR_ADD_SUB, /* +|- */
+ ASTAT_OP_VECTOR_SUB_SUB, /* -|- */
+ ASTAT_OP_VECTOR_SUB_ADD, /* -|+ */
+};
+
+typedef void (*hwloop_callback)(struct DisasContext *dc, int loop);
+
+typedef struct DisasContext {
+ CPUArchState *env;
+ struct TranslationBlock *tb;
+ /* The current PC we're decoding (could be middle of parallel insn) */
+ target_ulong pc;
+ /* Length of current insn (2/4/8) */
+ target_ulong insn_len;
+
+ /* For delayed ASTAT handling */
+ enum astat_ops astat_op;
+
+ /* For hardware loop processing */
+ hwloop_callback hwloop_callback;
+ void *hwloop_data;
+
+ /* Was a DISALGNEXCPT used in this parallel insn ? */
+ int disalgnexcpt;
+
+ int is_jmp;
+ int mem_idx;
+} DisasContext;
+
+void do_interrupt(CPUArchState *env);
+CPUArchState *cpu_init(const char *cpu_model);
+int cpu_exec(CPUArchState *s);
+int cpu_bfin_signal_handler(int host_signum, void *pinfo, void *puc);
+
+extern const char * const greg_names[];
+extern const char *get_allreg_name(int grp, int reg);
+
+#define MMU_KERNEL_IDX 0
+#define MMU_USER_IDX 1
+
+int cpu_bfin_handle_mmu_fault(CPUArchState *env, target_ulong address, int rw,
+ int mmu_idx);
+#define cpu_handle_mmu_fault cpu_bfin_handle_mmu_fault
+
+#if defined(CONFIG_USER_ONLY)
+static inline void cpu_clone_regs(CPUArchState *env, target_ulong newsp)
+{
+ if (newsp)
+ env->spreg = newsp;
+}
+#endif
+
+#include "exec/cpu-all.h"
+#include "cpu-qom.h"
+
+static inline bool cpu_has_work(CPUState *cpu)
+{
+ return (cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
+}
+
+#include "exec/exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUArchState *env, TranslationBlock *tb)
+{
+ env->pc = tb->pc;
+}
+
+static inline target_ulong cpu_get_pc(CPUArchState *env)
+{
+ return env->pc;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUArchState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = cpu_get_pc(env);
+ *cs_base = 0;
+ *flags = env->astat[ASTAT_RND_MOD];
+}
+
+#endif
diff --git a/target-bfin/helper.c b/target-bfin/helper.c
new file mode 100644
index 0000000..79a15cf
--- /dev/null
+++ b/target-bfin/helper.c
@@ -0,0 +1,37 @@
+/*
+ * Blackfin helpers
+ *
+ * Copyright 2007-2013 Mike Frysinger
+ * Copyright 2007-2011 Analog Devices, Inc.
+ *
+ * Licensed under the Lesser GPL 2 or later.
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <assert.h>
+
+#include "config.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "qemu/host-utils.h"
+
+#if defined(CONFIG_USER_ONLY)
+
+void do_interrupt(CPUArchState *env)
+{
+ env->exception_index = -1;
+}
+
+int cpu_handle_mmu_fault(CPUArchState *env, target_ulong address, int rw,
+ int mmu_idx)
+{
+ env->exception_index = EXCP_DCPLB_VIOLATE;
+ return 1;
+}
+
+#endif
diff --git a/target-bfin/helper.h b/target-bfin/helper.h
new file mode 100644
index 0000000..9596721
--- /dev/null
+++ b/target-bfin/helper.h
@@ -0,0 +1,23 @@
+#include "exec/def-helper.h"
+
+DEF_HELPER_3(raise_exception, void, env, i32, i32)
+DEF_HELPER_5(memalign, void, env, i32, i32, i32, i32)
+
+DEF_HELPER_4(dbga_l, void, env, i32, i32, i32)
+DEF_HELPER_4(dbga_h, void, env, i32, i32, i32)
+DEF_HELPER_FLAGS_1(outc, TCG_CALL_NO_RWG, void, i32)
+DEF_HELPER_FLAGS_3(dbg, TCG_CALL_NO_RWG, void, i32, i32, i32)
+DEF_HELPER_FLAGS_2(dbg_areg, TCG_CALL_NO_RWG, void, i64, i32)
+
+DEF_HELPER_1(astat_load, i32, env)
+DEF_HELPER_2(astat_store, void, env, i32)
+
+DEF_HELPER_FLAGS_1(ones, TCG_CALL_NO_RWG_SE, i32, i32)
+DEF_HELPER_FLAGS_2(signbits, TCG_CALL_NO_RWG_SE, i32, i32, i32)
+DEF_HELPER_FLAGS_2(signbits_64, TCG_CALL_NO_RWG_SE, i32, i64, i32)
+
+DEF_HELPER_FLAGS_4(dagadd, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32)
+DEF_HELPER_FLAGS_4(dagsub, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32)
+DEF_HELPER_FLAGS_2(add_brev, TCG_CALL_NO_RWG_SE, i32, i32, i32)
+
+#include "exec/def-helper.h"
diff --git a/target-bfin/linux-fixed-code.h b/target-bfin/linux-fixed-code.h
new file mode 100644
index 0000000..a6dddc4
--- /dev/null
+++ b/target-bfin/linux-fixed-code.h
@@ -0,0 +1,23 @@
+/* DO NOT EDIT: Autogenerated. */
+/* Fixed code region of Linux userspace starting at 0x400. Last produced
+ from Linux-2.6.37 (not that the fixed code region changes often). */
+static const unsigned char bfin_linux_fixed_code[] = {
+0x28, 0xe1, 0xad, 0x00, 0xa0, 0x00, 0x00, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x91, 0x01, 0x93, 0x10, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x91, 0x08, 0x08, 0x02, 0x10, 0x02, 0x93,
+0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x91, 0x01, 0x50, 0x00, 0x93, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x91, 0x01, 0x52, 0x00, 0x93, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x91, 0x01, 0x56, 0x00, 0x93, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x91, 0x01, 0x54, 0x00, 0x93, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x91, 0x01, 0x58, 0x00, 0x93, 0x10, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/target-bfin/op_helper.c b/target-bfin/op_helper.c
new file mode 100644
index 0000000..c905760
--- /dev/null
+++ b/target-bfin/op_helper.c
@@ -0,0 +1,229 @@
+/*
+ * Blackfin helpers
+ *
+ * Copyright 2007-2013 Mike Frysinger
+ * Copyright 2007-2011 Analog Devices, Inc.
+ *
+ * Licensed under the Lesser GPL 2 or later.
+ */
+
+#include "cpu.h"
+#include "helper.h"
+
+void HELPER(raise_exception)(CPUArchState *env, uint32_t excp, uint32_t pc)
+{
+ env->exception_index = excp;
+ if (pc != -1)
+ env->pc = pc;
+ cpu_loop_exit(env);
+}
+
+void HELPER(memalign)(CPUArchState *env, uint32_t excp, uint32_t pc,
+ uint32_t addr, uint32_t len)
+{
+ if ((addr & (len - 1)) == 0)
+ return;
+
+ HELPER(raise_exception)(env, excp, pc);
+}
+
+void HELPER(dbga_l)(CPUArchState *env, uint32_t pc, uint32_t actual,
+ uint32_t expected)
+{
+ if ((actual & 0xffff) != expected)
+ HELPER(raise_exception)(env, EXCP_DBGA, pc);
+}
+
+void HELPER(dbga_h)(CPUArchState *env, uint32_t pc, uint32_t actual,
+ uint32_t expected)
+{
+ if ((actual >> 16) != expected)
+ HELPER(raise_exception)(env, EXCP_DBGA, pc);
+}
+
+void HELPER(outc)(uint32_t ch)
+{
+ putc(ch, stdout);
+ if (ch == '\n')
+ fflush(stdout);
+}
+
+void HELPER(dbg)(uint32_t val, uint32_t grp, uint32_t reg)
+{
+ printf("DBG : %s = 0x%08x\n", get_allreg_name(grp, reg), val);
+}
+
+void HELPER(dbg_areg)(uint64_t val, uint32_t areg)
+{
+ printf("DBG : A%u = 0x%010"PRIx64"\n", areg, (val << 24) >> 24);
+}
+
+uint32_t HELPER(astat_load)(CPUArchState *env)
+{
+ return bfin_astat_read(env);
+}
+
+void HELPER(astat_store)(CPUArchState *env, uint32_t astat)
+{
+ bfin_astat_write(env, astat);
+}
+
+/* Count the number of bits set to 1 in the 32bit value */
+uint32_t HELPER(ones)(uint32_t val)
+{
+ uint32_t i;
+ uint32_t ret;
+
+ ret = 0;
+ for (i = 0; i < 32; ++i)
+ ret += !!(val & (1 << i));
+
+ return ret;
+}
+
+/* Count number of leading bits that match the sign bit */
+uint32_t HELPER(signbits)(uint32_t val, uint32_t size)
+{
+ uint32_t mask = 1 << (size - 1);
+ uint32_t bit = val & mask;
+ uint32_t count = 0;
+
+ for (;;) {
+ mask >>= 1;
+ bit >>= 1;
+ if (mask == 0)
+ break;
+ if ((val & mask) != bit)
+ break;
+ ++count;
+ }
+
+ return count;
+}
+
+/* Count number of leading bits that match the sign bit */
+uint32_t HELPER(signbits_64)(uint64_t val, uint32_t size)
+{
+ uint64_t mask = (uint64_t)1 << (size - 1);
+ uint64_t bit = val & mask;
+ uint32_t count = 0;
+
+ for (;;) {
+ mask >>= 1;
+ bit >>= 1;
+ if (mask == 0)
+ break;
+ if ((val & mask) != bit)
+ break;
+ ++count;
+ }
+
+ if (size == 40)
+ count -= 8;
+
+ return count;
+}
+
+/* This is a bit crazy, but we want to simulate the hardware behavior exactly
+ rather than worry about the circular buffers being used correctly. Which
+ isn't to say there isn't room for improvement here, just that we want to
+ be conservative. See also dagsub(). */
+uint32_t HELPER(dagadd)(uint32_t I, uint32_t L, uint32_t B, uint32_t M)
+{
+ uint64_t i = I;
+ uint64_t l = L;
+ uint64_t b = B;
+ uint64_t m = M;
+
+ uint64_t LB, IM, IML;
+ uint32_t im32, iml32, lb32, res;
+ uint64_t msb, car;
+
+ msb = (uint64_t)1 << 31;
+ car = (uint64_t)1 << 32;
+
+ IM = i + m;
+ im32 = IM;
+ LB = l + b;
+ lb32 = LB;
+
+ if ((int32_t)M < 0) {
+ IML = i + m + l;
+ iml32 = IML;
+ if ((i & msb) || (IM & car))
+ res = (im32 < b) ? iml32 : im32;
+ else
+ res = (im32 < b) ? im32 : iml32;
+ } else {
+ IML = i + m - l;
+ iml32 = IML;
+ if ((IM & car) == (LB & car))
+ res = (im32 < lb32) ? im32 : iml32;
+ else
+ res = (im32 < lb32) ? iml32 : im32;
+ }
+
+ return res;
+}
+
+/* See dagadd() notes above. */
+uint32_t HELPER(dagsub)(uint32_t I, uint32_t L, uint32_t B, uint32_t M)
+{
+ uint64_t i = I;
+ uint64_t l = L;
+ uint64_t b = B;
+ uint64_t m = M;
+
+ uint64_t mbar = (uint32_t)(~m + 1);
+ uint64_t LB, IM, IML;
+ uint32_t b32, im32, iml32, lb32, res;
+ uint64_t msb, car;
+
+ msb = (uint64_t)1 << 31;
+ car = (uint64_t)1 << 32;
+
+ IM = i + mbar;
+ im32 = IM;
+ LB = l + b;
+ lb32 = LB;
+
+ if ((int32_t)M < 0) {
+ IML = i + mbar - l;
+ iml32 = IML;
+ if (!!((i & msb) && (IM & car)) == !!(LB & car))
+ res = (im32 < lb32) ? im32 : iml32;
+ else
+ res = (im32 < lb32) ? iml32 : im32;
+ } else {
+ IML = i + mbar + l;
+ iml32 = IML;
+ b32 = b;
+ if (M == 0 || IM & car)
+ res = (im32 < b32) ? iml32 : im32;
+ else
+ res = (im32 < b32) ? im32 : iml32;
+ }
+
+ return res;
+}
+
+uint32_t HELPER(add_brev)(uint32_t addend1, uint32_t addend2)
+{
+ uint32_t mask, b, r;
+ int i, cy;
+
+ mask = 0x80000000;
+ r = 0;
+ cy = 0;
+
+ for (i = 31; i >= 0; --i) {
+ b = ((addend1 & mask) >> i) + ((addend2 & mask) >> i);
+ b += cy;
+ cy = b >> 1;
+ b &= 1;
+ r |= b << i;
+ mask >>= 1;
+ }
+
+ return r;
+}
diff --git a/target-bfin/translate.c b/target-bfin/translate.c
new file mode 100644
index 0000000..a619f66
--- /dev/null
+++ b/target-bfin/translate.c
@@ -0,0 +1,1347 @@
+/*
+ * Blackfin translation
+ *
+ * Copyright 2007-2013 Mike Frysinger
+ * Copyright 2007-2011 Analog Devices, Inc.
+ *
+ * Licensed under the Lesser GPL 2 or later.
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "cpu.h"
+#include "disas/disas.h"
+#include "exec/exec-all.h"
+#include "tcg-op.h"
+#include "qemu-common.h"
+#include "opcode/bfin.h"
+
+#include "helper.h"
+#define GEN_HELPER 1
+#include "helper.h"
+
+/* We're making a call (which means we need to update RTS) */
+#define DISAS_CALL 0xad0
+
+static TCGv_ptr cpu_env;
+static TCGv cpu_dreg[8];
+static TCGv cpu_preg[8];
+#define cpu_spreg cpu_preg[6]
+#define cpu_fpreg cpu_preg[7]
+static TCGv cpu_ireg[4];
+static TCGv cpu_mreg[4];
+static TCGv cpu_breg[4];
+static TCGv cpu_lreg[4];
+static TCGv_i64 cpu_areg[2];
+static TCGv cpu_rets;
+static TCGv cpu_lcreg[2], cpu_ltreg[2], cpu_lbreg[2];
+static TCGv cpu_cycles[2];
+static TCGv cpu_uspreg;
+static TCGv cpu_seqstat;
+static TCGv cpu_syscfg;
+static TCGv cpu_reti;
+static TCGv cpu_retx;
+static TCGv cpu_retn;
+static TCGv cpu_rete;
+static TCGv cpu_emudat;
+static TCGv cpu_pc;
+static TCGv cpu_cc;
+static TCGv /*cpu_astat_op,*/ cpu_astat_arg[3];
+
+#include "exec/gen-icount.h"
+
+static inline void
+bfin_tcg_new_set3(TCGv *tcgv, unsigned int cnt, unsigned int offbase,
+ const char * const *names)
+{
+ unsigned int i;
+ for (i = 0; i < cnt; ++i)
+ tcgv[i] = tcg_global_mem_new(TCG_AREG0, offbase + (i * 4), names[i]);
+}
+#define bfin_tcg_new_set2(tcgv, cnt, reg, name_idx) \
+ bfin_tcg_new_set3(tcgv, cnt, offsetof(CPUArchState, reg), &greg_names[name_idx])
+#define bfin_tcg_new_set(reg, name_idx) \
+ bfin_tcg_new_set2(cpu_##reg, ARRAY_SIZE(cpu_##reg), reg, name_idx)
+#define bfin_tcg_new(reg, name_idx) \
+ bfin_tcg_new_set2(&cpu_##reg, 1, reg, name_idx)
+
+CPUArchState *cpu_init(const char *cpu_model)
+{
+ BfinCPU *cpu;
+ CPUArchState *env;
+ static int tcg_initialized = 0;
+
+ cpu = BFIN_CPU(object_new(TYPE_BFIN_CPU));
+ env = &cpu->env;
+
+ cpu_reset(CPU(cpu));
+ qemu_init_vcpu(env);
+
+ if (tcg_initialized)
+ return env;
+
+ tcg_initialized = 1;
+
+#define GEN_HELPER 2
+#include "helper.h"
+
+ cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+
+ cpu_pc = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUArchState, pc), "PC");
+ cpu_cc = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUArchState, astat[ASTAT_CC]), "CC");
+
+ /*cpu_astat_op = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUArchState, astat_op), "astat_op");*/
+ cpu_astat_arg[0] = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUArchState, astat_arg[0]), "astat_arg[0]");
+ cpu_astat_arg[1] = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUArchState, astat_arg[1]), "astat_arg[1]");
+ cpu_astat_arg[2] = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUArchState, astat_arg[2]), "astat_arg[2]");
+
+ cpu_areg[0] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUArchState, areg[0]), "A0");
+ cpu_areg[1] = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUArchState, areg[1]), "A1");
+
+ bfin_tcg_new_set(dreg, 0);
+ bfin_tcg_new_set(preg, 8);
+ bfin_tcg_new_set(ireg, 16);
+ bfin_tcg_new_set(mreg, 20);
+ bfin_tcg_new_set(breg, 24);
+ bfin_tcg_new_set(lreg, 28);
+ bfin_tcg_new(rets, 39);
+ bfin_tcg_new(lcreg[0], 48);
+ bfin_tcg_new(ltreg[0], 49);
+ bfin_tcg_new(lbreg[0], 50);
+ bfin_tcg_new(lcreg[1], 51);
+ bfin_tcg_new(ltreg[1], 52);
+ bfin_tcg_new(lbreg[1], 53);
+ bfin_tcg_new_set(cycles, 54);
+ bfin_tcg_new(uspreg, 56);
+ bfin_tcg_new(seqstat, 57);
+ bfin_tcg_new(syscfg, 58);
+ bfin_tcg_new(reti, 59);
+ bfin_tcg_new(retx, 60);
+ bfin_tcg_new(retn, 61);
+ bfin_tcg_new(rete, 62);
+ bfin_tcg_new(emudat, 63);
+
+ return env;
+}
+
+#define _astat_printf(bit) cpu_fprintf(f, "%s" #bit " ", (env->astat[ASTAT_##bit] ? "" : "~"))
+void cpu_dump_state(CPUArchState *env, FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+ int flags)
+{
+ cpu_fprintf(f, " SYSCFG: %04lx SEQSTAT: %08x\n",
+ env->syscfg, env->seqstat);
+ cpu_fprintf(f, "RETE: %08x RETN: %08x RETX: %08x\n",
+ env->rete, env->retn, env->retx);
+ cpu_fprintf(f, "RETI: %08x RETS: %08x PC : %08x\n",
+ env->reti, env->rets, env->pc);
+ cpu_fprintf(f, " R0 : %08x R4 : %08x P0 : %08x P4 : %08x\n",
+ env->dreg[0], env->dreg[4], env->preg[0], env->preg[4]);
+ cpu_fprintf(f, " R1 : %08x R5 : %08x P1 : %08x P5 : %08x\n",
+ env->dreg[1], env->dreg[5], env->preg[1], env->preg[5]);
+ cpu_fprintf(f, " R2 : %08x R6 : %08x P2 : %08x SP : %08x\n",
+ env->dreg[2], env->dreg[6], env->preg[2], env->spreg);
+ cpu_fprintf(f, " R3 : %08x R7 : %08x P3 : %08x FP : %08x\n",
+ env->dreg[3], env->dreg[7], env->preg[3], env->fpreg);
+ cpu_fprintf(f, " LB0: %08x LT0: %08x LC0: %08x\n",
+ env->lbreg[0], env->ltreg[0], env->lcreg[0]);
+ cpu_fprintf(f, " LB1: %08x LT1: %08x LC1: %08x\n",
+ env->lbreg[1], env->ltreg[1], env->lcreg[1]);
+ cpu_fprintf(f, " B0 : %08x L0 : %08x M0 : %08x I0 : %08x\n",
+ env->breg[0], env->lreg[0], env->mreg[0], env->ireg[0]);
+ cpu_fprintf(f, " B1 : %08x L1 : %08x M1 : %08x I1 : %08x\n",
+ env->breg[1], env->lreg[1], env->mreg[1], env->ireg[1]);
+ cpu_fprintf(f, " B2 : %08x L2 : %08x M2 : %08x I2 : %08x\n",
+ env->breg[2], env->lreg[2], env->mreg[2], env->ireg[2]);
+ cpu_fprintf(f, " B3 : %08x L3 : %08x M3 : %08x I3 : %08x\n",
+ env->breg[3], env->lreg[3], env->mreg[3], env->ireg[3]);
+ cpu_fprintf(f, " A0: %010lx A1: %010lx\n",
+ env->areg[0] & 0xffffffffff, env->areg[1] & 0xffffffffff);
+ cpu_fprintf(f, " USP: %08x ASTAT: %08x CC : %08x\n",
+ env->uspreg, bfin_astat_read(env), env->astat[ASTAT_CC]);
+ cpu_fprintf(f, "ASTAT BITS: ");
+ _astat_printf(VS);
+ _astat_printf(V);
+ _astat_printf(AV1S);
+ _astat_printf(AV1);
+ _astat_printf(AV0S);
+ _astat_printf(AV0);
+ _astat_printf(AC1);
+ _astat_printf(AC0);
+ _astat_printf(AQ);
+ _astat_printf(CC);
+ _astat_printf(V_COPY);
+ _astat_printf(AC0_COPY);
+ _astat_printf(AN);
+ _astat_printf(AZ);
+ cpu_fprintf(f, "\nASTAT CACHE: OP: %02u ARG: %08x %08x %08x\n",
+ env->astat_op, env->astat_arg[0], env->astat_arg[1], env->astat_arg[2]);
+ cpu_fprintf(f, " CYCLES: %08x %08x\n",
+ env->cycles[0], env->cycles[1]);
+
+/*
+ iw = ldq_code(env->pc);
+ if ((iw & 0xc000) != 0xc000)
+ len = 2;
+ else if ((iw & BIT_MULTI_INS) && (iw & 0xe800) != 0xe800)
+ len = 8;
+ else
+ len = 4;
+ log_target_disas(env->pc, len, 0);
+*/
+}
+
+static void gen_astat_update(DisasContext *, bool);
+
+static void gen_goto_tb(DisasContext *dc, int tb_num, TCGv dest)
+{
+/*
+ TranslationBlock *tb;
+ tb = dc->tb;
+
+ if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+ tcg_gen_goto_tb(tb_num);
+ tcg_gen_mov_tl(cpu_pc, dest);
+ tcg_gen_exit_tb((long)tb + tb_num);
+ } else */{
+ gen_astat_update(dc, false);
+ tcg_gen_mov_tl(cpu_pc, dest);
+ tcg_gen_exit_tb(0);
+ }
+}
+
+static void gen_gotoi_tb(DisasContext *dc, int tb_num, target_ulong dest)
+{
+ TCGv tmp = tcg_temp_local_new();
+ tcg_gen_movi_tl(tmp, dest);
+ gen_goto_tb(dc, tb_num, tmp);
+ tcg_temp_free(tmp);
+}
+
+static void cec_exception(DisasContext *dc, int excp)
+{
+ TCGv tmp = tcg_const_tl(excp);
+ TCGv pc = tcg_const_tl(dc->pc);
+ gen_helper_raise_exception(cpu_env, tmp, pc);
+ tcg_temp_free(tmp);
+ dc->is_jmp = DISAS_UPDATE;
+}
+
+static void cec_require_supervisor(DisasContext *dc)
+{
+#ifdef CONFIG_LINUX_USER
+ cec_exception(dc, EXCP_ILL_SUPV);
+#else
+# error todo
+#endif
+}
+
+static void gen_align_check(DisasContext *dc, TCGv addr, uint32_t len, bool inst)
+{
+ TCGv excp, pc, tmp;
+
+ /* XXX: This should be made into a runtime option. It adds likes
+ 10% overhead to memory intensive apps (like mp3 decoding). */
+ if (1) {
+ return;
+ }
+
+ excp = tcg_const_tl(inst ? EXCP_MISALIG_INST : EXCP_DATA_MISALGIN);
+ pc = tcg_const_tl(dc->pc);
+ tmp = tcg_const_tl(len);
+ gen_helper_memalign(cpu_env, excp, pc, addr, tmp);
+ tcg_temp_free(tmp);
+ tcg_temp_free(pc);
+ tcg_temp_free(excp);
+}
+
+static void gen_aligned_qemu_ld16u(DisasContext *dc, TCGv ret, TCGv addr)
+{
+ gen_align_check(dc, addr, 2, false);
+ tcg_gen_qemu_ld16u(ret, addr, dc->mem_idx);
+}
+
+static void gen_aligned_qemu_ld16s(DisasContext *dc, TCGv ret, TCGv addr)
+{
+ gen_align_check(dc, addr, 2, false);
+ tcg_gen_qemu_ld16s(ret, addr, dc->mem_idx);
+}
+
+static void gen_aligned_qemu_ld32u(DisasContext *dc, TCGv ret, TCGv addr)
+{
+ gen_align_check(dc, addr, 4, false);
+ tcg_gen_qemu_ld32u(ret, addr, dc->mem_idx);
+}
+
+static void gen_aligned_qemu_st16(DisasContext *dc, TCGv val, TCGv addr)
+{
+ gen_align_check(dc, addr, 2, false);
+ tcg_gen_qemu_st16(val, addr, dc->mem_idx);
+}
+
+static void gen_aligned_qemu_st32(DisasContext *dc, TCGv val, TCGv addr)
+{
+ gen_align_check(dc, addr, 4, false);
+ tcg_gen_qemu_st32(val, addr, dc->mem_idx);
+}
+
+/*
+ * If a LB reg is written, we need to invalidate the two translation
+ * blocks that could be affected -- the TB's referenced by the old LB
+ * could have LC/LT handling which we no longer want, and the new LB
+ * is probably missing LC/LT handling which we want. In both cases,
+ * we need to regenerate the block.
+ */
+static void gen_maybe_lb_exit_tb(DisasContext *dc, TCGv reg)
+{
+ if (!TCGV_EQUAL(reg, cpu_lbreg[0]) && !TCGV_EQUAL(reg, cpu_lbreg[1]))
+ return;
+
+ /* tb_invalidate_phys_page_range */
+ dc->is_jmp = DISAS_UPDATE;
+ /* XXX: Not entirely correct, but very few things load
+ * directly into LB ... */
+ gen_gotoi_tb(dc, 0, dc->pc + dc->insn_len);
+}
+
+static void gen_hwloop_default(DisasContext *dc, int loop)
+{
+ if (loop != -1)
+ gen_goto_tb(dc, 0, cpu_ltreg[loop]);
+}
+
+static void _gen_hwloop_call(DisasContext *dc, int loop)
+{
+ if (dc->is_jmp != DISAS_CALL)
+ return;
+
+ if (loop == -1)
+ tcg_gen_movi_tl(cpu_rets, dc->pc + dc->insn_len);
+ else
+ tcg_gen_mov_tl(cpu_rets, cpu_ltreg[loop]);
+}
+
+static void gen_hwloop_br_pcrel_cc(DisasContext *dc, int loop)
+{
+ int l;
+ int pcrel = (unsigned long)dc->hwloop_data;
+ int T = pcrel & 1;
+ pcrel &= ~1;
+
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc, T, l);
+ gen_gotoi_tb(dc, 0, dc->pc + pcrel);
+ gen_set_label(l);
+ if (loop == -1)
+ dc->hwloop_callback = gen_hwloop_default;
+ else
+ gen_hwloop_default(dc, loop);
+}
+
+static void gen_hwloop_br_pcrel(DisasContext *dc, int loop)
+{
+ TCGv *reg = dc->hwloop_data;
+ _gen_hwloop_call(dc, loop);
+ tcg_gen_addi_tl(cpu_pc, *reg, dc->pc);
+ gen_goto_tb(dc, 0, cpu_pc);
+}
+
+static void gen_hwloop_br_pcrel_imm(DisasContext *dc, int loop)
+{
+ int pcrel = (unsigned long)dc->hwloop_data;
+ TCGv tmp;
+
+ _gen_hwloop_call(dc, loop);
+ tmp = tcg_const_tl(pcrel);
+ tcg_gen_addi_tl(cpu_pc, tmp, dc->pc);
+ tcg_temp_free(tmp);
+ gen_goto_tb(dc, 0, cpu_pc);
+}
+
+static void gen_hwloop_br_direct(DisasContext *dc, int loop)
+{
+ TCGv *reg = dc->hwloop_data;
+ _gen_hwloop_call(dc, loop);
+ gen_goto_tb(dc, 0, *reg);
+}
+
+static void _gen_hwloop_check(DisasContext *dc, int loop, int l)
+{
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_lcreg[loop], 0, l);
+ tcg_gen_subi_tl(cpu_lcreg[loop], cpu_lcreg[loop], 1);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_lcreg[loop], 0, l);
+ dc->hwloop_callback(dc, loop);
+}
+
+static void gen_hwloop_check(DisasContext *dc)
+{
+ bool loop1, loop0;
+ int endl;
+
+ loop1 = (dc->pc == dc->env->lbreg[1]);
+ loop0 = (dc->pc == dc->env->lbreg[0]);
+
+ if (loop1 || loop0)
+ endl = gen_new_label();
+
+ if (loop1) {
+ int l;
+ if (loop0)
+ l = gen_new_label();
+ else
+ l = endl;
+
+ _gen_hwloop_check(dc, 1, l);
+
+ if (loop0) {
+ tcg_gen_br(endl);
+ gen_set_label(l);
+ }
+ }
+
+ if (loop0)
+ _gen_hwloop_check(dc, 0, endl);
+
+ if (loop1 || loop0)
+ gen_set_label(endl);
+
+ dc->hwloop_callback(dc, -1);
+}
+
+/* R#.L = reg; R#.H = reg; */
+/* XXX: This modifies the low source ... assumes it is a temp ... */
+/*
+static void gen_mov_l_h_tl(TCGv dst, TCGv srcl, TCGv srch)
+{
+ tcg_gen_shli_tl(dst, srch, 16);
+ tcg_gen_andi_tl(srcl, srcl, 0xffff);
+ tcg_gen_or_tl(dst, dst, srcl);
+}
+*/
+
+/* R#.L = reg */
+static void gen_mov_l_tl(TCGv dst, TCGv src)
+{
+ tcg_gen_andi_tl(dst, dst, 0xffff0000);
+ tcg_gen_andi_tl(src, src, 0xffff);
+ tcg_gen_or_tl(dst, dst, src);
+}
+
+/* R#.L = imm32 */
+/*
+static void gen_movi_l_tl(TCGv dst, uint32_t src)
+{
+ tcg_gen_andi_tl(dst, dst, 0xffff0000);
+ tcg_gen_ori_tl(dst, dst, src & 0xffff);
+}
+*/
+
+/* R#.H = reg */
+/* XXX: This modifies the source ... assumes it is a temp ... */
+static void gen_mov_h_tl(TCGv dst, TCGv src)
+{
+ tcg_gen_andi_tl(dst, dst, 0xffff);
+ tcg_gen_shli_tl(src, src, 16);
+ tcg_gen_or_tl(dst, dst, src);
+}
+
+/* R#.H = imm32 */
+/*
+static void gen_movi_h_tl(TCGv dst, uint32_t src)
+{
+ tcg_gen_andi_tl(dst, dst, 0xffff);
+ tcg_gen_ori_tl(dst, dst, src << 16);
+}
+*/
+
+static void gen_extNs_tl(TCGv dst, TCGv src, TCGv n)
+{
+ /* Shift the sign bit up, and then back down */
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_subfi_tl(tmp, 32, n);
+ tcg_gen_shl_tl(dst, src, tmp);
+ tcg_gen_sar_tl(dst, dst, tmp);
+ tcg_temp_free(tmp);
+}
+
+static void gen_extNsi_tl(TCGv dst, TCGv src, uint32_t n)
+{
+ /* Shift the sign bit up, and then back down */
+ tcg_gen_shli_tl(dst, src, 32 - n);
+ tcg_gen_sari_tl(dst, dst, 32 - n);
+}
+
+static void gen_extNsi_i64(TCGv_i64 dst, TCGv_i64 src, uint32_t n)
+{
+ /* Shift the sign bit up, and then back down */
+ tcg_gen_shli_i64(dst, src, 64 - n);
+ tcg_gen_sari_i64(dst, dst, 64 - n);
+}
+
+#if 0
+static void gen_extNu_tl(TCGv dst, TCGv src, TCGv n)
+{
+ /* Just mask off the higher bits */
+ tcg_gen_andi_tl(dst, src, ~((1 << n) - 1));
+}
+
+static void gen_extNui_tl(TCGv dst, TCGv src, uint32_t n)
+{
+ /* Just mask off the higher bits */
+ tcg_gen_andi_tl(dst, src, ~((1 << n) - 1));
+}
+#endif
+
+static void gen_signbitsi_tl(TCGv dst, TCGv src, uint32_t size)
+{
+ TCGv tmp_size = tcg_const_tl(size);
+ gen_helper_signbits(dst, src, tmp_size);
+ tcg_temp_free(tmp_size);
+}
+
+static void gen_signbitsi_i64_i32(TCGv dst, TCGv_i64 src, uint32_t size)
+{
+ TCGv tmp_size = tcg_const_tl(size);
+ gen_helper_signbits_64(dst, src, tmp_size);
+ tcg_temp_free(tmp_size);
+}
+
+static void gen_abs_tl(TCGv ret, TCGv arg)
+{
+ int l = gen_new_label();
+ tcg_gen_mov_tl(ret, arg);
+ tcg_gen_brcondi_tl(TCG_COND_GE, arg, 0, l);
+ tcg_gen_neg_tl(ret, ret);
+ gen_set_label(l);
+}
+
+static void gen_abs_i64(TCGv_i64 ret, TCGv_i64 arg)
+{
+ int l = gen_new_label();
+ tcg_gen_mov_i64(ret, arg);
+ tcg_gen_brcondi_i64(TCG_COND_GE, arg, 0, l);
+ tcg_gen_neg_i64(ret, ret);
+ gen_set_label(l);
+}
+
+/* Common tail code for DIVQ/DIVS insns */
+static void _gen_divqs(TCGv pquo, TCGv r, TCGv aq, TCGv div)
+{
+ /*
+ * pquo <<= 1
+ * pquo |= aq
+ * pquo = (pquo & 0x1FFFF) | (r << 17)
+ */
+ tcg_gen_shli_tl(pquo, pquo, 1);
+ tcg_gen_or_tl(pquo, pquo, aq);
+ tcg_gen_andi_tl(pquo, pquo, 0x1FFFF);
+ tcg_gen_shli_tl(r, r, 17);
+ tcg_gen_or_tl(pquo, pquo, r);
+
+ tcg_temp_free(r);
+ tcg_temp_free(aq);
+ tcg_temp_free(div);
+}
+
+/* Common AQ ASTAT bit management for DIVQ/DIVS insns */
+static void _gen_divqs_st_aq(TCGv r, TCGv aq, TCGv div)
+{
+ /* aq = (r ^ div) >> 15 */
+ tcg_gen_xor_tl(aq, r, div);
+ tcg_gen_shri_tl(aq, aq, 15);
+ tcg_gen_andi_tl(aq, aq, 1);
+ tcg_gen_st_tl(aq, cpu_env, offsetof(CPUArchState, astat[ASTAT_AQ]));
+}
+
+/* DIVQ ( Dreg, Dreg ) ;
+ * Based on AQ status bit, either add or subtract the divisor from
+ * the dividend. Then set the AQ status bit based on the MSBs of the
+ * 32-bit dividend and the 16-bit divisor. Left shift the dividend one
+ * bit. Copy the logical inverse of AQ into the dividend LSB.
+ */
+static void gen_divq(TCGv pquo, TCGv src)
+{
+ int l;
+ TCGv af, r, aq, div;
+
+ /* div = R#.L */
+ div = tcg_temp_local_new();
+ tcg_gen_ext16u_tl(div, src);
+
+ /* af = pquo >> 16 */
+ af = tcg_temp_local_new();
+ tcg_gen_shri_tl(af, pquo, 16);
+
+ /*
+ * we take this:
+ * if (ASTAT_AQ)
+ * r = div + af;
+ * else
+ * r = af - div;
+ *
+ * and turn it into:
+ * r = div;
+ * if (aq == 0)
+ * r = -r;
+ * r += af;
+ */
+ aq = tcg_temp_local_new();
+ tcg_gen_ld_tl(aq, cpu_env, offsetof(CPUArchState, astat[ASTAT_AQ]));
+
+ l = gen_new_label();
+ r = tcg_temp_local_new();
+ tcg_gen_mov_tl(r, div);
+ tcg_gen_brcondi_tl(TCG_COND_NE, aq, 0, l);
+ tcg_gen_neg_tl(r, r);
+ gen_set_label(l);
+ tcg_gen_add_tl(r, r, af);
+
+ tcg_temp_free(af);
+
+ _gen_divqs_st_aq(r, aq, div);
+
+ /* aq = !aq */
+ tcg_gen_xori_tl(aq, aq, 1);
+
+ _gen_divqs(pquo, r, aq, div);
+}
+
+/* DIVS ( Dreg, Dreg ) ;
+ * Initialize for DIVQ. Set the AQ status bit based on the signs of
+ * the 32-bit dividend and the 16-bit divisor. Left shift the dividend
+ * one bit. Copy AQ into the dividend LSB.
+ */
+static void gen_divs(TCGv pquo, TCGv src)
+{
+ TCGv r, aq, div;
+
+ /* div = R#.L */
+ div = tcg_temp_local_new();
+ tcg_gen_ext16u_tl(div, src);
+
+ /* r = pquo >> 16 */
+ r = tcg_temp_local_new();
+ tcg_gen_shri_tl(r, pquo, 16);
+
+ aq = tcg_temp_local_new();
+
+ _gen_divqs_st_aq(r, aq, div);
+
+ _gen_divqs(pquo, r, aq, div);
+}
+
+/* Reg = ROT reg BY reg/imm
+ * The Blackfin rotate is not like the TCG rotate. It shifts through the
+ * CC bit too giving it 33 bits to play with. So we have to reduce things
+ * to shifts ourself.
+ */
+static void gen_rot_tl(TCGv dst, TCGv src, TCGv orig_shift)
+{
+ uint32_t nbits = 32;
+ TCGv shift, ret, tmp, tmp_shift;
+ int l, endl;
+
+ /* shift = CLAMP (shift, -nbits, nbits); */
+
+ endl = gen_new_label();
+
+ /* if (shift == 0) */
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, orig_shift, 0, l);
+ tcg_gen_mov_tl(dst, src);
+ tcg_gen_br(endl);
+ gen_set_label(l);
+
+ /* Reduce everything to rotate left */
+ shift = tcg_temp_local_new();
+ tcg_gen_mov_tl(shift, orig_shift);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_GE, shift, 0, l);
+ tcg_gen_addi_tl(shift, shift, nbits + 1);
+ gen_set_label(l);
+
+ if (TCGV_EQUAL(dst, src))
+ ret = tcg_temp_local_new();
+ else
+ ret = dst;
+
+ /* ret = shift == nbits ? 0 : val << shift; */
+ tcg_gen_movi_tl(ret, 0);
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_EQ, shift, nbits, l);
+ tcg_gen_shl_tl(ret, src, shift);
+ gen_set_label(l);
+
+ /* ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift); */
+ l = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_EQ, shift, 1, l);
+ tmp = tcg_temp_new();
+ tmp_shift = tcg_temp_new();
+ tcg_gen_subfi_tl(tmp_shift, nbits + 1, shift);
+ tcg_gen_shr_tl(tmp, src, tmp_shift);
+ tcg_gen_or_tl(ret, ret, tmp);
+ tcg_temp_free(tmp_shift);
+ tcg_temp_free(tmp);
+ gen_set_label(l);
+
+ /* Then add in and output feedback via the CC register */
+ tcg_gen_subi_tl(shift, shift, 1);
+ tcg_gen_shl_tl(cpu_cc, cpu_cc, shift);
+ tcg_gen_or_tl(ret, ret, cpu_cc);
+ tcg_gen_subfi_tl(shift, nbits - 1, shift);
+ tcg_gen_shr_tl(cpu_cc, src, shift);
+ tcg_gen_andi_tl(cpu_cc, cpu_cc, 1);
+
+ if (TCGV_EQUAL(dst, src)) {
+ tcg_gen_mov_tl(dst, ret);
+ tcg_temp_free(ret);
+ }
+
+ tcg_temp_free(shift);
+ gen_set_label(endl);
+}
+
+static void gen_roti_tl(TCGv dst, TCGv src, int32_t shift)
+{
+ uint32_t nbits = 32;
+ TCGv ret;
+
+ /* shift = CLAMP (shift, -nbits, nbits); */
+
+ if (shift == 0) {
+ tcg_gen_mov_tl(dst, src);
+ return;
+ }
+
+ /* Reduce everything to rotate left */
+ if (shift < 0)
+ shift += nbits + 1;
+
+ if (TCGV_EQUAL(dst, src))
+ ret = tcg_temp_new();
+ else
+ ret = dst;
+
+ /* First rotate the main register */
+ if (shift == nbits)
+ tcg_gen_movi_tl(ret, 0);
+ else
+ tcg_gen_shli_tl(ret, src, shift);
+ if (shift != 1) {
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_shri_tl(tmp, src, (nbits + 1) - shift);
+ tcg_gen_or_tl(ret, ret, tmp);
+ tcg_temp_free(tmp);
+ }
+
+ /* Then add in and output feedback via the CC register */
+ tcg_gen_shli_tl(cpu_cc, cpu_cc, shift - 1);
+ tcg_gen_or_tl(ret, ret, cpu_cc);
+ tcg_gen_shri_tl(cpu_cc, src, nbits - shift);
+ tcg_gen_andi_tl(cpu_cc, cpu_cc, 1);
+
+ if (TCGV_EQUAL(dst, src)) {
+ tcg_gen_mov_tl(dst, ret);
+ tcg_temp_free(ret);
+ }
+}
+
+static void gen_rot_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 orig_shift)
+{
+ uint32_t nbits = 40;
+ TCGv_i64 shift, ret, tmp, tmp_shift, cc64;
+ int l, endl;
+
+ /* shift = CLAMP (shift, -nbits, nbits); */
+
+ endl = gen_new_label();
+
+ /* if (shift == 0) */
+ l = gen_new_label();
+ tcg_gen_brcondi_i64(TCG_COND_NE, orig_shift, 0, l);
+ tcg_gen_mov_i64(dst, src);
+ tcg_gen_br(endl);
+ gen_set_label(l);
+
+ /* Reduce everything to rotate left */
+ shift = tcg_temp_local_new_i64();
+ tcg_gen_mov_i64(shift, orig_shift);
+ l = gen_new_label();
+ tcg_gen_brcondi_i64(TCG_COND_GE, shift, 0, l);
+ tcg_gen_addi_i64(shift, shift, nbits + 1);
+ gen_set_label(l);
+
+ if (TCGV_EQUAL_I64(dst, src))
+ ret = tcg_temp_local_new_i64();
+ else
+ ret = dst;
+
+ /* ret = shift == nbits ? 0 : val << shift; */
+ tcg_gen_movi_i64(ret, 0);
+ l = gen_new_label();
+ tcg_gen_brcondi_i64(TCG_COND_EQ, shift, nbits, l);
+ tcg_gen_shl_i64(ret, src, shift);
+ gen_set_label(l);
+
+ /* ret |= shift == 1 ? 0 : val >> ((nbits + 1) - shift); */
+ l = gen_new_label();
+ tcg_gen_brcondi_i64(TCG_COND_EQ, shift, 1, l);
+ tmp = tcg_temp_new_i64();
+ tmp_shift = tcg_temp_new_i64();
+ tcg_gen_subfi_i64(tmp_shift, nbits + 1, shift);
+ tcg_gen_shr_i64(tmp, src, tmp_shift);
+ tcg_gen_or_i64(ret, ret, tmp);
+ tcg_temp_free_i64(tmp_shift);
+ tcg_temp_free_i64(tmp);
+ gen_set_label(l);
+
+ /* Then add in and output feedback via the CC register */
+ cc64 = tcg_temp_new_i64();
+ tcg_gen_ext_i32_i64(cc64, cpu_cc);
+ tcg_gen_subi_i64(shift, shift, 1);
+ tcg_gen_shl_i64(cc64, cc64, shift);
+ tcg_gen_or_i64(ret, ret, cc64);
+ tcg_gen_subfi_i64(shift, nbits - 1, shift);
+ tcg_gen_shr_i64(cc64, src, shift);
+ tcg_gen_andi_i64(cc64, cc64, 1);
+ tcg_gen_trunc_i64_i32(cpu_cc, cc64);
+ tcg_temp_free_i64(cc64);
+
+ if (TCGV_EQUAL_I64(dst, src)) {
+ tcg_gen_mov_i64(dst, ret);
+ tcg_temp_free_i64(ret);
+ }
+
+ tcg_temp_free_i64(shift);
+ gen_set_label(endl);
+}
+
+static void gen_roti_i64(TCGv_i64 dst, TCGv_i64 src, int32_t shift)
+{
+ uint32_t nbits = 40;
+ TCGv_i64 ret, cc64;
+
+ /* shift = CLAMP (shift, -nbits, nbits); */
+
+ if (shift == 0) {
+ tcg_gen_mov_i64(dst, src);
+ return;
+ }
+
+ /* Reduce everything to rotate left */
+ if (shift < 0)
+ shift += nbits + 1;
+
+ if (TCGV_EQUAL_I64(dst, src))
+ ret = tcg_temp_new_i64();
+ else
+ ret = dst;
+
+ /* First rotate the main register */
+ if (shift == nbits)
+ tcg_gen_movi_i64(ret, 0);
+ else
+ tcg_gen_shli_i64(ret, src, shift);
+ if (shift != 1) {
+ TCGv_i64 tmp = tcg_temp_new_i64();
+ tcg_gen_shri_i64(tmp, src, (nbits + 1) - shift);
+ tcg_gen_or_i64(ret, ret, tmp);
+ tcg_temp_free_i64(tmp);
+ }
+
+ /* Then add in and output feedback via the CC register */
+ cc64 = tcg_temp_new_i64();
+ tcg_gen_ext_i32_i64(cc64, cpu_cc);
+ tcg_gen_shli_i64(cc64, cc64, shift - 1);
+ tcg_gen_or_i64(ret, ret, cc64);
+ tcg_gen_shri_i64(cc64, src, nbits - shift);
+ tcg_gen_andi_i64(cc64, cc64, 1);
+ tcg_gen_trunc_i64_i32(cpu_cc, cc64);
+ tcg_temp_free_i64(cc64);
+
+ if (TCGV_EQUAL_I64(dst, src)) {
+ tcg_gen_mov_i64(dst, ret);
+ tcg_temp_free_i64(ret);
+ }
+}
+
+/* This is a bit crazy, but we want to simulate the hardware behavior exactly
+ rather than worry about the circular buffers being used correctly. Which
+ isn't to say there isn't room for improvement here, just that we want to
+ be conservative. See also dagsub(). */
+static void gen_dagadd(DisasContext *dc, int dagno, TCGv M)
+{
+ int l, endl;
+
+ /* Optimize for when circ buffers are not used */
+ l = gen_new_label();
+ endl = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, cpu_lreg[dagno], 0, l);
+ tcg_gen_add_tl(cpu_ireg[dagno], cpu_ireg[dagno], M);
+ tcg_gen_br(endl);
+ gen_set_label(l);
+
+ /* Fallback to the big guns */
+ gen_helper_dagadd(cpu_ireg[dagno], cpu_ireg[dagno],
+ cpu_lreg[dagno], cpu_breg[dagno], M);
+
+ gen_set_label(endl);
+}
+
+static void gen_dagaddi(DisasContext *dc, int dagno, uint32_t M)
+{
+ TCGv m = tcg_temp_local_new();
+ tcg_gen_movi_tl(m, M);
+ gen_dagadd(dc, dagno, m);
+ tcg_temp_free(m);
+}
+
+/* See dagadd() notes above. */
+static void gen_dagsub(DisasContext *dc, int dagno, TCGv M)
+{
+ int l, endl;
+
+ /* Optimize for when circ buffers are not used */
+ l = gen_new_label();
+ endl = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, cpu_lreg[dagno], 0, l);
+ tcg_gen_sub_tl(cpu_ireg[dagno], cpu_ireg[dagno], M);
+ tcg_gen_br(endl);
+ gen_set_label(l);
+
+ /* Fallback to the big guns */
+ gen_helper_dagsub(cpu_ireg[dagno], cpu_ireg[dagno],
+ cpu_lreg[dagno], cpu_breg[dagno], M);
+
+ gen_set_label(endl);
+}
+
+static void gen_dagsubi(DisasContext *dc, int dagno, uint32_t M)
+{
+ TCGv m = tcg_temp_local_new();
+ tcg_gen_movi_tl(m, M);
+ gen_dagsub(dc, dagno, m);
+ tcg_temp_free(m);
+}
+
+#define _gen_astat_store(bit, reg) tcg_gen_st_tl(reg, cpu_env, offsetof(CPUArchState, astat[bit]))
+
+static void _gen_astat_update_az(TCGv reg, TCGv tmp)
+{
+ tcg_gen_setcondi_tl(TCG_COND_EQ, tmp, reg, 0);
+ _gen_astat_store(ASTAT_AZ, tmp);
+}
+
+static void _gen_astat_update_az2(TCGv reg, TCGv reg2, TCGv tmp)
+{
+ TCGv tmp2 = tcg_temp_new();
+ tcg_gen_setcondi_tl(TCG_COND_EQ, tmp, reg, 0);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, tmp2, reg2, 0);
+ tcg_gen_or_tl(tmp, tmp, tmp2);
+ tcg_temp_free(tmp2);
+ _gen_astat_store(ASTAT_AZ, tmp);
+}
+
+static void _gen_astat_update_an(TCGv reg, TCGv tmp, uint32_t len)
+{
+ tcg_gen_setcondi_tl(TCG_COND_GEU, tmp, reg, 1 << (len - 1));
+ _gen_astat_store(ASTAT_AN, tmp);
+}
+
+static void _gen_astat_update_an2(TCGv reg, TCGv reg2, TCGv tmp, uint32_t len)
+{
+ TCGv tmp2 = tcg_temp_new();
+ tcg_gen_setcondi_tl(TCG_COND_GEU, tmp, reg, 1 << (len - 1));
+ tcg_gen_setcondi_tl(TCG_COND_GEU, tmp2, reg2, 1 << (len - 1));
+ tcg_gen_or_tl(tmp, tmp, tmp2);
+ tcg_temp_free(tmp2);
+ _gen_astat_store(ASTAT_AN, tmp);
+}
+
+static void _gen_astat_update_nz(TCGv reg, TCGv tmp, uint32_t len)
+{
+ _gen_astat_update_az(reg, tmp);
+ _gen_astat_update_an(reg, tmp, len);
+}
+
+static void _gen_astat_update_nz2(TCGv reg, TCGv reg2, TCGv tmp, uint32_t len)
+{
+ _gen_astat_update_az2(reg, reg2, tmp);
+ _gen_astat_update_an2(reg, reg2, tmp, len);
+}
+
+static void gen_astat_update(DisasContext *dc, bool clear)
+{
+ TCGv tmp = tcg_temp_local_new();
+ uint32_t len = 16;
+
+ switch (dc->astat_op) {
+ case ASTAT_OP_ABS: /* [0] = ABS( [1] ) */
+ len = 32;
+ /* XXX: Missing V/VS updates */
+ _gen_astat_update_nz(cpu_astat_arg[0], tmp, len);
+ break;
+
+ case ASTAT_OP_ABS_VECTOR: /* [0][1] = ABS( [2] ) (V) */
+ /* XXX: Missing V/VS updates */
+ _gen_astat_update_nz2(cpu_astat_arg[0], cpu_astat_arg[1], tmp, len);
+ break;
+
+ case ASTAT_OP_ADD32: /* [0] = [1] + [2] */
+ /* XXX: Missing V/VS updates */
+ len = 32;
+ tcg_gen_not_tl(tmp, cpu_astat_arg[1]);
+ tcg_gen_setcond_tl(TCG_COND_LTU, tmp, tmp, cpu_astat_arg[2]);
+ _gen_astat_store(ASTAT_AC0, tmp);
+ _gen_astat_store(ASTAT_AC0_COPY, tmp);
+ _gen_astat_update_nz(cpu_astat_arg[0], tmp, 32);
+ break;
+
+ case ASTAT_OP_ASHIFT32:
+ len *= 2;
+ case ASTAT_OP_ASHIFT16:
+ tcg_gen_movi_tl(tmp, 0);
+ /* Need to update AC0 ? */
+ _gen_astat_store(ASTAT_V, tmp);
+ _gen_astat_store(ASTAT_V_COPY, tmp);
+ _gen_astat_update_nz(cpu_astat_arg[0], tmp, len);
+ break;
+
+ case ASTAT_OP_COMPARE_SIGNED: {
+ TCGv flgs, flgo, overflow, flgn, res = tcg_temp_new();
+ tcg_gen_sub_tl(res, cpu_astat_arg[0], cpu_astat_arg[1]);
+ _gen_astat_update_az(res, tmp);
+ tcg_gen_setcond_tl(TCG_COND_LEU, tmp, cpu_astat_arg[1], cpu_astat_arg[0]);
+ _gen_astat_store(ASTAT_AC0, tmp);
+ _gen_astat_store(ASTAT_AC0_COPY, tmp);
+ /* XXX: This has got to be simpler ... */
+ /* int flgs = srcop >> 31; */
+ flgs = tcg_temp_new();
+ tcg_gen_shri_tl(flgs, cpu_astat_arg[0], 31);
+ /* int flgo = dstop >> 31; */
+ flgo = tcg_temp_new();
+ tcg_gen_shri_tl(flgo, cpu_astat_arg[1], 31);
+ /* int flgn = result >> 31; */
+ flgn = tcg_temp_new();
+ tcg_gen_shri_tl(flgn, res, 31);
+ /* int overflow = (flgs ^ flgo) & (flgn ^ flgs); */
+ overflow = tcg_temp_new();
+ tcg_gen_xor_tl(tmp, flgs, flgo);
+ tcg_gen_xor_tl(overflow, flgn, flgs);
+ tcg_gen_and_tl(overflow, tmp, overflow);
+ /* an = (flgn && !overflow) || (!flgn && overflow); */
+ tcg_gen_not_tl(tmp, overflow);
+ tcg_gen_and_tl(tmp, flgn, tmp);
+ tcg_gen_not_tl(res, flgn);
+ tcg_gen_and_tl(res, res, overflow);
+ tcg_gen_or_tl(tmp, tmp, res);
+ tcg_temp_free(flgn);
+ tcg_temp_free(overflow);
+ tcg_temp_free(flgo);
+ tcg_temp_free(flgs);
+ tcg_temp_free(res);
+ _gen_astat_store(ASTAT_AN, tmp);
+ break;
+ }
+
+ case ASTAT_OP_COMPARE_UNSIGNED:
+ tcg_gen_sub_tl(tmp, cpu_astat_arg[0], cpu_astat_arg[1]);
+ _gen_astat_update_az(tmp, tmp);
+ tcg_gen_setcond_tl(TCG_COND_LEU, tmp, cpu_astat_arg[1], cpu_astat_arg[0]);
+ _gen_astat_store(ASTAT_AC0, tmp);
+ _gen_astat_store(ASTAT_AC0_COPY, tmp);
+ tcg_gen_setcond_tl(TCG_COND_GTU, tmp, cpu_astat_arg[1], cpu_astat_arg[0]);
+ _gen_astat_store(ASTAT_AN, tmp);
+ break;
+
+ case ASTAT_OP_LOGICAL:
+ len = 32;
+ tcg_gen_movi_tl(tmp, 0);
+ /* AC0 is correct ? */
+ _gen_astat_store(ASTAT_AC0, tmp);
+ _gen_astat_store(ASTAT_AC0_COPY, tmp);
+ _gen_astat_store(ASTAT_V, tmp);
+ _gen_astat_store(ASTAT_V_COPY, tmp);
+ _gen_astat_update_nz(cpu_astat_arg[0], tmp, len);
+ break;
+
+ case ASTAT_OP_LSHIFT32:
+ len *= 2;
+ case ASTAT_OP_LSHIFT16:
+ _gen_astat_update_az(cpu_astat_arg[0], tmp);
+ /* XXX: should be checking bit shifted */
+ tcg_gen_setcondi_tl(TCG_COND_GEU, tmp, cpu_astat_arg[0], 1 << (len - 1));
+ _gen_astat_store(ASTAT_AN, tmp);
+ /* XXX: No saturation handling ... */
+ tcg_gen_movi_tl(tmp, 0);
+ _gen_astat_store(ASTAT_V, tmp);
+ _gen_astat_store(ASTAT_V_COPY, tmp);
+ break;
+
+ case ASTAT_OP_LSHIFT_RT32:
+ len *= 2;
+ case ASTAT_OP_LSHIFT_RT16:
+ _gen_astat_update_az(cpu_astat_arg[0], tmp);
+ /* XXX: should be checking bit shifted */
+ tcg_gen_setcondi_tl(TCG_COND_GEU, tmp, cpu_astat_arg[0], 1 << (len - 1));
+ _gen_astat_store(ASTAT_AN, tmp);
+ tcg_gen_movi_tl(tmp, 0);
+ _gen_astat_store(ASTAT_V, tmp);
+ _gen_astat_store(ASTAT_V_COPY, tmp);
+ break;
+
+ case ASTAT_OP_MIN_MAX: /* [0] = MAX/MIN( [1], [2] ) */
+ tcg_gen_movi_tl(tmp, 0);
+ _gen_astat_store(ASTAT_V, tmp);
+ _gen_astat_store(ASTAT_V_COPY, tmp);
+ _gen_astat_update_nz(cpu_astat_arg[0], tmp, 32);
+ break;
+
+ case ASTAT_OP_MIN_MAX_VECTOR: /* [0][1] = MAX/MIN( [2], [3] ) (V) */
+ tcg_gen_movi_tl(tmp, 0);
+ _gen_astat_store(ASTAT_V, tmp);
+ _gen_astat_store(ASTAT_V_COPY, tmp);
+ tcg_gen_sari_tl(cpu_astat_arg[0], cpu_astat_arg[0], 16);
+ _gen_astat_update_nz2(cpu_astat_arg[0], cpu_astat_arg[1], tmp, 16);
+ break;
+
+ case ASTAT_OP_NEGATE: /* [0] = -[1] */
+ len = 32;
+ _gen_astat_update_nz(cpu_astat_arg[0], tmp, 32);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, tmp, cpu_astat_arg[0], 1 << (len - 1));
+ _gen_astat_store(ASTAT_V, tmp);
+ /* XXX: Should "VS |= V;" */
+ tcg_gen_setcondi_tl(TCG_COND_EQ, tmp, cpu_astat_arg[0], 0);
+ _gen_astat_store(ASTAT_AC0, tmp);
+ break;
+
+ case ASTAT_OP_SUB32: /* [0] = [1] - [2] */
+ len = 32;
+ /* XXX: Missing V/VS updates */
+ tcg_gen_setcond_tl(TCG_COND_LEU, tmp, cpu_astat_arg[2], cpu_astat_arg[1]);
+ _gen_astat_store(ASTAT_AC0, tmp);
+ _gen_astat_store(ASTAT_AC0_COPY, tmp);
+ _gen_astat_update_nz(cpu_astat_arg[0], tmp, len);
+ break;
+
+ case ASTAT_OP_VECTOR_ADD_ADD: /* [0][1] = [2] +|+ [3] */
+ case ASTAT_OP_VECTOR_ADD_SUB: /* [0][1] = [2] +|- [3] */
+ case ASTAT_OP_VECTOR_SUB_SUB: /* [0][1] = [2] -|- [3] */
+ case ASTAT_OP_VECTOR_SUB_ADD: /* [0][1] = [2] -|+ [3] */
+ _gen_astat_update_az2(cpu_astat_arg[0], cpu_astat_arg[1], tmp);
+ /* Need AN, AC0/AC1, V */
+ break;
+
+ default:
+ fprintf(stderr, "qemu: unhandled astat op %u\n", dc->astat_op);
+ abort();
+ case ASTAT_OP_DYNAMIC:
+ case ASTAT_OP_NONE:
+ break;
+ }
+
+ tcg_temp_free(tmp);
+
+ if (clear)
+ dc->astat_op = ASTAT_OP_NONE;
+}
+
+static void
+_astat_queue_state(DisasContext *dc, enum astat_ops op, unsigned int num,
+ TCGv arg0, TCGv arg1, TCGv arg2)
+{
+ dc->astat_op = op;
+ /*tcg_gen_movi_tl(cpu_astat_op, dc->astat_op);*/
+
+ tcg_gen_mov_tl(cpu_astat_arg[0], arg0);
+ if (num > 1)
+ tcg_gen_mov_tl(cpu_astat_arg[1], arg1);
+ else
+ tcg_gen_discard_tl(cpu_astat_arg[1]);
+ if (num > 2)
+ tcg_gen_mov_tl(cpu_astat_arg[2], arg2);
+ else
+ tcg_gen_discard_tl(cpu_astat_arg[2]);
+}
+#define astat_queue_state1(dc, op, arg0) _astat_queue_state(dc, op, 1, arg0, arg0, arg0)
+#define astat_queue_state2(dc, op, arg0, arg1) _astat_queue_state(dc, op, 2, arg0, arg1, arg1)
+#define astat_queue_state3(dc, op, arg0, arg1, arg2) _astat_queue_state(dc, op, 3, arg0, arg1, arg2)
+
+static void gen_astat_load(DisasContext *dc, TCGv reg)
+{
+ gen_astat_update(dc, true);
+ gen_helper_astat_load(reg, cpu_env);
+}
+
+static void gen_astat_store(DisasContext *dc, TCGv reg)
+{
+ unsigned int i;
+
+ gen_helper_astat_store(cpu_env, reg);
+
+ dc->astat_op = ASTAT_OP_NONE;
+ /*tcg_gen_movi_tl(cpu_astat_op, dc->astat_op);*/
+
+ for (i = 0; i < ARRAY_SIZE(cpu_astat_arg); ++i)
+ tcg_gen_discard_tl(cpu_astat_arg[i]);
+}
+
+static void interp_insn_bfin(DisasContext *dc);
+
+static void check_breakpoint(CPUArchState *env, DisasContext *dc)
+{
+ CPUBreakpoint *bp;
+
+ if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
+ QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (bp->pc == dc->pc) {
+ cec_exception(dc, EXCP_DEBUG);
+ dc->is_jmp = DISAS_UPDATE;
+ }
+ }
+ }
+}
+
+static void
+gen_intermediate_code_internal(CPUArchState *env, TranslationBlock *tb,
+ int search_pc)
+{
+ uint16_t *gen_opc_end;
+ uint32_t pc_start;
+ int j, lj;
+ struct DisasContext ctx;
+ struct DisasContext *dc = &ctx;
+ uint32_t next_page_start;
+ int num_insns;
+ int max_insns;
+
+ pc_start = tb->pc;
+ dc->env = env;
+ dc->tb = tb;
+ /* XXX: handle super/user mode here. */
+ dc->mem_idx = 0;
+
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
+
+ dc->is_jmp = DISAS_NEXT;
+ dc->pc = pc_start;
+ dc->astat_op = ASTAT_OP_DYNAMIC;
+ dc->hwloop_callback = gen_hwloop_default;
+ dc->disalgnexcpt = 1;
+
+ next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+ lj = -1;
+ num_insns = 0;
+ max_insns = tb->cflags & CF_COUNT_MASK;
+ if (max_insns == 0)
+ max_insns = CF_COUNT_MASK;
+
+ gen_tb_start();
+ do {
+ check_breakpoint(env, dc);
+
+ if (search_pc) {
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
+ if (lj < j) {
+ lj++;
+ while (lj < j)
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
+ }
+ tcg_ctx.gen_opc_pc[lj] = dc->pc;
+ tcg_ctx.gen_opc_instr_start[lj] = 1;
+ tcg_ctx.gen_opc_icount[lj] = num_insns;
+ }
+
+ if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
+ gen_io_start();
+
+ if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
+ tcg_gen_debug_insn_start(dc->pc);
+
+ interp_insn_bfin(dc);
+ gen_hwloop_check(dc);
+ dc->pc += dc->insn_len;
+
+ ++num_insns;
+ } while (!dc->is_jmp &&
+ tcg_ctx.gen_opc_ptr < gen_opc_end &&
+ !env->singlestep_enabled &&
+ !singlestep &&
+ dc->pc < next_page_start &&
+ num_insns < max_insns);
+
+ if (tb->cflags & CF_LAST_IO)
+ gen_io_end();
+
+ if (unlikely(env->singlestep_enabled)) {
+ cec_exception(dc, EXCP_DEBUG);
+ } else {
+ switch (dc->is_jmp) {
+ case DISAS_NEXT:
+ gen_gotoi_tb(dc, 1, dc->pc);
+ break;
+ default:
+ case DISAS_UPDATE:
+ /* indicate that the hash table must be used
+ to find the next TB */
+ tcg_gen_exit_tb(0);
+ break;
+ case DISAS_CALL:
+ case DISAS_JUMP:
+ case DISAS_TB_JUMP:
+ /* nothing more to generate */
+ break;
+ }
+ }
+
+ gen_tb_end(tb, num_insns);
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
+
+#ifdef DEBUG_DISAS
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+ qemu_log("----------------\n");
+ qemu_log("IN: %s\n", lookup_symbol(pc_start));
+ log_target_disas(env, pc_start, dc->pc - pc_start, 0);
+ qemu_log("\n");
+ }
+#endif
+ if (search_pc) {
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
+ lj++;
+ while (lj <= j)
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
+ } else {
+ tb->size = dc->pc - pc_start;
+ tb->icount = num_insns;
+ }
+}
+
+void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb)
+{
+ gen_intermediate_code_internal(env, tb, 0);
+}
+
+void gen_intermediate_code_pc(CPUArchState *env, struct TranslationBlock *tb)
+{
+ gen_intermediate_code_internal(env, tb, 1);
+}
+
+void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb, int pc_pos)
+{
+ env->pc = tcg_ctx.gen_opc_pc[pc_pos];
+}
+
+#include "bfin-sim.c"
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
@ 2013-06-17 7:16 ` Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 4/5] Blackfin: add test suite Mike Frysinger
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2013-06-17 7:16 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
default-configs/bfin-linux-user.mak | 1 +
linux-user/bfin/syscall.h | 59 ++++++
linux-user/bfin/syscall_nr.h | 389 ++++++++++++++++++++++++++++++++++++
linux-user/bfin/target_flat.h | 92 +++++++++
linux-user/bfin/target_sigcontext.h | 61 ++++++
linux-user/bfin/target_signal.h | 31 +++
linux-user/bfin/termbits.h | 227 +++++++++++++++++++++
linux-user/elfload.c | 47 +++++
linux-user/main.c | 160 +++++++++++++++
linux-user/qemu.h | 4 +
linux-user/signal.c | 225 +++++++++++++++++++++
linux-user/syscall.c | 3 +-
linux-user/syscall_defs.h | 65 +++++-
linux-user/target_ucontext.h | 14 ++
14 files changed, 1375 insertions(+), 3 deletions(-)
create mode 100644 default-configs/bfin-linux-user.mak
create mode 100644 linux-user/bfin/syscall.h
create mode 100644 linux-user/bfin/syscall_nr.h
create mode 100644 linux-user/bfin/target_flat.h
create mode 100644 linux-user/bfin/target_sigcontext.h
create mode 100644 linux-user/bfin/target_signal.h
create mode 100644 linux-user/bfin/termbits.h
create mode 100644 linux-user/target_ucontext.h
diff --git a/default-configs/bfin-linux-user.mak b/default-configs/bfin-linux-user.mak
new file mode 100644
index 0000000..5f7aefb
--- /dev/null
+++ b/default-configs/bfin-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for bfin-linux-user
diff --git a/linux-user/bfin/syscall.h b/linux-user/bfin/syscall.h
new file mode 100644
index 0000000..892ee75
--- /dev/null
+++ b/linux-user/bfin/syscall.h
@@ -0,0 +1,59 @@
+struct target_pt_regs {
+ abi_ulong orig_pc;
+ abi_ulong ipend;
+ abi_ulong seqstat;
+ abi_ulong rete;
+ abi_ulong retn;
+ abi_ulong retx;
+ abi_ulong pc; /* PC == RETI */
+ abi_ulong rets;
+ abi_ulong reserved; /* Used as scratch during system calls */
+ abi_ulong astat;
+ abi_ulong lb1;
+ abi_ulong lb0;
+ abi_ulong lt1;
+ abi_ulong lt0;
+ abi_ulong lc1;
+ abi_ulong lc0;
+ abi_ulong a1w;
+ abi_ulong a1x;
+ abi_ulong a0w;
+ abi_ulong a0x;
+ abi_ulong b3;
+ abi_ulong b2;
+ abi_ulong b1;
+ abi_ulong b0;
+ abi_ulong l3;
+ abi_ulong l2;
+ abi_ulong l1;
+ abi_ulong l0;
+ abi_ulong m3;
+ abi_ulong m2;
+ abi_ulong m1;
+ abi_ulong m0;
+ abi_ulong i3;
+ abi_ulong i2;
+ abi_ulong i1;
+ abi_ulong i0;
+ abi_ulong usp;
+ abi_ulong fp;
+ abi_ulong p5;
+ abi_ulong p4;
+ abi_ulong p3;
+ abi_ulong p2;
+ abi_ulong p1;
+ abi_ulong p0;
+ abi_ulong r7;
+ abi_ulong r6;
+ abi_ulong r5;
+ abi_ulong r4;
+ abi_ulong r3;
+ abi_ulong r2;
+ abi_ulong r1;
+ abi_ulong r0;
+ abi_ulong orig_r0;
+ abi_ulong orig_p0;
+ abi_ulong syscfg;
+};
+
+#define UNAME_MACHINE "blackfin"
diff --git a/linux-user/bfin/syscall_nr.h b/linux-user/bfin/syscall_nr.h
new file mode 100644
index 0000000..52ec628
--- /dev/null
+++ b/linux-user/bfin/syscall_nr.h
@@ -0,0 +1,389 @@
+/*
+ * This file contains the system call numbers.
+ */
+#define TARGET_NR_restart_syscall 0
+#define TARGET_NR_exit 1
+#define TARGET_NR_fork 2
+#define TARGET_NR_read 3
+#define TARGET_NR_write 4
+#define TARGET_NR_open 5
+#define TARGET_NR_close 6
+ /* 7 TARGET_NR_waitpid obsolete */
+#define TARGET_NR_creat 8
+#define TARGET_NR_link 9
+#define TARGET_NR_unlink 10
+#define TARGET_NR_execve 11
+#define TARGET_NR_chdir 12
+#define TARGET_NR_time 13
+#define TARGET_NR_mknod 14
+#define TARGET_NR_chmod 15
+#define TARGET_NR_chown 16
+ /* 17 TARGET_NR_break obsolete */
+ /* 18 TARGET_NR_oldstat obsolete */
+#define TARGET_NR_lseek 19
+#define TARGET_NR_getpid 20
+#define TARGET_NR_mount 21
+ /* 22 TARGET_NR_umount obsolete */
+#define TARGET_NR_setuid 23
+#define TARGET_NR_getuid 24
+#define TARGET_NR_stime 25
+#define TARGET_NR_ptrace 26
+#define TARGET_NR_alarm 27
+ /* 28 TARGET_NR_oldfstat obsolete */
+#define TARGET_NR_pause 29
+ /* 30 TARGET_NR_utime obsolete */
+ /* 31 TARGET_NR_stty obsolete */
+ /* 32 TARGET_NR_gtty obsolete */
+#define TARGET_NR_access 33
+#define TARGET_NR_nice 34
+ /* 35 TARGET_NR_ftime obsolete */
+#define TARGET_NR_sync 36
+#define TARGET_NR_kill 37
+#define TARGET_NR_rename 38
+#define TARGET_NR_mkdir 39
+#define TARGET_NR_rmdir 40
+#define TARGET_NR_dup 41
+#define TARGET_NR_pipe 42
+#define TARGET_NR_times 43
+ /* 44 TARGET_NR_prof obsolete */
+#define TARGET_NR_brk 45
+#define TARGET_NR_setgid 46
+#define TARGET_NR_getgid 47
+ /* 48 TARGET_NR_signal obsolete */
+#define TARGET_NR_geteuid 49
+#define TARGET_NR_getegid 50
+#define TARGET_NR_acct 51
+#define TARGET_NR_umount2 52
+ /* 53 TARGET_NR_lock obsolete */
+#define TARGET_NR_ioctl 54
+#define TARGET_NR_fcntl 55
+ /* 56 TARGET_NR_mpx obsolete */
+#define TARGET_NR_setpgid 57
+ /* 58 TARGET_NR_ulimit obsolete */
+ /* 59 TARGET_NR_oldolduname obsolete */
+#define TARGET_NR_umask 60
+#define TARGET_NR_chroot 61
+#define TARGET_NR_ustat 62
+#define TARGET_NR_dup2 63
+#define TARGET_NR_getppid 64
+#define TARGET_NR_getpgrp 65
+#define TARGET_NR_setsid 66
+ /* 67 TARGET_NR_sigaction obsolete */
+#define TARGET_NR_sgetmask 68
+#define TARGET_NR_ssetmask 69
+#define TARGET_NR_setreuid 70
+#define TARGET_NR_setregid 71
+ /* 72 TARGET_NR_sigsuspend obsolete */
+ /* 73 TARGET_NR_sigpending obsolete */
+#define TARGET_NR_sethostname 74
+#define TARGET_NR_setrlimit 75
+ /* 76 TARGET_NR_old_getrlimit obsolete */
+#define TARGET_NR_getrusage 77
+#define TARGET_NR_gettimeofday 78
+#define TARGET_NR_settimeofday 79
+#define TARGET_NR_getgroups 80
+#define TARGET_NR_setgroups 81
+ /* 82 TARGET_NR_select obsolete */
+#define TARGET_NR_symlink 83
+ /* 84 TARGET_NR_oldlstat obsolete */
+#define TARGET_NR_readlink 85
+ /* 86 TARGET_NR_uselib obsolete */
+ /* 87 TARGET_NR_swapon obsolete */
+#define TARGET_NR_reboot 88
+ /* 89 TARGET_NR_readdir obsolete */
+ /* 90 TARGET_NR_mmap obsolete */
+#define TARGET_NR_munmap 91
+#define TARGET_NR_truncate 92
+#define TARGET_NR_ftruncate 93
+#define TARGET_NR_fchmod 94
+#define TARGET_NR_fchown 95
+#define TARGET_NR_getpriority 96
+#define TARGET_NR_setpriority 97
+ /* 98 TARGET_NR_profil obsolete */
+#define TARGET_NR_statfs 99
+#define TARGET_NR_fstatfs 100
+ /* 101 TARGET_NR_ioperm */
+ /* 102 TARGET_NR_socketcall obsolete */
+#define TARGET_NR_syslog 103
+#define TARGET_NR_setitimer 104
+#define TARGET_NR_getitimer 105
+#define TARGET_NR_stat 106
+#define TARGET_NR_lstat 107
+#define TARGET_NR_fstat 108
+ /* 109 TARGET_NR_olduname obsolete */
+ /* 110 TARGET_NR_iopl obsolete */
+#define TARGET_NR_vhangup 111
+ /* 112 TARGET_NR_idle obsolete */
+ /* 113 TARGET_NR_vm86old */
+#define TARGET_NR_wait4 114
+ /* 115 TARGET_NR_swapoff obsolete */
+#define TARGET_NR_sysinfo 116
+ /* 117 TARGET_NR_ipc oboslete */
+#define TARGET_NR_fsync 118
+ /* 119 TARGET_NR_sigreturn obsolete */
+#define TARGET_NR_clone 120
+#define TARGET_NR_setdomainname 121
+#define TARGET_NR_uname 122
+ /* 123 TARGET_NR_modify_ldt obsolete */
+#define TARGET_NR_adjtimex 124
+#define TARGET_NR_mprotect 125
+ /* 126 TARGET_NR_sigprocmask obsolete */
+ /* 127 TARGET_NR_create_module obsolete */
+#define TARGET_NR_init_module 128
+#define TARGET_NR_delete_module 129
+ /* 130 TARGET_NR_get_kernel_syms obsolete */
+#define TARGET_NR_quotactl 131
+#define TARGET_NR_getpgid 132
+#define TARGET_NR_fchdir 133
+#define TARGET_NR_bdflush 134
+ /* 135 was sysfs */
+#define TARGET_NR_personality 136
+ /* 137 TARGET_NR_afs_syscall */
+#define TARGET_NR_setfsuid 138
+#define TARGET_NR_setfsgid 139
+#define TARGET_NR__llseek 140
+#define TARGET_NR_getdents 141
+ /* 142 TARGET_NR__newselect obsolete */
+#define TARGET_NR_flock 143
+ /* 144 TARGET_NR_msync obsolete */
+#define TARGET_NR_readv 145
+#define TARGET_NR_writev 146
+#define TARGET_NR_getsid 147
+#define TARGET_NR_fdatasync 148
+#define TARGET_NR__sysctl 149
+ /* 150 TARGET_NR_mlock */
+ /* 151 TARGET_NR_munlock */
+ /* 152 TARGET_NR_mlockall */
+ /* 153 TARGET_NR_munlockall */
+#define TARGET_NR_sched_setparam 154
+#define TARGET_NR_sched_getparam 155
+#define TARGET_NR_sched_setscheduler 156
+#define TARGET_NR_sched_getscheduler 157
+#define TARGET_NR_sched_yield 158
+#define TARGET_NR_sched_get_priority_max 159
+#define TARGET_NR_sched_get_priority_min 160
+#define TARGET_NR_sched_rr_get_interval 161
+#define TARGET_NR_nanosleep 162
+#define TARGET_NR_mremap 163
+#define TARGET_NR_setresuid 164
+#define TARGET_NR_getresuid 165
+ /* 166 TARGET_NR_vm86 */
+ /* 167 TARGET_NR_query_module */
+ /* 168 TARGET_NR_poll */
+#define TARGET_NR_nfsservctl 169
+#define TARGET_NR_setresgid 170
+#define TARGET_NR_getresgid 171
+#define TARGET_NR_prctl 172
+#define TARGET_NR_rt_sigreturn 173
+#define TARGET_NR_rt_sigaction 174
+#define TARGET_NR_rt_sigprocmask 175
+#define TARGET_NR_rt_sigpending 176
+#define TARGET_NR_rt_sigtimedwait 177
+#define TARGET_NR_rt_sigqueueinfo 178
+#define TARGET_NR_rt_sigsuspend 179
+#define TARGET_NR_pread 180
+#define TARGET_NR_pwrite 181
+#define TARGET_NR_lchown 182
+#define TARGET_NR_getcwd 183
+#define TARGET_NR_capget 184
+#define TARGET_NR_capset 185
+#define TARGET_NR_sigaltstack 186
+#define TARGET_NR_sendfile 187
+ /* 188 TARGET_NR_getpmsg */
+ /* 189 TARGET_NR_putpmsg */
+#define TARGET_NR_vfork 190
+#define TARGET_NR_getrlimit 191
+#define TARGET_NR_mmap2 192 /* xxx: this is mmap2 !? */
+#define TARGET_NR_truncate64 193
+#define TARGET_NR_ftruncate64 194
+#define TARGET_NR_stat64 195
+#define TARGET_NR_lstat64 196
+#define TARGET_NR_fstat64 197
+#define TARGET_NR_chown32 198
+#define TARGET_NR_getuid32 199
+#define TARGET_NR_getgid32 200
+#define TARGET_NR_geteuid32 201
+#define TARGET_NR_getegid32 202
+#define TARGET_NR_setreuid32 203
+#define TARGET_NR_setregid32 204
+#define TARGET_NR_getgroups32 205
+#define TARGET_NR_setgroups32 206
+#define TARGET_NR_fchown32 207
+#define TARGET_NR_setresuid32 208
+#define TARGET_NR_getresuid32 209
+#define TARGET_NR_setresgid32 210
+#define TARGET_NR_getresgid32 211
+#define TARGET_NR_lchown32 212
+#define TARGET_NR_setuid32 213
+#define TARGET_NR_setgid32 214
+#define TARGET_NR_setfsuid32 215
+#define TARGET_NR_setfsgid32 216
+#define TARGET_NR_pivot_root 217
+ /* 218 TARGET_NR_mincore */
+ /* 219 TARGET_NR_madvise */
+#define TARGET_NR_getdents64 220
+#define TARGET_NR_fcntl64 221
+ /* 222 reserved for TUX */
+ /* 223 reserved for TUX */
+#define TARGET_NR_gettid 224
+#define TARGET_NR_readahead 225
+#define TARGET_NR_setxattr 226
+#define TARGET_NR_lsetxattr 227
+#define TARGET_NR_fsetxattr 228
+#define TARGET_NR_getxattr 229
+#define TARGET_NR_lgetxattr 230
+#define TARGET_NR_fgetxattr 231
+#define TARGET_NR_listxattr 232
+#define TARGET_NR_llistxattr 233
+#define TARGET_NR_flistxattr 234
+#define TARGET_NR_removexattr 235
+#define TARGET_NR_lremovexattr 236
+#define TARGET_NR_fremovexattr 237
+#define TARGET_NR_tkill 238
+#define TARGET_NR_sendfile64 239
+#define TARGET_NR_futex 240
+#define TARGET_NR_sched_setaffinity 241
+#define TARGET_NR_sched_getaffinity 242
+ /* 243 TARGET_NR_set_thread_area */
+ /* 244 TARGET_NR_get_thread_area */
+#define TARGET_NR_io_setup 245
+#define TARGET_NR_io_destroy 246
+#define TARGET_NR_io_getevents 247
+#define TARGET_NR_io_submit 248
+#define TARGET_NR_io_cancel 249
+ /* 250 TARGET_NR_alloc_hugepages */
+ /* 251 TARGET_NR_free_hugepages */
+#define TARGET_NR_exit_group 252
+#define TARGET_NR_lookup_dcookie 253
+#define TARGET_NR_bfin_spinlock 254
+
+#define TARGET_NR_epoll_create 255
+#define TARGET_NR_epoll_ctl 256
+#define TARGET_NR_epoll_wait 257
+ /* 258 TARGET_NR_remap_file_pages */
+#define TARGET_NR_set_tid_address 259
+#define TARGET_NR_timer_create 260
+#define TARGET_NR_timer_settime 261
+#define TARGET_NR_timer_gettime 262
+#define TARGET_NR_timer_getoverrun 263
+#define TARGET_NR_timer_delete 264
+#define TARGET_NR_clock_settime 265
+#define TARGET_NR_clock_gettime 266
+#define TARGET_NR_clock_getres 267
+#define TARGET_NR_clock_nanosleep 268
+#define TARGET_NR_statfs64 269
+#define TARGET_NR_fstatfs64 270
+#define TARGET_NR_tgkill 271
+#define TARGET_NR_utimes 272
+#define TARGET_NR_fadvise64_64 273
+ /* 274 TARGET_NR_vserver */
+ /* 275 TARGET_NR_mbind */
+ /* 276 TARGET_NR_get_mempolicy */
+ /* 277 TARGET_NR_set_mempolicy */
+#define TARGET_NR_mq_open 278
+#define TARGET_NR_mq_unlink 279
+#define TARGET_NR_mq_timedsend 280
+#define TARGET_NR_mq_timedreceive 281
+#define TARGET_NR_mq_notify 282
+#define TARGET_NR_mq_getsetattr 283
+#define TARGET_NR_kexec_load 284
+#define TARGET_NR_waitid 285
+#define TARGET_NR_add_key 286
+#define TARGET_NR_request_key 287
+#define TARGET_NR_keyctl 288
+#define TARGET_NR_ioprio_set 289
+#define TARGET_NR_ioprio_get 290
+#define TARGET_NR_inotify_init 291
+#define TARGET_NR_inotify_add_watch 292
+#define TARGET_NR_inotify_rm_watch 293
+ /* 294 TARGET_NR_migrate_pages */
+#define TARGET_NR_openat 295
+#define TARGET_NR_mkdirat 296
+#define TARGET_NR_mknodat 297
+#define TARGET_NR_fchownat 298
+#define TARGET_NR_futimesat 299
+#define TARGET_NR_fstatat64 300
+#define TARGET_NR_unlinkat 301
+#define TARGET_NR_renameat 302
+#define TARGET_NR_linkat 303
+#define TARGET_NR_symlinkat 304
+#define TARGET_NR_readlinkat 305
+#define TARGET_NR_fchmodat 306
+#define TARGET_NR_faccessat 307
+#define TARGET_NR_pselect6 308
+#define TARGET_NR_ppoll 309
+#define TARGET_NR_unshare 310
+
+/* Blackfin private syscalls */
+#define TARGET_NR_sram_alloc 311
+#define TARGET_NR_sram_free 312
+#define TARGET_NR_dma_memcpy 313
+
+/* socket syscalls */
+#define TARGET_NR_accept 314
+#define TARGET_NR_bind 315
+#define TARGET_NR_connect 316
+#define TARGET_NR_getpeername 317
+#define TARGET_NR_getsockname 318
+#define TARGET_NR_getsockopt 319
+#define TARGET_NR_listen 320
+#define TARGET_NR_recv 321
+#define TARGET_NR_recvfrom 322
+#define TARGET_NR_recvmsg 323
+#define TARGET_NR_send 324
+#define TARGET_NR_sendmsg 325
+#define TARGET_NR_sendto 326
+#define TARGET_NR_setsockopt 327
+#define TARGET_NR_shutdown 328
+#define TARGET_NR_socket 329
+#define TARGET_NR_socketpair 330
+
+/* sysv ipc syscalls */
+#define TARGET_NR_semctl 331
+#define TARGET_NR_semget 332
+#define TARGET_NR_semop 333
+#define TARGET_NR_msgctl 334
+#define TARGET_NR_msgget 335
+#define TARGET_NR_msgrcv 336
+#define TARGET_NR_msgsnd 337
+#define TARGET_NR_shmat 338
+#define TARGET_NR_shmctl 339
+#define TARGET_NR_shmdt 340
+#define TARGET_NR_shmget 341
+
+#define TARGET_NR_splice 342
+#define TARGET_NR_sync_file_range 343
+#define TARGET_NR_tee 344
+#define TARGET_NR_vmsplice 345
+
+#define TARGET_NR_epoll_pwait 346
+#define TARGET_NR_utimensat 347
+#define TARGET_NR_signalfd 348
+#define TARGET_NR_timerfd_create 349
+#define TARGET_NR_eventfd 350
+#define TARGET_NR_pread64 351
+#define TARGET_NR_pwrite64 352
+#define TARGET_NR_fadvise64 353
+#define TARGET_NR_set_robust_list 354
+#define TARGET_NR_get_robust_list 355
+#define TARGET_NR_fallocate 356
+#define TARGET_NR_semtimedop 357
+#define TARGET_NR_timerfd_settime 358
+#define TARGET_NR_timerfd_gettime 359
+#define TARGET_NR_signalfd4 360
+#define TARGET_NR_eventfd2 361
+#define TARGET_NR_epoll_create1 362
+#define TARGET_NR_dup3 363
+#define TARGET_NR_pipe2 364
+#define TARGET_NR_inotify_init1 365
+#define TARGET_NR_preadv 366
+#define TARGET_NR_pwritev 367
+#define TARGET_NR_rt_tgsigqueueinfo 368
+#define TARGET_NR_perf_event_open 369
+#define TARGET_NR_recvmmsg 370
+#define TARGET_NR_fanotify_init 371
+#define TARGET_NR_fanotify_mark 372
+#define TARGET_NR_prlimit64 373
+#define TARGET_NR_cacheflush 374
+
+#define TARGET_NR_syscall 375
diff --git a/linux-user/bfin/target_flat.h b/linux-user/bfin/target_flat.h
new file mode 100644
index 0000000..c694a6a
--- /dev/null
+++ b/linux-user/bfin/target_flat.h
@@ -0,0 +1,92 @@
+/*
+ * uClinux flat-format executables
+ *
+ * Copyright 2003-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2
+ */
+
+#define FLAT_BFIN_RELOC_TYPE_16_BIT 0
+#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
+#define FLAT_BFIN_RELOC_TYPE_32_BIT 2
+
+#define flat_argvp_envp_on_stack() 0
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_old_ram_flag(flag) (flag)
+#define flat_get_relocate_addr(relval) ((relval) & 0x03ffffff)
+
+static inline int flat_set_persistent(abi_ulong relval, abi_ulong *persistent)
+{
+ int type = (relval >> 26) & 7;
+ if (type == 3) {
+ *persistent = relval << 16;
+ return 1;
+ }
+ return 0;
+}
+
+static abi_ulong
+flat_get_addr_from_rp(abi_ulong ul_ptr, abi_ulong relval, abi_ulong flags, abi_ulong *persistent)
+{
+ int type = (relval >> 26) & 7;
+ abi_ulong val;
+
+#ifdef DEBUG
+ printf("%s:%i: ptr:%8x relval:%8x type:%x flags:%x persistent:%x",
+ __func__, __LINE__, ul_ptr, relval, type, flags, *persistent);
+#endif
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT:
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+ if (get_user_u16(val, ul_ptr)) {
+ fprintf(stderr, "BINFMT_FLAT: unable to read reloc at %#x\n", ul_ptr);
+ abort();
+ }
+ val += *persistent;
+ break;
+ case FLAT_BFIN_RELOC_TYPE_32_BIT:
+ if (get_user_u32(val, ul_ptr)) {
+ fprintf(stderr, "BINFMT_FLAT: unable to read reloc at %#x\n", ul_ptr);
+ abort();
+ }
+ break;
+ default:
+ fprintf(stderr, "BINFMT_FLAT: Unknown relocation type %x\n", type);
+ abort();
+ break;
+ }
+#ifdef DEBUG
+ printf(" val:%x\n", val);
+#endif
+
+ /*
+ * Stack-relative relocs contain the offset into the stack, we
+ * have to add the stack's start address here and return 1 from
+ * flat_addr_absolute to prevent the normal address calculations
+ */
+ if (relval & (1 << 29)) {
+ fprintf(stderr, "BINFMT_FLAT: stack relocs not supported\n");
+ abort();
+ /*return val + current->mm->context.end_brk;*/
+ }
+
+ if ((flags & FLAT_FLAG_GOTPIC) == 0)
+ val = ntohl(val);
+
+ return val;
+}
+
+static int
+flat_put_addr_at_rp(abi_ulong ptr, abi_ulong addr, abi_ulong relval)
+{
+ int type = (relval >> 26) & 7;
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT: return put_user_u16(addr, ptr);
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT: return put_user_u16(addr >> 16, ptr);
+ case FLAT_BFIN_RELOC_TYPE_32_BIT: return put_user_u32(addr, ptr);
+ }
+
+ abort();
+}
diff --git a/linux-user/bfin/target_sigcontext.h b/linux-user/bfin/target_sigcontext.h
new file mode 100644
index 0000000..10d61e2
--- /dev/null
+++ b/linux-user/bfin/target_sigcontext.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef TARGET_SIGCONTEXT_H
+#define TARGET_SIGCONTEXT_H
+
+/* Add new entries at the end of the structure only. */
+struct target_sigcontext {
+ abi_ulong sc_r0;
+ abi_ulong sc_r1;
+ abi_ulong sc_r2;
+ abi_ulong sc_r3;
+ abi_ulong sc_r4;
+ abi_ulong sc_r5;
+ abi_ulong sc_r6;
+ abi_ulong sc_r7;
+ abi_ulong sc_p0;
+ abi_ulong sc_p1;
+ abi_ulong sc_p2;
+ abi_ulong sc_p3;
+ abi_ulong sc_p4;
+ abi_ulong sc_p5;
+ abi_ulong sc_usp;
+ abi_ulong sc_a0w;
+ abi_ulong sc_a1w;
+ abi_ulong sc_a0x;
+ abi_ulong sc_a1x;
+ abi_ulong sc_astat;
+ abi_ulong sc_rets;
+ abi_ulong sc_pc;
+ abi_ulong sc_retx;
+ abi_ulong sc_fp;
+ abi_ulong sc_i0;
+ abi_ulong sc_i1;
+ abi_ulong sc_i2;
+ abi_ulong sc_i3;
+ abi_ulong sc_m0;
+ abi_ulong sc_m1;
+ abi_ulong sc_m2;
+ abi_ulong sc_m3;
+ abi_ulong sc_l0;
+ abi_ulong sc_l1;
+ abi_ulong sc_l2;
+ abi_ulong sc_l3;
+ abi_ulong sc_b0;
+ abi_ulong sc_b1;
+ abi_ulong sc_b2;
+ abi_ulong sc_b3;
+ abi_ulong sc_lc0;
+ abi_ulong sc_lc1;
+ abi_ulong sc_lt0;
+ abi_ulong sc_lt1;
+ abi_ulong sc_lb0;
+ abi_ulong sc_lb1;
+ abi_ulong sc_seqstat;
+};
+
+#endif
diff --git a/linux-user/bfin/target_signal.h b/linux-user/bfin/target_signal.h
new file mode 100644
index 0000000..7367c0a
--- /dev/null
+++ b/linux-user/bfin/target_signal.h
@@ -0,0 +1,31 @@
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+ abi_ulong ss_sp;
+ abi_long ss_flags;
+ abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK 1
+#define TARGET_SS_DISABLE 2
+
+#define TARGET_MINSIGSTKSZ 2048
+#define TARGET_SIGSTKSZ 8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUArchState *env)
+{
+ return env->spreg;
+}
+
+#define TARGET_SIGRETURN_STUB 0x400
+
+#endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/bfin/termbits.h b/linux-user/bfin/termbits.h
new file mode 100644
index 0000000..5c5fa01
--- /dev/null
+++ b/linux-user/bfin/termbits.h
@@ -0,0 +1,227 @@
+/* from asm/termbits.h */
+/* NOTE: exactly the same as i386 */
+
+#define TARGET_NCCS 19
+
+struct target_termios {
+ uint32_t c_iflag; /* input mode flags */
+ uint32_t c_oflag; /* output mode flags */
+ uint32_t c_cflag; /* control mode flags */
+ uint32_t c_lflag; /* local mode flags */
+ uint8_t c_line; /* line discipline */
+ uint8_t c_cc[TARGET_NCCS]; /* control characters */
+};
+
+/* c_iflag bits */
+#define TARGET_IGNBRK 0000001
+#define TARGET_BRKINT 0000002
+#define TARGET_IGNPAR 0000004
+#define TARGET_PARMRK 0000010
+#define TARGET_INPCK 0000020
+#define TARGET_ISTRIP 0000040
+#define TARGET_INLCR 0000100
+#define TARGET_IGNCR 0000200
+#define TARGET_ICRNL 0000400
+#define TARGET_IUCLC 0001000
+#define TARGET_IXON 0002000
+#define TARGET_IXANY 0004000
+#define TARGET_IXOFF 0010000
+#define TARGET_IMAXBEL 0020000
+#define TARGET_IUTF8 0040000
+
+/* c_oflag bits */
+#define TARGET_OPOST 0000001
+#define TARGET_OLCUC 0000002
+#define TARGET_ONLCR 0000004
+#define TARGET_OCRNL 0000010
+#define TARGET_ONOCR 0000020
+#define TARGET_ONLRET 0000040
+#define TARGET_OFILL 0000100
+#define TARGET_OFDEL 0000200
+#define TARGET_NLDLY 0000400
+#define TARGET_NL0 0000000
+#define TARGET_NL1 0000400
+#define TARGET_CRDLY 0003000
+#define TARGET_CR0 0000000
+#define TARGET_CR1 0001000
+#define TARGET_CR2 0002000
+#define TARGET_CR3 0003000
+#define TARGET_TABDLY 0014000
+#define TARGET_TAB0 0000000
+#define TARGET_TAB1 0004000
+#define TARGET_TAB2 0010000
+#define TARGET_TAB3 0014000
+#define TARGET_XTABS 0014000
+#define TARGET_BSDLY 0020000
+#define TARGET_BS0 0000000
+#define TARGET_BS1 0020000
+#define TARGET_VTDLY 0040000
+#define TARGET_VT0 0000000
+#define TARGET_VT1 0040000
+#define TARGET_FFDLY 0100000
+#define TARGET_FF0 0000000
+#define TARGET_FF1 0100000
+
+/* c_cflag bit meaning */
+#define TARGET_CBAUD 0010017
+#define TARGET_B0 0000000 /* hang up */
+#define TARGET_B50 0000001
+#define TARGET_B75 0000002
+#define TARGET_B110 0000003
+#define TARGET_B134 0000004
+#define TARGET_B150 0000005
+#define TARGET_B200 0000006
+#define TARGET_B300 0000007
+#define TARGET_B600 0000010
+#define TARGET_B1200 0000011
+#define TARGET_B1800 0000012
+#define TARGET_B2400 0000013
+#define TARGET_B4800 0000014
+#define TARGET_B9600 0000015
+#define TARGET_B19200 0000016
+#define TARGET_B38400 0000017
+#define TARGET_EXTA B19200
+#define TARGET_EXTB B38400
+#define TARGET_CSIZE 0000060
+#define TARGET_CS5 0000000
+#define TARGET_CS6 0000020
+#define TARGET_CS7 0000040
+#define TARGET_CS8 0000060
+#define TARGET_CSTOPB 0000100
+#define TARGET_CREAD 0000200
+#define TARGET_PARENB 0000400
+#define TARGET_PARODD 0001000
+#define TARGET_HUPCL 0002000
+#define TARGET_CLOCAL 0004000
+#define TARGET_CBAUDEX 0010000
+#define TARGET_B57600 0010001
+#define TARGET_B115200 0010002
+#define TARGET_B230400 0010003
+#define TARGET_B460800 0010004
+#define TARGET_B500000 0010005
+#define TARGET_B576000 0010006
+#define TARGET_B921600 0010007
+#define TARGET_B1000000 0010010
+#define TARGET_B1152000 0010011
+#define TARGET_B1500000 0010012
+#define TARGET_B2000000 0010013
+#define TARGET_B2500000 0010014
+#define TARGET_B3000000 0010015
+#define TARGET_B3500000 0010016
+#define TARGET_B4000000 0010017
+#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */
+#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */
+#define TARGET_CRTSCTS 020000000000 /* flow control */
+
+/* c_lflag bits */
+#define TARGET_ISIG 0000001
+#define TARGET_ICANON 0000002
+#define TARGET_XCASE 0000004
+#define TARGET_ECHO 0000010
+#define TARGET_ECHOE 0000020
+#define TARGET_ECHOK 0000040
+#define TARGET_ECHONL 0000100
+#define TARGET_NOFLSH 0000200
+#define TARGET_TOSTOP 0000400
+#define TARGET_ECHOCTL 0001000
+#define TARGET_ECHOPRT 0002000
+#define TARGET_ECHOKE 0004000
+#define TARGET_FLUSHO 0010000
+#define TARGET_PENDIN 0040000
+#define TARGET_IEXTEN 0100000
+
+/* c_cc character offsets */
+#define TARGET_VINTR 0
+#define TARGET_VQUIT 1
+#define TARGET_VERASE 2
+#define TARGET_VKILL 3
+#define TARGET_VEOF 4
+#define TARGET_VTIME 5
+#define TARGET_VMIN 6
+#define TARGET_VSWTC 7
+#define TARGET_VSTART 8
+#define TARGET_VSTOP 9
+#define TARGET_VSUSP 10
+#define TARGET_VEOL 11
+#define TARGET_VREPRINT 12
+#define TARGET_VDISCARD 13
+#define TARGET_VWERASE 14
+#define TARGET_VLNEXT 15
+#define TARGET_VEOL2 16
+
+/* ioctls */
+
+#define TARGET_TCGETS 0x5401
+#define TARGET_TCSETS 0x5402
+#define TARGET_TCSETSW 0x5403
+#define TARGET_TCSETSF 0x5404
+#define TARGET_TCGETA 0x5405
+#define TARGET_TCSETA 0x5406
+#define TARGET_TCSETAW 0x5407
+#define TARGET_TCSETAF 0x5408
+#define TARGET_TCSBRK 0x5409
+#define TARGET_TCXONC 0x540A
+#define TARGET_TCFLSH 0x540B
+
+#define TARGET_TIOCEXCL 0x540C
+#define TARGET_TIOCNXCL 0x540D
+#define TARGET_TIOCSCTTY 0x540E
+#define TARGET_TIOCGPGRP 0x540F
+#define TARGET_TIOCSPGRP 0x5410
+#define TARGET_TIOCOUTQ 0x5411
+#define TARGET_TIOCSTI 0x5412
+#define TARGET_TIOCGWINSZ 0x5413
+#define TARGET_TIOCSWINSZ 0x5414
+#define TARGET_TIOCMGET 0x5415
+#define TARGET_TIOCMBIS 0x5416
+#define TARGET_TIOCMBIC 0x5417
+#define TARGET_TIOCMSET 0x5418
+#define TARGET_TIOCGSOFTCAR 0x5419
+#define TARGET_TIOCSSOFTCAR 0x541A
+#define TARGET_FIONREAD 0x541B
+#define TARGET_TIOCINQ TARGET_FIONREAD
+#define TARGET_TIOCLINUX 0x541C
+#define TARGET_TIOCCONS 0x541D
+#define TARGET_TIOCGSERIAL 0x541E
+#define TARGET_TIOCSSERIAL 0x541F
+#define TARGET_TIOCPKT 0x5420
+#define TARGET_FIONBIO 0x5421
+#define TARGET_TIOCNOTTY 0x5422
+#define TARGET_TIOCSETD 0x5423
+#define TARGET_TIOCGETD 0x5424
+#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
+#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
+#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, uint32_t) /* Get Pty Number (of pty-mux device) */
+#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int32_t) /* Lock/unlock Pty */
+
+#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */
+#define TARGET_FIOCLEX 0x5451
+#define TARGET_FIOASYNC 0x5452
+#define TARGET_TIOCSERCONFIG 0x5453
+#define TARGET_TIOCSERGWILD 0x5454
+#define TARGET_TIOCSERSWILD 0x5455
+#define TARGET_TIOCGLCKTRMIOS 0x5456
+#define TARGET_TIOCSLCKTRMIOS 0x5457
+#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
+#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
+
+/* Used for packet mode */
+#define TARGET_TIOCPKT_DATA 0
+#define TARGET_TIOCPKT_FLUSHREAD 1
+#define TARGET_TIOCPKT_FLUSHWRITE 2
+#define TARGET_TIOCPKT_STOP 4
+#define TARGET_TIOCPKT_START 8
+#define TARGET_TIOCPKT_NOSTOP 16
+#define TARGET_TIOCPKT_DOSTOP 32
+
+#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ddef23e..b09e33e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -979,6 +979,48 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUM68KState *e
#endif
+#ifdef TARGET_BFIN
+
+#define ELF_START_MMAP 0x00000000
+
+#define elf_check_arch(x) ( (x) == EM_BLACKFIN )
+#define elf_is_fdpic(e) ( (e)->e_flags & EF_BFIN_FDPIC )
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_BLACKFIN
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+ if (infop->personality == PER_LINUX_FDPIC) {
+ if (infop->other_info) {
+ /* dynamic */
+ regs->p0 = tswapl(infop->loadmap_addr);
+ regs->p1 = tswapl(infop->other_info->loadmap_addr);
+ regs->p2 = tswapl(infop->other_info->pt_dynamic_addr);
+ } else {
+ /* static */
+ regs->p0 = tswapl(infop->loadmap_addr);
+ regs->p1 = 0;
+ regs->p2 = tswapl(infop->pt_dynamic_addr);
+ }
+ regs->r7 = 0;
+ } else if (infop->start_code == 0) {
+ /* Must be bare metal ELF ... */
+ infop->personality = PER_MASK;
+ }
+ regs->pc = tswapl(infop->entry);
+ regs->usp = tswapl(infop->start_stack);
+}
+
+#define ELF_EXEC_PAGESIZE 4096
+
+/* See linux kernel: arch/blackfin/include/asm/elf.h. */
+#define ELF_NREG 40
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+#endif
+
#ifdef TARGET_ALPHA
#define ELF_START_MMAP (0x30000000000ULL)
@@ -1677,6 +1719,11 @@ static void load_elf_image(const char *image_name, int image_fd,
address does not conflict with MMAP_MIN_ADDR or the
QEMU application itself. */
probe_guest_base(image_name, loaddr, hiaddr);
+#ifdef TARGET_BFIN
+ /* Make space for the fixed code region */
+ if (elf_is_fdpic(ehdr) && load_addr < 0x1000)
+ load_addr += 0x1000;
+#endif
}
load_bias = load_addr - loaddr;
diff --git a/linux-user/main.c b/linux-user/main.c
index b97b8cf..bb5d032 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2795,6 +2795,115 @@ void cpu_loop(CPUM68KState *env)
}
#endif /* TARGET_M68K */
+#ifdef TARGET_BFIN
+
+#include "disas/disas.h"
+
+void cpu_loop(CPUArchState *env)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+ int trapnr, gdbsig;
+ target_siginfo_t info;
+
+ for (;;) {
+ cpu_exec_start(cs);
+ trapnr = cpu_exec(env);
+ cpu_exec_end(cs);
+ gdbsig = 0;
+
+ switch (trapnr) {
+ case EXCP_SYSCALL:
+ env->pc += 2;
+ env->dreg[0] = do_syscall(env,
+ env->preg[0],
+ env->dreg[0],
+ env->dreg[1],
+ env->dreg[2],
+ env->dreg[3],
+ env->dreg[4],
+ env->dreg[5], 0, 0);
+ break;
+ case EXCP_INTERRUPT:
+ /* just indicate that signals should be handled asap */
+ break;
+ case EXCP_DEBUG:
+ /* XXX: does this handle hwloops ? */
+ /*env->pc += 2;*/
+ /* EMUEXCPT signals debugger only if attached; NOP otherwise */
+ gdbsig = TARGET_SIGTRAP;
+ break;
+ case EXCP_SOFT_BP:
+ {
+ int sig = gdb_handlesig(env, TARGET_SIGTRAP);
+ if (sig) {
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = TARGET_TRAP_BRKPT;
+ queue_signal(env, info.si_signo, &info);
+ }
+ }
+ break;
+ case EXCP_HLT:
+ do_syscall(env, TARGET_NR_exit, 0, 0, 0, 0, 0, 0, 0, 0);
+ break;
+ case EXCP_ABORT:
+ do_syscall(env, TARGET_NR_exit, 1, 0, 0, 0, 0, 0, 0, 0);
+ break;
+ case EXCP_DBGA:
+ fprintf(stderr, "qemu: DBGA failed\n");
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGABRT;
+ break;
+ case EXCP_UNDEF_INST:
+ fprintf(stderr, "qemu: unhandled insn @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ gdbsig = TARGET_SIGILL;
+ break;
+ case EXCP_DCPLB_VIOLATE:
+ fprintf(stderr, "qemu: memory violation @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGSEGV;
+ break;
+ case EXCP_ILL_SUPV:
+ fprintf(stderr, "qemu: supervisor mode required @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ gdbsig = TARGET_SIGILL;
+ break;
+ case EXCP_MISALIG_INST:
+ fprintf(stderr, "qemu: unaligned insn fetch @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGSEGV;
+ break;
+ case EXCP_DATA_MISALGIN:
+ fprintf(stderr, "qemu: unaligned data fetch @ %#x\n", env->pc);
+ log_target_disas(env, env->pc, 8, 0);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGSEGV;
+ break;
+ default:
+ fprintf(stderr, "qemu: unhandled CPU exception %#x - aborting\n",
+ trapnr);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ gdbsig = TARGET_SIGILL;
+ break;
+ }
+
+ if (gdbsig) {
+ gdb_handlesig(env, gdbsig);
+ /* XXX: should we let people continue if gdb handles the signal ? */
+ if (gdbsig != TARGET_SIGTRAP) {
+ exit(1);
+ }
+ }
+
+ process_pending_signals(env);
+ }
+}
+
+#endif
+
#ifdef TARGET_ALPHA
static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
{
@@ -4013,6 +4122,57 @@ int main(int argc, char **argv, char **envp)
}
env->pc = regs->pc;
}
+#elif defined(TARGET_BFIN)
+ {
+ env->personality = info->personality;
+ env->dreg[0] = regs->r0;
+ env->dreg[1] = regs->r1;
+ env->dreg[2] = regs->r2;
+ env->dreg[3] = regs->r3;
+ env->dreg[4] = regs->r4;
+ env->dreg[5] = regs->r5;
+ env->dreg[6] = regs->r6;
+ env->dreg[7] = regs->r7;
+ env->preg[0] = regs->p0;
+ env->preg[1] = regs->p1;
+ env->preg[2] = regs->p2;
+ env->preg[3] = regs->p3;
+ env->preg[4] = regs->p4;
+ env->preg[5] = regs->p5;
+ env->spreg = regs->usp;
+ env->fpreg = regs->fp;
+ env->uspreg = regs->usp;
+ env->breg[0] = regs->b0;
+ env->breg[1] = regs->b1;
+ env->breg[2] = regs->b2;
+ env->breg[3] = regs->b3;
+ env->lreg[0] = regs->l0;
+ env->lreg[1] = regs->l1;
+ env->lreg[2] = regs->l2;
+ env->lreg[3] = regs->l3;
+ env->mreg[0] = regs->m0;
+ env->mreg[1] = regs->m1;
+ env->mreg[2] = regs->m2;
+ env->mreg[3] = regs->m3;
+ env->ireg[0] = regs->i0;
+ env->ireg[1] = regs->i1;
+ env->ireg[2] = regs->i2;
+ env->ireg[3] = regs->i3;
+ env->lcreg[0] = regs->lc0;
+ env->ltreg[0] = regs->lt0;
+ env->lbreg[0] = regs->lb0;
+ env->lcreg[1] = regs->lc1;
+ env->ltreg[1] = regs->lt1;
+ env->lbreg[1] = regs->lb1;
+ env->areg[0] = ((uint64_t)regs->a0x << 32) | regs->a0w;
+ env->areg[1] = ((uint64_t)regs->a1x << 32) | regs->a1w;
+ env->rets = regs->rets;
+ env->rete = regs->rete;
+ env->retn = regs->retn;
+ env->retx = regs->retx;
+ env->pc = regs->pc;
+ bfin_astat_write(env, regs->astat);
+ }
#elif defined(TARGET_ALPHA)
{
int i;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index b10e957..819f268 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -26,6 +26,10 @@
#define THREAD
#endif
+#ifdef TARGET_BFIN
+#define CONFIG_USE_FDPIC
+#endif
+
/* This struct is used to hold certain information about the image.
* Basically, it replicates in user space what would be certain
* task_struct fields in the kernel
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 5da8452..6e2d613 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5353,6 +5353,231 @@ long do_rt_sigreturn(CPUAlphaState *env)
force_sig(TARGET_SIGSEGV);
}
+#elif defined(TARGET_BFIN)
+
+#include "target_sigcontext.h"
+#include "target_ucontext.h"
+
+struct target_rt_sigframe {
+ int32_t sig;
+ abi_ulong pinfo;
+ abi_ulong puc;
+ /* This is no longer needed by the kernel, but unfortunately userspace
+ * code expects it to be there. */
+ char retcode[8];
+ target_siginfo_t info;
+ struct target_ucontext uc;
+};
+
+struct fdpic_func_descriptor {
+ abi_ulong text;
+ abi_ulong GOT;
+};
+
+#define rreg dreg
+
+static inline int
+target_rt_restore_sigcontext(CPUArchState *env, struct target_sigcontext *sc, long *ret)
+{
+ uint32_t reg;
+ int err = 0;
+
+#define RESTORE2(e, x) err |= __get_user(env->e, &sc->sc_##x)
+#define RESTOREA(r, i) RESTORE2(r##reg[i], r##i)
+#define RESTORE(x) RESTORE2(x, x)
+
+ /* restore passed registers */
+ RESTOREA(r, 0); RESTOREA(r, 1); RESTOREA(r, 2); RESTOREA(r, 3);
+ RESTOREA(r, 4); RESTOREA(r, 5); RESTOREA(r, 6); RESTOREA(r, 7);
+ RESTOREA(p, 0); RESTOREA(p, 1); RESTOREA(p, 2); RESTOREA(p, 3);
+ RESTOREA(p, 4); RESTOREA(p, 5);
+ RESTORE2(spreg, usp);
+ err |= __get_user(reg, &sc->sc_a0x);
+ env->areg[0] = reg;
+ err |= __get_user(reg, &sc->sc_a0w);
+ env->areg[0] = (env->areg[0] << 32) | reg;
+ err |= __get_user(reg, &sc->sc_a1x);
+ env->areg[1] = reg;
+ err |= __get_user(reg, &sc->sc_a1w);
+ env->areg[1] = (env->areg[1] << 32) | reg;
+ err |= __get_user(reg, &sc->sc_astat);
+ bfin_astat_write(env, reg);
+ RESTORE(rets);
+ RESTORE(pc);
+ RESTORE(retx);
+ RESTORE2(fpreg, fp);
+ RESTOREA(i, 0); RESTOREA(i, 1); RESTOREA(i, 2); RESTOREA(i, 3);
+ RESTOREA(m, 0); RESTOREA(m, 1); RESTOREA(m, 2); RESTOREA(m, 3);
+ RESTOREA(l, 0); RESTOREA(l, 1); RESTOREA(l, 2); RESTOREA(l, 3);
+ RESTOREA(b, 0); RESTOREA(b, 1); RESTOREA(b, 2); RESTOREA(b, 3);
+ RESTOREA(lc, 0); RESTOREA(lc, 1);
+ RESTOREA(lt, 0); RESTOREA(lt, 1);
+ RESTOREA(lb, 0); RESTOREA(lb, 1);
+ RESTORE(seqstat);
+
+ *ret = env->dreg[0];
+ return err;
+}
+
+static inline int
+target_rt_setup_sigcontext(struct target_sigcontext *sc, CPUArchState *env)
+{
+ int err = 0;
+
+#define SETUP2(e, x) err |= __put_user(env->e, &sc->sc_##x)
+#define SETUPA(r, i) SETUP2(r##reg[i], r##i)
+#define SETUP(x) SETUP2(x, x)
+
+ SETUPA(r, 0); SETUPA(r, 1); SETUPA(r, 2); SETUPA(r, 3);
+ SETUPA(r, 4); SETUPA(r, 5); SETUPA(r, 6); SETUPA(r, 7);
+ SETUPA(p, 0); SETUPA(p, 1); SETUPA(p, 2); SETUPA(p, 3);
+ SETUPA(p, 4); SETUPA(p, 5);
+ SETUP2(spreg, usp);
+ err |= __put_user((uint32_t)env->areg[0], &sc->sc_a0w);
+ err |= __put_user((uint32_t)env->areg[1], &sc->sc_a1w);
+ err |= __put_user((uint32_t)(env->areg[0] >> 32), &sc->sc_a0x);
+ err |= __put_user((uint32_t)(env->areg[1] >> 32), &sc->sc_a1x);
+ err |= __put_user(bfin_astat_read(env), &sc->sc_astat);
+ SETUP(rets);
+ SETUP(pc);
+ SETUP(retx);
+ SETUP2(fpreg, fp);
+ SETUPA(i, 0); SETUPA(i, 1); SETUPA(i, 2); SETUPA(i, 3);
+ SETUPA(m, 0); SETUPA(m, 1); SETUPA(m, 2); SETUPA(m, 3);
+ SETUPA(l, 0); SETUPA(l, 1); SETUPA(l, 2); SETUPA(l, 3);
+ SETUPA(b, 0); SETUPA(b, 1); SETUPA(b, 2); SETUPA(b, 3);
+ SETUPA(lc, 0); SETUPA(lc, 1);
+ SETUPA(lt, 0); SETUPA(lt, 1);
+ SETUPA(lb, 0); SETUPA(lb, 1);
+ SETUP(seqstat);
+
+ return err;
+}
+
+#undef rreg
+
+static inline abi_ulong
+get_sigframe(struct target_sigaction *ka, CPUArchState *env, size_t frame_size)
+{
+ abi_ulong usp;
+
+ /* Default to using normal stack. */
+ usp = env->spreg;
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(usp) == 0)) {
+ usp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ }
+
+ return ((usp - frame_size) & -8UL);
+}
+
+static void setup_rt_frame(int sig, struct target_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPUArchState *env)
+{
+ struct target_rt_sigframe *frame;
+ abi_ulong frame_addr;
+ abi_ulong info_addr;
+ abi_ulong uc_addr;
+ int err = 0;
+ int i;
+
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+ goto give_sigsegv;
+
+ err |= __put_user(sig, &frame->sig);
+
+ info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
+ err |= __put_user(info_addr, &frame->pinfo);
+ uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
+ err |= __put_user(uc_addr, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.tuc_flags);
+ err |= __put_user(0, &frame->uc.tuc_link);
+ err |= __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(env->spreg), &frame->uc.tuc_stack.ss_flags);
+ err |= __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
+ err |= target_rt_setup_sigcontext(&frame->uc.tuc_mcontext, env);
+
+ for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+ if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
+ goto give_sigsegv;
+ }
+
+ if (err)
+ goto give_sigsegv;
+
+ /* Set up registers for signal handler */
+ env->spreg = frame_addr;
+ if (env->personality & 0x0080000/*FDPIC_FUNCPTRS*/) {
+ struct fdpic_func_descriptor *funcptr;
+ if (!lock_user_struct(VERIFY_READ, funcptr, ka->_sa_handler, 1))
+ goto give_sigsegv;
+ __get_user(env->pc, &funcptr->text);
+ __get_user(env->preg[3], &funcptr->GOT);
+ unlock_user_struct(funcptr, ka->_sa_handler, 0);
+ } else
+ env->pc = ka->_sa_handler;
+ env->rets = TARGET_SIGRETURN_STUB;
+
+ env->dreg[0] = frame->sig;
+ env->dreg[1] = info_addr;
+ env->dreg[2] = uc_addr;
+
+ unlock_user_struct(frame, frame_addr, 1);
+ return;
+
+ give_sigsegv:
+ unlock_user_struct(frame, frame_addr, 1);
+ force_sig(TARGET_SIGSEGV);
+}
+
+static void setup_frame(int sig, struct target_sigaction *ka,
+ target_sigset_t *set, CPUArchState *env)
+{
+ target_siginfo_t info;
+ setup_rt_frame(sig, ka, &info, set, env);
+}
+
+long do_sigreturn(CPUArchState *env)
+{
+ fprintf(stderr, "do_sigreturn: not implemented\n");
+ return -TARGET_ENOSYS;
+}
+
+/* NB: This version should work for any arch ... */
+long do_rt_sigreturn(CPUArchState *env)
+{
+ long ret;
+ abi_ulong frame_addr = env->spreg;
+ struct target_rt_sigframe *frame;
+ sigset_t host_set;
+
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+ goto badframe;
+
+ target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
+ sigprocmask(SIG_SETMASK, &host_set, NULL);
+
+ if (target_rt_restore_sigcontext(env, &frame->uc.tuc_mcontext, &ret))
+ goto badframe;
+
+ if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
+ goto badframe;
+
+ unlock_user_struct(frame, frame_addr, 0);
+ return ret;
+
+ badframe:
+ unlock_user_struct(frame, frame_addr, 0);
+ force_sig(TARGET_SIGSEGV);
+ return 0;
+}
+
#else
static void setup_frame(int sig, struct target_sigaction *ka,
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cdd0c28..a9dce35 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7444,7 +7444,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_sigaltstack:
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
- defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC) || \
+ defined(TARGET_BFIN)
ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
break;
#else
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 92c01a9..362cd2d 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -63,7 +63,7 @@
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
|| defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_UNICORE32) \
- || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ || defined(TARGET_S390X) || defined(TARGET_OPENRISC) || defined(TARGET_BFIN)
#define TARGET_IOC_SIZEBITS 14
#define TARGET_IOC_DIRBITS 2
@@ -327,7 +327,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|| defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \
|| defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
|| defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \
- || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
+ || defined(TARGET_S390X) || defined(TARGET_OPENRISC) || defined(TARGET_BFIN)
#if defined(TARGET_SPARC)
#define TARGET_SA_NOCLDSTOP 8u
@@ -1689,6 +1689,67 @@ struct target_stat64 {
int64_t st_blocks;
};
+#elif defined(TARGET_BFIN)
+
+struct target_stat {
+ uint16_t st_dev;
+ uint16_t __pad1;
+ abi_ulong st_ino;
+ uint16_t st_mode;
+ uint16_t st_nlink;
+ uint16_t st_uid;
+ uint16_t st_gid;
+ uint16_t st_rdev;
+ uint16_t __pad2;
+ abi_ulong st_size;
+ abi_ulong st_blksize;
+ abi_ulong st_blocks;
+ abi_ulong target_st_atime;
+ abi_ulong __unused1;
+ abi_ulong target_st_mtime;
+ abi_ulong __unused2;
+ abi_ulong target_st_ctime;
+ abi_ulong __unused3;
+ abi_ulong __unused4;
+ abi_ulong __unused5;
+} __attribute__((packed));
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct target_stat64 {
+ uint64_t st_dev;
+ unsigned char __pad1[4];
+
+#define STAT64_HAS_BROKEN_ST_INO 1
+ abi_ulong __st_ino;
+
+ uint32_t st_mode;
+ uint32_t st_nlink;
+
+ abi_ulong st_uid;
+ abi_ulong st_gid;
+
+ uint64_t st_rdev;
+ unsigned char __pad2[4];
+
+ int64_t st_size;
+ abi_ulong st_blksize;
+
+ int64_t st_blocks; /* Number 512-byte blocks allocated. */
+
+ abi_ulong target_st_atime;
+ abi_ulong target_st_atime_nsec;
+
+ abi_ulong target_st_mtime;
+ abi_ulong target_st_mtime_nsec;
+
+ abi_ulong target_st_ctime;
+ abi_ulong target_st_ctime_nsec;
+
+ uint64_t st_ino;
+} __attribute__((packed));
+
#elif defined(TARGET_ALPHA)
struct target_stat {
diff --git a/linux-user/target_ucontext.h b/linux-user/target_ucontext.h
new file mode 100644
index 0000000..49706b4
--- /dev/null
+++ b/linux-user/target_ucontext.h
@@ -0,0 +1,14 @@
+/* This is the asm-generic/ucontext.h version */
+
+#ifndef TARGET_UCONTEXT_H
+#define TARGET_UCONTEXT_H
+
+struct target_ucontext {
+ abi_ulong tuc_flags;
+ abi_ulong tuc_link;
+ target_stack_t tuc_stack;
+ struct target_sigcontext tuc_mcontext;
+ target_sigset_t tuc_sigmask; /* mask last for extensibility */
+};
+
+#endif
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 4/5] Blackfin: add test suite
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support Mike Frysinger
@ 2013-06-17 7:16 ` Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 5/5] linux-user: add support for Blackfin syscalls Mike Frysinger
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2013-06-17 7:16 UTC (permalink / raw)
To: qemu-devel
To run it, simply add the bfin-elf compiler to your PATH and do:
make -C tests/tcg/bfin
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
Deleted test content due to size (~2 MiB). It's all just Blackfin
assembly at any rate.
Code can be found here:
git://sources.blackfin.uclinux.org/git/users/vapier/qemu.git
http://blackfin.uclinux.org/git/?p=users/vapier/qemu.git
tests/tcg/Makefile | 4 +
tests/tcg/bfin/.gitignore | 2 +
tests/tcg/bfin/10272_small.s | 51 ++
tests/tcg/bfin/10436.s | 39 +
tests/tcg/bfin/10622.s | 21 +
tests/tcg/bfin/10742.s | 17 +
tests/tcg/bfin/10799.s | 55 ++
tests/tcg/bfin/7641.s | 38 +
tests/tcg/bfin/Makefile | 80 ++
tests/tcg/bfin/a0.s | 17 +
tests/tcg/bfin/a1.s | 29 +
tests/tcg/bfin/a10.s | 163 ++++
tests/tcg/bfin/a2.s | 179 ++++
tests/tcg/bfin/a24.s | 12 +
tests/tcg/bfin/a25.s | 28 +
tests/tcg/bfin/a26.s | 72 ++
tests/tcg/bfin/a3.s | 313 +++++++
tests/tcg/bfin/a4.s | 36 +
tests/tcg/bfin/a7.s | 179 ++++
tests/tcg/bfin/a8.s | 41 +
tests/tcg/bfin/a9.s | 205 +++++
tests/tcg/bfin/abs-2.S | 42 +
tests/tcg/bfin/abs-3.S | 42 +
tests/tcg/bfin/abs.S | 42 +
tests/tcg/bfin/acc-rot.s | 129 +++
tests/tcg/bfin/acp5_19.s | 12 +
tests/tcg/bfin/add_imm7.s | 38 +
tests/tcg/bfin/algnbug1.s | 38 +
tests/tcg/bfin/algnbug2.s | 69 ++
tests/tcg/bfin/b0.S | 51 ++
tests/tcg/bfin/b1.s | 12 +
tests/tcg/bfin/b2.S | 26 +
tests/tcg/bfin/brcc.s | 164 ++++
tests/tcg/bfin/brevadd.s | 20 +
tests/tcg/bfin/byteunpack.s | 45 +
tests/tcg/bfin/c_alu2op_arith_r_sft.s | 226 +++++
tests/tcg/bfin/c_alu2op_conv_b.s | 211 +++++
tests/tcg/bfin/c_alu2op_conv_h.s | 211 +++++
tests/tcg/bfin/c_alu2op_conv_mix.s | 186 ++++
tests/tcg/bfin/c_alu2op_conv_neg.s | 211 +++++
tests/tcg/bfin/c_alu2op_conv_toggle.s | 211 +++++
tests/tcg/bfin/c_alu2op_conv_xb.s | 211 +++++
tests/tcg/bfin/c_alu2op_conv_xh.s | 212 +++++
tests/tcg/bfin/c_alu2op_divq.s | 220 +++++
tests/tcg/bfin/c_alu2op_divs.s | 220 +++++
tests/tcg/bfin/c_alu2op_log_l_sft.s | 220 +++++
tests/tcg/bfin/c_alu2op_log_r_sft.s | 217 +++++
tests/tcg/bfin/c_alu2op_shadd_1.s | 209 +++++
tests/tcg/bfin/c_alu2op_shadd_2.s | 209 +++++
tests/tcg/bfin/c_br_preg_killed_ac.s | 82 ++
tests/tcg/bfin/c_br_preg_killed_ex1.s | 85 ++
tests/tcg/bfin/c_br_preg_stall_ac.s | 75 ++
tests/tcg/bfin/c_br_preg_stall_ex1.s | 70 ++
tests/tcg/bfin/c_brcc_bp1.s | 45 +
tests/tcg/bfin/c_brcc_bp2.s | 45 +
tests/tcg/bfin/c_brcc_bp3.s | 47 +
tests/tcg/bfin/c_brcc_bp4.s | 46 +
tests/tcg/bfin/c_brcc_brf_bp.s | 46 +
tests/tcg/bfin/c_brcc_brf_brt_bp.s | 47 +
tests/tcg/bfin/c_brcc_brf_brt_nbp.s | 46 +
tests/tcg/bfin/c_brcc_brf_fbkwd.s | 46 +
tests/tcg/bfin/c_brcc_brf_nbp.s | 45 +
tests/tcg/bfin/c_brcc_brt_bp.s | 46 +
tests/tcg/bfin/c_brcc_brt_nbp.s | 45 +
tests/tcg/bfin/c_calla_ljump.s | 31 +
tests/tcg/bfin/c_calla_subr.s | 28 +
tests/tcg/bfin/c_cc2dreg.s | 56 ++
tests/tcg/bfin/c_cc2stat_cc_ac.S | 240 +++++
tests/tcg/bfin/c_cc2stat_cc_an.s | 243 +++++
tests/tcg/bfin/c_cc2stat_cc_aq.s | 243 +++++
tests/tcg/bfin/c_cc2stat_cc_av0.S | 241 +++++
tests/tcg/bfin/c_cc2stat_cc_av1.S | 240 +++++
tests/tcg/bfin/c_cc2stat_cc_az.s | 243 +++++
tests/tcg/bfin/c_cc_flag_ccmv_depend.S | 82 ++
tests/tcg/bfin/c_cc_flagdreg_mvbrsft.s | 87 ++
tests/tcg/bfin/c_cc_regmvlogi_mvbrsft.s | 83 ++
tests/tcg/bfin/c_ccflag_dr_dr.s | 299 ++++++
tests/tcg/bfin/c_ccflag_dr_dr_uu.s | 299 ++++++
tests/tcg/bfin/c_ccflag_dr_imm3.s | 224 +++++
tests/tcg/bfin/c_ccflag_dr_imm3_uu.s | 221 +++++
tests/tcg/bfin/c_ccflag_pr_imm3.s | 539 +++++++++++
tests/tcg/bfin/c_ccflag_pr_imm3_uu.s | 238 +++++
tests/tcg/bfin/c_ccflag_pr_pr.s | 262 ++++++
tests/tcg/bfin/c_ccflag_pr_pr_uu.s | 212 +++++
tests/tcg/bfin/c_ccmv_cc_dr_dr.s | 124 +++
tests/tcg/bfin/c_ccmv_cc_dr_pr.s | 61 ++
tests/tcg/bfin/c_ccmv_cc_pr_pr.s | 111 +++
tests/tcg/bfin/c_ccmv_ncc_dr_dr.s | 123 +++
tests/tcg/bfin/c_ccmv_ncc_dr_pr.s | 60 ++
tests/tcg/bfin/c_ccmv_ncc_pr_pr.s | 111 +++
tests/tcg/bfin/c_comp3op_dr_and_dr.s | 412 +++++++++
tests/tcg/bfin/c_comp3op_dr_minus_dr.s | 412 +++++++++
tests/tcg/bfin/c_comp3op_dr_mix.s | 237 +++++
tests/tcg/bfin/c_comp3op_dr_or_dr.s | 412 +++++++++
tests/tcg/bfin/c_comp3op_dr_plus_dr.s | 412 +++++++++
tests/tcg/bfin/c_comp3op_dr_xor_dr.s | 412 +++++++++
tests/tcg/bfin/c_comp3op_pr_plus_pr_sh1.s | 302 ++++++
tests/tcg/bfin/c_comp3op_pr_plus_pr_sh2.s | 302 ++++++
tests/tcg/bfin/c_compi2opd_dr_add_i7_n.s | 164 ++++
tests/tcg/bfin/c_compi2opd_dr_add_i7_p.s | 147 +++
tests/tcg/bfin/c_compi2opd_dr_eq_i7_n.s | 166 ++++
tests/tcg/bfin/c_compi2opd_dr_eq_i7_p.s | 147 +++
tests/tcg/bfin/c_compi2opd_flags.S | 600 ++++++++++++
tests/tcg/bfin/c_compi2opd_flags_2.S | 600 ++++++++++++
tests/tcg/bfin/c_compi2opp_pr_add_i7_n.s | 149 +++
tests/tcg/bfin/c_compi2opp_pr_add_i7_p.s | 116 +++
tests/tcg/bfin/c_compi2opp_pr_eq_i7_n.s | 161 ++++
tests/tcg/bfin/c_compi2opp_pr_eq_i7_p.s | 131 +++
tests/tcg/bfin/c_dagmodik_lnz_imgebl.s | 290 ++++++
tests/tcg/bfin/c_dagmodik_lnz_imltbl.s | 289 ++++++
tests/tcg/bfin/c_dagmodik_lz_inc_dec.s | 140 +++
tests/tcg/bfin/c_dagmodim_lnz_imgebl.s | 108 +++
tests/tcg/bfin/c_dagmodim_lnz_imltbl.s | 109 +++
tests/tcg/bfin/c_dagmodim_lz_inc_dec.s | 98 ++
tests/tcg/bfin/c_dsp32alu_a_neg_a.s | 34 +
tests/tcg/bfin/c_dsp32alu_aa_absabs.s | 35 +
tests/tcg/bfin/c_dsp32alu_aa_negneg.s | 35 +
tests/tcg/bfin/c_dsp32alu_abs.s | 62 ++
tests/tcg/bfin/c_dsp32alu_absabs.s | 62 ++
tests/tcg/bfin/c_dsp32alu_awx.s | 54 ++
tests/tcg/bfin/c_dsp32alu_bytepack.s | 77 ++
tests/tcg/bfin/c_dsp32alu_byteunpack.s | 113 +++
tests/tcg/bfin/c_dsp32alu_disalnexcpt.s | 255 ++++++
tests/tcg/bfin/c_dsp32alu_max.s | 261 ++++++
tests/tcg/bfin/c_dsp32alu_maxmax.s | 261 ++++++
tests/tcg/bfin/c_dsp32alu_min.s | 261 ++++++
tests/tcg/bfin/c_dsp32alu_minmin.s | 261 ++++++
tests/tcg/bfin/c_dsp32alu_rr_lph_a1a0.s | 33 +
tests/tcg/bfin/c_dsp32alu_search.s | 74 ++
tests/tcg/bfin/c_dsp32alu_sgn.s | 39 +
tests/tcg/bfin/c_dsp32mac_a1a0.s | 255 ++++++
tests/tcg/bfin/c_dsp32mac_pair_a0.s | 129 +++
tests/tcg/bfin/c_dsp32mac_pair_a0_i.s | 247 +++++
tests/tcg/bfin/c_dsp32mac_pair_a0_m.s | 129 +++
tests/tcg/bfin/c_dsp32mac_pair_a1.s | 127 +++
tests/tcg/bfin/c_dsp32mac_pair_a1_i.s | 243 +++++
tests/tcg/bfin/c_dsp32mac_pair_a1_m.s | 127 +++
tests/tcg/bfin/c_dsp32mult_pair_m.s | 178 ++++
tests/tcg/bfin/c_dsp32mult_pair_m_i.s | 178 ++++
tests/tcg/bfin/c_dsp32mult_pair_m_u.s | 178 ++++
tests/tcg/bfin/c_dsp32shift_a0alr.s | 77 ++
tests/tcg/bfin/c_dsp32shift_af.s | 186 ++++
tests/tcg/bfin/c_dsp32shift_ahalf_ln.s | 423 +++++++++
tests/tcg/bfin/c_dsp32shift_ahalf_lp.s | 423 +++++++++
tests/tcg/bfin/c_dsp32shift_ahalf_rn.s | 423 +++++++++
tests/tcg/bfin/c_dsp32shift_ahalf_rn_s.s | 424 +++++++++
tests/tcg/bfin/c_dsp32shift_ahalf_rp.s | 423 +++++++++
tests/tcg/bfin/c_dsp32shift_ahalf_rp_s.s | 423 +++++++++
tests/tcg/bfin/c_dsp32shift_align16.s | 210 +++++
tests/tcg/bfin/c_dsp32shift_align24.s | 210 +++++
tests/tcg/bfin/c_dsp32shift_align8.s | 210 +++++
tests/tcg/bfin/c_dsp32shift_fdepx.s | 210 +++++
tests/tcg/bfin/c_dsp32shift_fextx.s | 210 +++++
tests/tcg/bfin/c_dsp32shift_lf.s | 422 +++++++++
tests/tcg/bfin/c_dsp32shift_lhalf_ln.s | 422 +++++++++
tests/tcg/bfin/c_dsp32shift_lhalf_lp.s | 422 +++++++++
tests/tcg/bfin/c_dsp32shift_lhalf_rn.s | 425 +++++++++
tests/tcg/bfin/c_dsp32shift_lhalf_rp.s | 423 +++++++++
tests/tcg/bfin/c_dsp32shift_ones.s | 214 +++++
tests/tcg/bfin/c_dsp32shift_pack.s | 411 +++++++++
tests/tcg/bfin/c_dsp32shift_rot.s | 427 +++++++++
tests/tcg/bfin/c_dsp32shift_rot_mix.s | 375 ++++++++
tests/tcg/bfin/c_dsp32shift_signbits_r.s | 214 +++++
tests/tcg/bfin/c_dsp32shift_signbits_rh.s | 214 +++++
tests/tcg/bfin/c_dsp32shift_signbits_rl.s | 210 +++++
tests/tcg/bfin/c_dsp32shift_vmax.s | 113 +++
tests/tcg/bfin/c_dsp32shift_vmaxvmax.s | 113 +++
tests/tcg/bfin/c_dsp32shiftim_a0alr.s | 213 +++++
tests/tcg/bfin/c_dsp32shiftim_af.s | 63 ++
tests/tcg/bfin/c_dsp32shiftim_af_s.s | 37 +
tests/tcg/bfin/c_dsp32shiftim_ahalf_ln.s | 406 ++++++++
tests/tcg/bfin/c_dsp32shiftim_ahalf_lp.s | 418 +++++++++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rn.s | 418 +++++++++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rn_s.s | 418 +++++++++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rp.s | 420 +++++++++
tests/tcg/bfin/c_dsp32shiftim_ahalf_rp_s.s | 422 +++++++++
tests/tcg/bfin/c_dsp32shiftim_ahh.s | 65 ++
tests/tcg/bfin/c_dsp32shiftim_amix.s | 124 +++
tests/tcg/bfin/c_dsp32shiftim_lf.s | 63 ++
tests/tcg/bfin/c_dsp32shiftim_lhalf_ln.s | 401 ++++++++
tests/tcg/bfin/c_dsp32shiftim_lhalf_lp.s | 418 +++++++++
tests/tcg/bfin/c_dsp32shiftim_lhalf_rn.s | 424 +++++++++
tests/tcg/bfin/c_dsp32shiftim_lhalf_rp.s | 421 +++++++++
tests/tcg/bfin/c_dsp32shiftim_lhh.s | 65 ++
tests/tcg/bfin/c_dsp32shiftim_lmix.s | 138 +++
tests/tcg/bfin/c_dsp32shiftim_rot.s | 62 ++
tests/tcg/bfin/c_dspldst_ld_dr_i.s | 168 ++++
tests/tcg/bfin/c_dspldst_ld_dr_ipp.s | 348 +++++++
tests/tcg/bfin/c_dspldst_ld_dr_ippm.s | 328 +++++++
tests/tcg/bfin/c_dspldst_ld_drhi_i.s | 168 ++++
tests/tcg/bfin/c_dspldst_ld_drhi_ipp.s | 364 ++++++++
tests/tcg/bfin/c_dspldst_ld_drlo_i.s | 164 ++++
tests/tcg/bfin/c_dspldst_ld_drlo_ipp.s | 355 +++++++
tests/tcg/bfin/c_dspldst_st_dr_i.s | 185 ++++
tests/tcg/bfin/c_dspldst_st_dr_ipp.s | 326 +++++++
tests/tcg/bfin/c_dspldst_st_dr_ippm.s | 279 ++++++
tests/tcg/bfin/c_dspldst_st_drhi_i.s | 161 ++++
tests/tcg/bfin/c_dspldst_st_drhi_ipp.s | 355 +++++++
tests/tcg/bfin/c_dspldst_st_drlo_i.s | 163 ++++
tests/tcg/bfin/c_dspldst_st_drlo_ipp.s | 351 +++++++
tests/tcg/bfin/c_ldimmhalf_dreg.s | 60 ++
tests/tcg/bfin/c_ldimmhalf_drhi.s | 85 ++
tests/tcg/bfin/c_ldimmhalf_drlo.s | 89 ++
tests/tcg/bfin/c_ldimmhalf_h_dr.s | 82 ++
tests/tcg/bfin/c_ldimmhalf_h_ibml.s | 165 ++++
tests/tcg/bfin/c_ldimmhalf_h_pr.s | 74 ++
tests/tcg/bfin/c_ldimmhalf_l_dr.s | 82 ++
tests/tcg/bfin/c_ldimmhalf_l_ibml.s | 165 ++++
tests/tcg/bfin/c_ldimmhalf_l_pr.s | 76 ++
tests/tcg/bfin/c_ldimmhalf_lz_dr.s | 81 ++
tests/tcg/bfin/c_ldimmhalf_lz_ibml.s | 168 ++++
tests/tcg/bfin/c_ldimmhalf_lz_pr.s | 72 ++
tests/tcg/bfin/c_ldimmhalf_lzhi_dr.s | 113 +++
tests/tcg/bfin/c_ldimmhalf_lzhi_ibml.s | 216 +++++
tests/tcg/bfin/c_ldimmhalf_lzhi_pr.s | 102 +++
tests/tcg/bfin/c_ldimmhalf_pibml.s | 212 +++++
tests/tcg/bfin/c_ldst_ld_d_p.s | 372 ++++++++
tests/tcg/bfin/c_ldst_ld_d_p_b.s | 353 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_h.s | 351 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_mm.s | 417 +++++++++
tests/tcg/bfin/c_ldst_ld_d_p_mm_b.s | 353 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_mm_h.s | 330 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_mm_xb.s | 341 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_mm_xh.s | 355 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_pp.s | 371 ++++++++
tests/tcg/bfin/c_ldst_ld_d_p_pp_b.s | 324 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_pp_h.s | 350 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_pp_xb.s | 355 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_pp_xh.s | 333 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_ppmm_hbx.s | 656 +++++++++++++
tests/tcg/bfin/c_ldst_ld_d_p_xb.s | 326 +++++++
tests/tcg/bfin/c_ldst_ld_d_p_xh.s | 354 +++++++
tests/tcg/bfin/c_ldst_ld_p_p.s | 327 +++++++
tests/tcg/bfin/c_ldst_ld_p_p_mm.s | 406 ++++++++
tests/tcg/bfin/c_ldst_ld_p_p_pp.s | 335 +++++++
tests/tcg/bfin/c_ldst_st_p_d.s | 299 ++++++
tests/tcg/bfin/c_ldst_st_p_d_b.s | 300 ++++++
tests/tcg/bfin/c_ldst_st_p_d_h.s | 280 ++++++
tests/tcg/bfin/c_ldst_st_p_d_mm.s | 601 ++++++++++++
tests/tcg/bfin/c_ldst_st_p_d_mm_b.s | 498 ++++++++++
tests/tcg/bfin/c_ldst_st_p_d_mm_h.s | 554 +++++++++++
tests/tcg/bfin/c_ldst_st_p_d_pp.s | 804 ++++++++++++++++
tests/tcg/bfin/c_ldst_st_p_d_pp_b.s | 455 +++++++++
tests/tcg/bfin/c_ldst_st_p_d_pp_h.s | 457 +++++++++
tests/tcg/bfin/c_ldst_st_p_p.s | 128 +++
tests/tcg/bfin/c_ldst_st_p_p_mm.s | 428 +++++++++
tests/tcg/bfin/c_ldst_st_p_p_pp.s | 397 ++++++++
tests/tcg/bfin/c_ldstidxl_ld_dr_b.s | 554 +++++++++++
tests/tcg/bfin/c_ldstidxl_ld_dr_h.s | 595 ++++++++++++
tests/tcg/bfin/c_ldstidxl_ld_dr_xb.s | 594 ++++++++++++
tests/tcg/bfin/c_ldstidxl_ld_dr_xh.s | 595 ++++++++++++
tests/tcg/bfin/c_ldstidxl_ld_dreg.s | 554 +++++++++++
tests/tcg/bfin/c_ldstidxl_ld_preg.s | 672 ++++++++++++++
tests/tcg/bfin/c_ldstidxl_st_dr_b.s | 612 +++++++++++++
tests/tcg/bfin/c_ldstidxl_st_dr_h.s | 609 ++++++++++++
tests/tcg/bfin/c_ldstidxl_st_dreg.s | 780 ++++++++++++++++
tests/tcg/bfin/c_ldstidxl_st_preg.s | 709 ++++++++++++++
tests/tcg/bfin/c_ldstii_ld_dr_h.s | 541 +++++++++++
tests/tcg/bfin/c_ldstii_ld_dr_xh.s | 541 +++++++++++
tests/tcg/bfin/c_ldstii_ld_dreg.s | 540 +++++++++++
tests/tcg/bfin/c_ldstii_ld_preg.s | 564 ++++++++++++
tests/tcg/bfin/c_ldstii_st_dr_h.s | 605 ++++++++++++
tests/tcg/bfin/c_ldstii_st_dreg.s | 640 +++++++++++++
tests/tcg/bfin/c_ldstii_st_preg.s | 603 ++++++++++++
tests/tcg/bfin/c_ldstiifp_ld_dreg.s | 528 +++++++++++
tests/tcg/bfin/c_ldstiifp_ld_preg.s | 511 +++++++++++
tests/tcg/bfin/c_ldstiifp_st_dreg.s | 641 +++++++++++++
tests/tcg/bfin/c_ldstiifp_st_preg.s | 618 +++++++++++++
tests/tcg/bfin/c_ldstpmod_ld_dr_hi.s | 411 +++++++++
tests/tcg/bfin/c_ldstpmod_ld_dr_lo.s | 410 +++++++++
tests/tcg/bfin/c_ldstpmod_ld_dreg.s | 462 ++++++++++
tests/tcg/bfin/c_ldstpmod_ld_h_xh.s | 458 ++++++++++
tests/tcg/bfin/c_ldstpmod_ld_lohi.s | 462 ++++++++++
tests/tcg/bfin/c_ldstpmod_st_dr_hi.s | 400 ++++++++
tests/tcg/bfin/c_ldstpmod_st_dr_lo.s | 401 ++++++++
tests/tcg/bfin/c_ldstpmod_st_dreg.s | 623 +++++++++++++
tests/tcg/bfin/c_ldstpmod_st_lohi.s | 625 +++++++++++++
tests/tcg/bfin/c_linkage.s | 60 ++
tests/tcg/bfin/c_logi2op_alshft_mix.s | 143 +++
tests/tcg/bfin/c_logi2op_arith_shft.s | 223 +++++
tests/tcg/bfin/c_logi2op_bitclr.s | 92 ++
tests/tcg/bfin/c_logi2op_bitset.s | 92 ++
tests/tcg/bfin/c_logi2op_bittgl.s | 165 ++++
tests/tcg/bfin/c_logi2op_bittst.s | 583 ++++++++++++
tests/tcg/bfin/c_logi2op_log_l_shft.s | 222 +++++
tests/tcg/bfin/c_logi2op_log_l_shft_astat.S | 82 ++
tests/tcg/bfin/c_logi2op_log_r_shft.s | 222 +++++
tests/tcg/bfin/c_logi2op_log_r_shft_astat.S | 82 ++
tests/tcg/bfin/c_logi2op_nbittst.s | 584 ++++++++++++
tests/tcg/bfin/c_loopsetup_nested.s | 166 ++++
tests/tcg/bfin/c_loopsetup_nested_bot.s | 165 ++++
tests/tcg/bfin/c_loopsetup_nested_prelc.s | 184 ++++
tests/tcg/bfin/c_loopsetup_nested_top.s | 166 ++++
tests/tcg/bfin/c_loopsetup_overlap.s | 167 ++++
tests/tcg/bfin/c_loopsetup_preg_div2_lc0.s | 95 ++
tests/tcg/bfin/c_loopsetup_preg_div2_lc1.s | 94 ++
tests/tcg/bfin/c_loopsetup_preg_lc0.s | 95 ++
tests/tcg/bfin/c_loopsetup_preg_lc1.s | 93 ++
tests/tcg/bfin/c_loopsetup_prelc.s | 145 +++
tests/tcg/bfin/c_loopsetup_topbotcntr.s | 110 +++
tests/tcg/bfin/c_progctrl_call_pcpr.s | 63 ++
tests/tcg/bfin/c_progctrl_call_pr.s | 32 +
tests/tcg/bfin/c_progctrl_jump_pcpr.s | 58 ++
tests/tcg/bfin/c_progctrl_jump_pr.s | 56 ++
tests/tcg/bfin/c_progctrl_nop.s | 55 ++
tests/tcg/bfin/c_progctrl_rts.s | 36 +
tests/tcg/bfin/c_ptr2op_pr_neg_pr.s | 163 ++++
tests/tcg/bfin/c_ptr2op_pr_sft_2_1.s | 162 ++++
tests/tcg/bfin/c_ptr2op_pr_shadd_1_2.s | 167 ++++
tests/tcg/bfin/c_pushpopmultiple_dp.s | 213 +++++
tests/tcg/bfin/c_pushpopmultiple_dp_pair.s | 203 ++++
tests/tcg/bfin/c_pushpopmultiple_dreg.s | 173 ++++
tests/tcg/bfin/c_pushpopmultiple_preg.s | 83 ++
tests/tcg/bfin/c_regmv_acc_acc.s | 125 +++
tests/tcg/bfin/c_regmv_dag_lz_dep.s | 148 +++
tests/tcg/bfin/c_regmv_dr_acc_acc.s | 191 ++++
tests/tcg/bfin/c_regmv_dr_dep_nostall.s | 245 +++++
tests/tcg/bfin/c_regmv_dr_dr.s | 209 +++++
tests/tcg/bfin/c_regmv_dr_imlb.s | 539 +++++++++++
tests/tcg/bfin/c_regmv_dr_pr.s | 107 +++
tests/tcg/bfin/c_regmv_imlb_dep_nostall.s | 664 ++++++++++++++
tests/tcg/bfin/c_regmv_imlb_dep_stall.s | 335 +++++++
tests/tcg/bfin/c_regmv_imlb_dr.s | 313 +++++++
tests/tcg/bfin/c_regmv_imlb_imlb.s | 925 +++++++++++++++++++
tests/tcg/bfin/c_regmv_imlb_pr.s | 302 ++++++
tests/tcg/bfin/c_regmv_pr_dep_nostall.s | 280 ++++++
tests/tcg/bfin/c_regmv_pr_dep_stall.s | 237 +++++
tests/tcg/bfin/c_regmv_pr_dr.s | 147 +++
tests/tcg/bfin/c_regmv_pr_imlb.s | 382 ++++++++
tests/tcg/bfin/c_regmv_pr_pr.s | 95 ++
tests/tcg/bfin/c_ujump.s | 52 ++
tests/tcg/bfin/cc-astat-bits.s | 101 ++
tests/tcg/bfin/cc1.s | 26 +
tests/tcg/bfin/cir.s | 20 +
tests/tcg/bfin/cir1.s | 84 ++
tests/tcg/bfin/cmpdreg.S | 40 +
tests/tcg/bfin/compare.s | 15 +
tests/tcg/bfin/d0.s | 31 +
tests/tcg/bfin/d1.s | 17 +
tests/tcg/bfin/d2.s | 56 ++
tests/tcg/bfin/div0.s | 37 +
tests/tcg/bfin/divq.s | 1322 +++++++++++++++++++++++++++
tests/tcg/bfin/dotproduct.s | 304 ++++++
tests/tcg/bfin/dotproduct2.s | 299 ++++++
tests/tcg/bfin/dsp_d0.s | 31 +
tests/tcg/bfin/dsp_d1.s | 117 +++
tests/tcg/bfin/edn_snafu.s | 45 +
tests/tcg/bfin/events.s | 44 +
tests/tcg/bfin/fact.s | 47 +
tests/tcg/bfin/fsm.s | 57 ++
tests/tcg/bfin/greg2.s | 18 +
tests/tcg/bfin/hwloop-branch-in.s | 99 ++
tests/tcg/bfin/hwloop-branch-out.s | 129 +++
tests/tcg/bfin/hwloop-lt-bits.s | 25 +
tests/tcg/bfin/hwloop-nested.s | 33 +
tests/tcg/bfin/i0.s | 57 ++
tests/tcg/bfin/issue113.s | 18 +
tests/tcg/bfin/issue126.s | 19 +
tests/tcg/bfin/issue129.s | 36 +
tests/tcg/bfin/issue144.s | 31 +
tests/tcg/bfin/issue83.s | 93 ++
tests/tcg/bfin/issue89.s | 30 +
tests/tcg/bfin/l0.s | 137 +++
tests/tcg/bfin/l0shift.s | 13 +
tests/tcg/bfin/l2_loop.s | 28 +
tests/tcg/bfin/link-2.s | 24 +
tests/tcg/bfin/link.s | 67 ++
tests/tcg/bfin/load.s | 239 +++++
tests/tcg/bfin/logic.s | 64 ++
tests/tcg/bfin/loop_snafu.s | 28 +
tests/tcg/bfin/loop_strncpy.s | 76 ++
tests/tcg/bfin/lp0.s | 17 +
tests/tcg/bfin/lp1.s | 16 +
tests/tcg/bfin/lsetup.s | 109 +++
tests/tcg/bfin/m0boundary.s | 46 +
tests/tcg/bfin/m17.s | 74 ++
tests/tcg/bfin/max_min_flags.s | 275 ++++++
tests/tcg/bfin/mem3.s | 42 +
tests/tcg/bfin/move.s | 36 +
tests/tcg/bfin/neg.S | 42 +
tests/tcg/bfin/nshift.s | 33 +
tests/tcg/bfin/pr.s | 81 ++
tests/tcg/bfin/push-pop-multiple.s | 169 ++++
tests/tcg/bfin/push-pop.s | 78 ++
tests/tcg/bfin/pushpopreg_1.s | 292 ++++++
tests/tcg/bfin/s0.s | 12 +
tests/tcg/bfin/s1.s | 25 +
tests/tcg/bfin/s10.s | 77 ++
tests/tcg/bfin/s15.s | 149 +++
tests/tcg/bfin/s16.s | 170 ++++
tests/tcg/bfin/s17.s | 46 +
tests/tcg/bfin/s2.s | 47 +
tests/tcg/bfin/s20.s | 25 +
tests/tcg/bfin/s21.s | 298 ++++++
tests/tcg/bfin/s4.s | 214 +++++
tests/tcg/bfin/s5.s | 107 +++
tests/tcg/bfin/s6.s | 83 ++
tests/tcg/bfin/s7.s | 83 ++
tests/tcg/bfin/s8.s | 55 ++
tests/tcg/bfin/s9.s | 134 +++
tests/tcg/bfin/se_kills2.S | 148 +++
tests/tcg/bfin/se_rets_hazard.s | 55 ++
tests/tcg/bfin/sign.s | 27 +
tests/tcg/bfin/simple0.s | 10 +
tests/tcg/bfin/stk.s | 78 ++
tests/tcg/bfin/stk2.s | 107 +++
tests/tcg/bfin/stk3.s | 106 +++
tests/tcg/bfin/stk4.s | 110 +++
tests/tcg/bfin/stk5.s | 34 +
tests/tcg/bfin/stk6.s | 58 ++
tests/tcg/bfin/tar10622.s | 20 +
tests/tcg/bfin/test.h | 134 +++
tests/tcg/bfin/testset.s | 73 ++
tests/tcg/bfin/testset2.s | 37 +
tests/tcg/bfin/testutils.inc | 258 ++++++
tests/tcg/bfin/vec-abs.S | 42 +
tests/tcg/bfin/vecadd.s | 65 ++
tests/tcg/bfin/vit_max.s | 57 ++
tests/tcg/bfin/wtf.s | 26 +
tests/tcg/bfin/zcall.s | 44 +
420 files changed, 87775 insertions(+)
create mode 100644 tests/tcg/bfin/.gitignore
create mode 100644 tests/tcg/bfin/10272_small.s
create mode 100644 tests/tcg/bfin/10436.s
create mode 100644 tests/tcg/bfin/10622.s
create mode 100644 tests/tcg/bfin/10742.s
create mode 100644 tests/tcg/bfin/10799.s
create mode 100644 tests/tcg/bfin/7641.s
create mode 100644 tests/tcg/bfin/Makefile
create mode 100644 tests/tcg/bfin/a0.s
create mode 100644 tests/tcg/bfin/a1.s
create mode 100644 tests/tcg/bfin/a10.s
create mode 100644 tests/tcg/bfin/a2.s
create mode 100644 tests/tcg/bfin/a24.s
create mode 100644 tests/tcg/bfin/a25.s
create mode 100644 tests/tcg/bfin/a26.s
create mode 100644 tests/tcg/bfin/a3.s
create mode 100644 tests/tcg/bfin/a4.s
create mode 100644 tests/tcg/bfin/a7.s
create mode 100644 tests/tcg/bfin/a8.s
create mode 100644 tests/tcg/bfin/a9.s
create mode 100644 tests/tcg/bfin/abs-2.S
create mode 100644 tests/tcg/bfin/abs-3.S
create mode 100644 tests/tcg/bfin/abs.S
create mode 100644 tests/tcg/bfin/acc-rot.s
create mode 100644 tests/tcg/bfin/acp5_19.s
create mode 100644 tests/tcg/bfin/add_imm7.s
create mode 100644 tests/tcg/bfin/algnbug1.s
create mode 100644 tests/tcg/bfin/algnbug2.s
create mode 100644 tests/tcg/bfin/b0.S
create mode 100644 tests/tcg/bfin/b1.s
create mode 100644 tests/tcg/bfin/b2.S
create mode 100644 tests/tcg/bfin/brcc.s
create mode 100644 tests/tcg/bfin/brevadd.s
create mode 100644 tests/tcg/bfin/byteunpack.s
create mode 100644 tests/tcg/bfin/c_alu2op_arith_r_sft.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_b.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_h.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_mix.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_neg.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_toggle.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_xb.s
create mode 100644 tests/tcg/bfin/c_alu2op_conv_xh.s
create mode 100644 tests/tcg/bfin/c_alu2op_divq.s
create mode 100644 tests/tcg/bfin/c_alu2op_divs.s
create mode 100644 tests/tcg/bfin/c_alu2op_log_l_sft.s
create mode 100644 tests/tcg/bfin/c_alu2op_log_r_sft.s
create mode 100644 tests/tcg/bfin/c_alu2op_shadd_1.s
create mode 100644 tests/tcg/bfin/c_alu2op_shadd_2.s
create mode 100644 tests/tcg/bfin/c_br_preg_killed_ac.s
create mode 100644 tests/tcg/bfin/c_br_preg_killed_ex1.s
create mode 100644 tests/tcg/bfin/c_br_preg_stall_ac.s
create mode 100644 tests/tcg/bfin/c_br_preg_stall_ex1.s
create mode 100644 tests/tcg/bfin/c_brcc_bp1.s
create mode 100644 tests/tcg/bfin/c_brcc_bp2.s
create mode 100644 tests/tcg/bfin/c_brcc_bp3.s
create mode 100644 tests/tcg/bfin/c_brcc_bp4.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_bp.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_brt_bp.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_brt_nbp.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_fbkwd.s
create mode 100644 tests/tcg/bfin/c_brcc_brf_nbp.s
create mode 100644 tests/tcg/bfin/c_brcc_brt_bp.s
create mode 100644 tests/tcg/bfin/c_brcc_brt_nbp.s
create mode 100644 tests/tcg/bfin/c_calla_ljump.s
create mode 100644 tests/tcg/bfin/c_calla_subr.s
create mode 100644 tests/tcg/bfin/c_cc2dreg.s
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_ac.S
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_an.s
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_aq.s
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_av0.S
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_av1.S
create mode 100644 tests/tcg/bfin/c_cc2stat_cc_az.s
create mode 100644 tests/tcg/bfin/c_cc_flag_ccmv_depend.S
create mode 100644 tests/tcg/bfin/c_cc_flagdreg_mvbrsft.s
create mode 100644 tests/tcg/bfin/c_cc_regmvlogi_mvbrsft.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_dr.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_dr_uu.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_imm3.s
create mode 100644 tests/tcg/bfin/c_ccflag_dr_imm3_uu.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_imm3.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_imm3_uu.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_pr.s
create mode 100644 tests/tcg/bfin/c_ccflag_pr_pr_uu.s
create mode 100644 tests/tcg/bfin/c_ccmv_cc_dr_dr.s
create mode 100644 tests/tcg/bfin/c_ccmv_cc_dr_pr.s
create mode 100644 tests/tcg/bfin/c_ccmv_cc_pr_pr.s
create mode 100644 tests/tcg/bfin/c_ccmv_ncc_dr_dr.s
create mode 100644 tests/tcg/bfin/c_ccmv_ncc_dr_pr.s
create mode 100644 tests/tcg/bfin/c_ccmv_ncc_pr_pr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_and_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_minus_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_mix.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_or_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_plus_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_dr_xor_dr.s
create mode 100644 tests/tcg/bfin/c_comp3op_pr_plus_pr_sh1.s
create mode 100644 tests/tcg/bfin/c_comp3op_pr_plus_pr_sh2.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_add_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_add_i7_p.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_eq_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opd_dr_eq_i7_p.s
create mode 100644 tests/tcg/bfin/c_compi2opd_flags.S
create mode 100644 tests/tcg/bfin/c_compi2opd_flags_2.S
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_add_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_add_i7_p.s
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_eq_i7_n.s
create mode 100644 tests/tcg/bfin/c_compi2opp_pr_eq_i7_p.s
create mode 100644 tests/tcg/bfin/c_dagmodik_lnz_imgebl.s
create mode 100644 tests/tcg/bfin/c_dagmodik_lnz_imltbl.s
create mode 100644 tests/tcg/bfin/c_dagmodik_lz_inc_dec.s
create mode 100644 tests/tcg/bfin/c_dagmodim_lnz_imgebl.s
create mode 100644 tests/tcg/bfin/c_dagmodim_lnz_imltbl.s
create mode 100644 tests/tcg/bfin/c_dagmodim_lz_inc_dec.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_a_neg_a.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_aa_absabs.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_aa_negneg.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_abs.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_absabs.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_awx.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_bytepack.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_byteunpack.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_disalnexcpt.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_max.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_maxmax.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_min.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_minmin.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_rr_lph_a1a0.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_search.s
create mode 100644 tests/tcg/bfin/c_dsp32alu_sgn.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_a1a0.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a0.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a0_i.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a0_m.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a1.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a1_i.s
create mode 100644 tests/tcg/bfin/c_dsp32mac_pair_a1_m.s
create mode 100644 tests/tcg/bfin/c_dsp32mult_pair_m.s
create mode 100644 tests/tcg/bfin/c_dsp32mult_pair_m_i.s
create mode 100644 tests/tcg/bfin/c_dsp32mult_pair_m_u.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_a0alr.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_af.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rn_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ahalf_rp_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_align16.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_align24.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_align8.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_fdepx.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_fextx.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lf.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_lhalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_ones.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_pack.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_rot.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_rot_mix.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_signbits_r.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_signbits_rh.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_signbits_rl.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_vmax.s
create mode 100644 tests/tcg/bfin/c_dsp32shift_vmaxvmax.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_a0alr.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_af.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_af_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rn_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahalf_rp_s.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_ahh.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_amix.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lf.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_ln.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_lp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_rn.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhalf_rp.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lhh.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_lmix.s
create mode 100644 tests/tcg/bfin/c_dsp32shiftim_rot.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_dr_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_dr_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_dr_ippm.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drhi_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drhi_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drlo_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_ld_drlo_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_dr_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_dr_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_dr_ippm.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drhi_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drhi_ipp.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drlo_i.s
create mode 100644 tests/tcg/bfin/c_dspldst_st_drlo_ipp.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_dreg.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_drhi.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_drlo.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_h_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_h_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_h_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_l_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_l_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_l_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lz_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lz_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lz_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lzhi_dr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lzhi_ibml.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_lzhi_pr.s
create mode 100644 tests/tcg/bfin/c_ldimmhalf_pibml.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_b.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_h.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_b.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_h.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_xb.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_mm_xh.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_b.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_h.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_xb.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_pp_xh.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_ppmm_hbx.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_xb.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_d_p_xh.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_p_p.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_p_p_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_ld_p_p_pp.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_b.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_h.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_mm_b.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_mm_h.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_pp.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_pp_b.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_d_pp_h.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_p.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_p_mm.s
create mode 100644 tests/tcg/bfin/c_ldst_st_p_p_pp.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_b.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_xb.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dr_xh.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_ld_preg.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_dr_b.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstidxl_st_preg.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_dr_xh.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstii_ld_preg.s
create mode 100644 tests/tcg/bfin/c_ldstii_st_dr_h.s
create mode 100644 tests/tcg/bfin/c_ldstii_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstii_st_preg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_ld_preg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstiifp_st_preg.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_dr_hi.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_dr_lo.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_h_xh.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_ld_lohi.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_dr_hi.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_dr_lo.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_dreg.s
create mode 100644 tests/tcg/bfin/c_ldstpmod_st_lohi.s
create mode 100644 tests/tcg/bfin/c_linkage.s
create mode 100644 tests/tcg/bfin/c_logi2op_alshft_mix.s
create mode 100644 tests/tcg/bfin/c_logi2op_arith_shft.s
create mode 100644 tests/tcg/bfin/c_logi2op_bitclr.s
create mode 100644 tests/tcg/bfin/c_logi2op_bitset.s
create mode 100644 tests/tcg/bfin/c_logi2op_bittgl.s
create mode 100644 tests/tcg/bfin/c_logi2op_bittst.s
create mode 100644 tests/tcg/bfin/c_logi2op_log_l_shft.s
create mode 100644 tests/tcg/bfin/c_logi2op_log_l_shft_astat.S
create mode 100644 tests/tcg/bfin/c_logi2op_log_r_shft.s
create mode 100644 tests/tcg/bfin/c_logi2op_log_r_shft_astat.S
create mode 100644 tests/tcg/bfin/c_logi2op_nbittst.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested_bot.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested_prelc.s
create mode 100644 tests/tcg/bfin/c_loopsetup_nested_top.s
create mode 100644 tests/tcg/bfin/c_loopsetup_overlap.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_div2_lc0.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_div2_lc1.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_lc0.s
create mode 100644 tests/tcg/bfin/c_loopsetup_preg_lc1.s
create mode 100644 tests/tcg/bfin/c_loopsetup_prelc.s
create mode 100644 tests/tcg/bfin/c_loopsetup_topbotcntr.s
create mode 100644 tests/tcg/bfin/c_progctrl_call_pcpr.s
create mode 100644 tests/tcg/bfin/c_progctrl_call_pr.s
create mode 100644 tests/tcg/bfin/c_progctrl_jump_pcpr.s
create mode 100644 tests/tcg/bfin/c_progctrl_jump_pr.s
create mode 100644 tests/tcg/bfin/c_progctrl_nop.s
create mode 100644 tests/tcg/bfin/c_progctrl_rts.s
create mode 100644 tests/tcg/bfin/c_ptr2op_pr_neg_pr.s
create mode 100644 tests/tcg/bfin/c_ptr2op_pr_sft_2_1.s
create mode 100644 tests/tcg/bfin/c_ptr2op_pr_shadd_1_2.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_dp.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_dp_pair.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_dreg.s
create mode 100644 tests/tcg/bfin/c_pushpopmultiple_preg.s
create mode 100644 tests/tcg/bfin/c_regmv_acc_acc.s
create mode 100644 tests/tcg/bfin/c_regmv_dag_lz_dep.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_acc_acc.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_dep_nostall.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_dr.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_imlb.s
create mode 100644 tests/tcg/bfin/c_regmv_dr_pr.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_dep_nostall.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_dep_stall.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_dr.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_imlb.s
create mode 100644 tests/tcg/bfin/c_regmv_imlb_pr.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_dep_nostall.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_dep_stall.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_dr.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_imlb.s
create mode 100644 tests/tcg/bfin/c_regmv_pr_pr.s
create mode 100644 tests/tcg/bfin/c_ujump.s
create mode 100644 tests/tcg/bfin/cc-astat-bits.s
create mode 100644 tests/tcg/bfin/cc1.s
create mode 100644 tests/tcg/bfin/cir.s
create mode 100644 tests/tcg/bfin/cir1.s
create mode 100644 tests/tcg/bfin/cmpdreg.S
create mode 100644 tests/tcg/bfin/compare.s
create mode 100644 tests/tcg/bfin/d0.s
create mode 100644 tests/tcg/bfin/d1.s
create mode 100644 tests/tcg/bfin/d2.s
create mode 100644 tests/tcg/bfin/div0.s
create mode 100644 tests/tcg/bfin/divq.s
create mode 100644 tests/tcg/bfin/dotproduct.s
create mode 100644 tests/tcg/bfin/dotproduct2.s
create mode 100644 tests/tcg/bfin/dsp_d0.s
create mode 100644 tests/tcg/bfin/dsp_d1.s
create mode 100644 tests/tcg/bfin/edn_snafu.s
create mode 100644 tests/tcg/bfin/events.s
create mode 100644 tests/tcg/bfin/fact.s
create mode 100644 tests/tcg/bfin/fsm.s
create mode 100644 tests/tcg/bfin/greg2.s
create mode 100644 tests/tcg/bfin/hwloop-branch-in.s
create mode 100644 tests/tcg/bfin/hwloop-branch-out.s
create mode 100644 tests/tcg/bfin/hwloop-lt-bits.s
create mode 100644 tests/tcg/bfin/hwloop-nested.s
create mode 100644 tests/tcg/bfin/i0.s
create mode 100644 tests/tcg/bfin/issue113.s
create mode 100644 tests/tcg/bfin/issue126.s
create mode 100644 tests/tcg/bfin/issue129.s
create mode 100644 tests/tcg/bfin/issue144.s
create mode 100644 tests/tcg/bfin/issue83.s
create mode 100644 tests/tcg/bfin/issue89.s
create mode 100644 tests/tcg/bfin/l0.s
create mode 100644 tests/tcg/bfin/l0shift.s
create mode 100644 tests/tcg/bfin/l2_loop.s
create mode 100644 tests/tcg/bfin/link-2.s
create mode 100644 tests/tcg/bfin/link.s
create mode 100644 tests/tcg/bfin/load.s
create mode 100644 tests/tcg/bfin/logic.s
create mode 100644 tests/tcg/bfin/loop_snafu.s
create mode 100644 tests/tcg/bfin/loop_strncpy.s
create mode 100644 tests/tcg/bfin/lp0.s
create mode 100644 tests/tcg/bfin/lp1.s
create mode 100644 tests/tcg/bfin/lsetup.s
create mode 100644 tests/tcg/bfin/m0boundary.s
create mode 100644 tests/tcg/bfin/m17.s
create mode 100644 tests/tcg/bfin/max_min_flags.s
create mode 100644 tests/tcg/bfin/mem3.s
create mode 100644 tests/tcg/bfin/move.s
create mode 100644 tests/tcg/bfin/neg.S
create mode 100644 tests/tcg/bfin/nshift.s
create mode 100644 tests/tcg/bfin/pr.s
create mode 100644 tests/tcg/bfin/push-pop-multiple.s
create mode 100644 tests/tcg/bfin/push-pop.s
create mode 100644 tests/tcg/bfin/pushpopreg_1.s
create mode 100644 tests/tcg/bfin/s0.s
create mode 100644 tests/tcg/bfin/s1.s
create mode 100644 tests/tcg/bfin/s10.s
create mode 100644 tests/tcg/bfin/s15.s
create mode 100644 tests/tcg/bfin/s16.s
create mode 100644 tests/tcg/bfin/s17.s
create mode 100644 tests/tcg/bfin/s2.s
create mode 100644 tests/tcg/bfin/s20.s
create mode 100644 tests/tcg/bfin/s21.s
create mode 100644 tests/tcg/bfin/s4.s
create mode 100644 tests/tcg/bfin/s5.s
create mode 100644 tests/tcg/bfin/s6.s
create mode 100644 tests/tcg/bfin/s7.s
create mode 100644 tests/tcg/bfin/s8.s
create mode 100644 tests/tcg/bfin/s9.s
create mode 100644 tests/tcg/bfin/se_kills2.S
create mode 100644 tests/tcg/bfin/se_rets_hazard.s
create mode 100644 tests/tcg/bfin/sign.s
create mode 100644 tests/tcg/bfin/simple0.s
create mode 100644 tests/tcg/bfin/stk.s
create mode 100644 tests/tcg/bfin/stk2.s
create mode 100644 tests/tcg/bfin/stk3.s
create mode 100644 tests/tcg/bfin/stk4.s
create mode 100644 tests/tcg/bfin/stk5.s
create mode 100644 tests/tcg/bfin/stk6.s
create mode 100644 tests/tcg/bfin/tar10622.s
create mode 100644 tests/tcg/bfin/test.h
create mode 100644 tests/tcg/bfin/testset.s
create mode 100644 tests/tcg/bfin/testset2.s
create mode 100644 tests/tcg/bfin/testutils.inc
create mode 100644 tests/tcg/bfin/vec-abs.S
create mode 100644 tests/tcg/bfin/vecadd.s
create mode 100644 tests/tcg/bfin/vit_max.s
create mode 100644 tests/tcg/bfin/wtf.s
create mode 100644 tests/tcg/bfin/zcall.s
diff --git a/tests/tcg/Makefile b/tests/tcg/Makefile
index 24e3154..da49378 100644
--- a/tests/tcg/Makefile
+++ b/tests/tcg/Makefile
@@ -153,6 +153,10 @@ test-cris:
test-lm32:
$(MAKE) -C lm32 check
+# testsuite for the Blackfin port.
+test-bfin:
+ $(MAKE) -C bfin check
+
clean:
rm -f *~ *.o test-i386.out test-i386.ref \
test-x86_64.log test-x86_64.ref qruncom $(TESTS)
diff --git a/tests/tcg/bfin/.gitignore b/tests/tcg/bfin/.gitignore
new file mode 100644
index 0000000..788ebb9
--- /dev/null
+++ b/tests/tcg/bfin/.gitignore
@@ -0,0 +1,2 @@
+*.x
+*.X
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 5/5] linux-user: add support for Blackfin syscalls
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 4/5] Blackfin: add test suite Mike Frysinger
@ 2013-06-17 7:16 ` Mike Frysinger
2013-06-25 21:23 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Richard Henderson
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2013-06-17 7:16 UTC (permalink / raw)
To: qemu-devel
The Blackfin arch supports a simple sram allocator for userspace, as well
as a DMA memcpy function to access the sram.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
linux-user/strace.list | 9 ++++++
linux-user/syscall.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 08f115d..cf093cc 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -105,6 +105,9 @@
#ifdef TARGET_NR_dipc
{ TARGET_NR_dipc, "dipc" , NULL, NULL, NULL },
#endif
+#ifdef TARGET_NR_dma_memcpy
+{ TARGET_NR_dma_memcpy, "dma_memcpy" , NULL, NULL, NULL },
+#endif
#ifdef TARGET_NR_dup
{ TARGET_NR_dup, "dup" , NULL, NULL, NULL },
#endif
@@ -1299,6 +1302,12 @@
#ifdef TARGET_NR_splice
{ TARGET_NR_splice, "splice" , NULL, NULL, NULL },
#endif
+#ifdef TARGET_NR_sram_alloc
+{ TARGET_NR_sram_alloc, "sram_alloc" , NULL, NULL, NULL },
+#endif
+#ifdef TARGET_NR_sram_free
+{ TARGET_NR_sram_free, "sram_free" , NULL, NULL, NULL },
+#endif
#ifdef TARGET_NR_ssetmask
{ TARGET_NR_ssetmask, "ssetmask" , NULL, NULL, NULL },
#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a9dce35..a4431f0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4755,6 +4755,14 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
}
#endif
+#ifdef TARGET_NR_sram_alloc
+struct sram_frag {
+ struct sram_frag *next;
+ abi_ulong addr, size;
+};
+static struct sram_frag *sfrags;
+#endif
+
#if defined(CONFIG_USE_NPTL)
/* ??? Using host futex calls even when target atomic operations
are not really atomic probably breaks things. However implementing
@@ -6413,6 +6421,72 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
ret = get_errno(munlockall());
break;
#endif
+#ifdef TARGET_NR_sram_alloc
+ case TARGET_NR_sram_alloc:
+ {
+ /* We don't want L1 insn to be read/write, but doing that
+ * keeps standard qemu funcs from being able to read/write
+ * that too. So grant r/w access to all. */
+ int prot = PROT_READ | PROT_WRITE;
+ if ((arg2 & 1 /*L1_INST_SRAM*/) || (arg2 & 8 /*L2_SRAM*/)) {
+ prot |= PROT_EXEC;
+ }
+
+ ret = get_errno(target_mmap(0, arg1, prot, MAP_PRIVATE |
+ MAP_ANONYMOUS, -1, 0));
+
+ if (!is_error(ret)) {
+ struct sram_frag *sf = malloc(sizeof(*sf));
+ sf->addr = ret;
+ sf->size = arg1;
+ if (sfrags) {
+ sf->next = sfrags;
+ sfrags = sf;
+ } else {
+ sf->next = NULL;
+ sfrags = sf;
+ }
+ }
+ }
+ break;
+#endif
+#ifdef TARGET_NR_sram_free
+ case TARGET_NR_sram_free:
+ {
+ struct sram_frag *sf, *prev;
+
+ ret = -TARGET_EINVAL;
+
+ sf = prev = sfrags;
+ while (sf) {
+ if (sf->addr == arg1) {
+ ret = get_errno(target_munmap(arg1, sf->size));
+ if (!is_error(ret)) {
+ if (sfrags == sf) {
+ sfrags = sf->next;
+ } else {
+ prev->next = sf->next;
+ }
+ free(sf);
+ }
+ break;
+ }
+ prev = sf;
+ sf = sf->next;
+ }
+ }
+ break;
+#endif
+#ifdef TARGET_NR_dma_memcpy
+ case TARGET_NR_dma_memcpy:
+ p = alloca(arg3);
+ if (copy_from_user(p, arg2, arg3))
+ goto efault;
+ if (copy_to_user(arg1, p, arg3))
+ goto efault;
+ ret = arg1;
+ break;
+#endif
case TARGET_NR_truncate:
if (!(p = lock_user_string(arg1)))
goto efault;
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
` (2 preceding siblings ...)
2013-06-17 7:16 ` [Qemu-devel] [PATCH 5/5] linux-user: add support for Blackfin syscalls Mike Frysinger
@ 2013-06-25 21:23 ` Richard Henderson
2013-06-25 23:14 ` Mike Frysinger
2013-06-28 13:47 ` Eric Blake
2013-06-28 14:24 ` Andreas Färber
5 siblings, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2013-06-25 21:23 UTC (permalink / raw)
To: Mike Frysinger; +Cc: qemu-devel
> diff --git a/target-bfin/bfin-sim.c b/target-bfin/bfin-sim.c
Why this separate file from translate.c?
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <inttypes.h>
Certainly you shouldn't need these, since this isn't a separately
compiled object -- you're included from translate.c.
> +static void
> +unhandled_instruction(DisasContext *dc, const char *insn)
> +{
> + fprintf(stderr, "unhandled insn: %s\n", insn);
Use LOG_UNIMP.
> +#define HOST_LONG_WORD_SIZE (sizeof(long) * 8)
You mean TCG_TARGET_REG_BITS?
> +static TCGv
> +get_allreg(DisasContext *dc, int grp, int reg)
> +{
> + TCGv *ret = cpu_regs[(grp << 3) | reg];
> + if (ret) {
> + return *ret;
> + }
> + abort();
> + illegal_instruction(dc);
> +}
Well, which is it? abort or illegal_instruction. And come to that, how is
abort any better than SEGV from dereferecing the null? Certainly the later
will generate a faster translator...
> +decode_multfunc_tl(DisasContext *dc, int h0, int h1, int src0, int src1,
> + int mmod, int MM, TCGv psat)
> +{
> + TCGv s0, s1, val;
> +
> + s0 = tcg_temp_local_new();
You'll really want to avoid local temps and branches, if at all possible. For
some of the more complex stuff that you're open-coding, you may be better off
with helper functions instead.
> + l = gen_new_label();
> + endl = gen_new_label();
> +
> + tcg_gen_brcondi_tl(TCG_COND_NE, val, 0x40000000, l);
> + if (mmod == M_W32) {
> + tcg_gen_movi_tl(val, 0x7fffffff);
> + } else {
> + tcg_gen_movi_tl(val, 0x80000000);
> + }
> + tcg_gen_movi_tl(psat, 1);
> + tcg_gen_br(endl);
> +
> + gen_set_label(l);
> + tcg_gen_shli_tl(val, val, 1);
> +
> + gen_set_label(endl);
Certainly possible here with 2 movcond, or 1 movcond, 1 setcond + 1 or.
> + l = gen_new_label();
> + tcg_gen_brcondi_tl(TCG_COND_EQ, psat, 0, l);
> + tcg_gen_ext32u_i64(val1, val1);
> + gen_set_label(l);
movcond again.
> +static void
> +saturate_s32(TCGv_i64 val, TCGv overflow)
I shall now stop mentioning movcond. I sense there are many locations to come.
> + } else if (prgfunc == 11 && poprnd < 6) {
> + /* TESTSET (Preg{poprnd}); */
> + TCGv tmp = tcg_temp_new();
> + tcg_gen_qemu_ld8u(tmp, cpu_preg[poprnd], dc->mem_idx);
> + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_cc, tmp, 0);
> + tcg_gen_ori_tl(tmp, tmp, 0x80);
> + tcg_gen_qemu_st8(tmp, cpu_preg[poprnd], dc->mem_idx);
> + tcg_temp_free(tmp);
I'll note that this is fine for system code, but for user code ought to be
atomic. There are a bunch of really bad examples in the tree, and no real
good solutions atm.
> + /* Can't push/pop reserved registers */
> + /*if (reg_is_reserved(grp, reg))
> + illegal_instruction(dc);*/
No commented out code like this.
> + /* Everything here needs to be aligned, so check once */
> + gen_align_check(dc, cpu_spreg, 4, false);
You ought not need to generate explicit alignment checks. Yes, we don't do
that correctly for user-mode, but we do for system mode.
My hope is that user mode eventually has the option of using the system mode
page tables too -- there are just too many things that don't work correctly
when host and target page sizes don't match, or the host and target don't have
the same unaligned access characteristics.
> + } else if (grp == 4 && (reg == 0 || reg == 2)) {
> + /* Pop A#.X */
> + tmp = tcg_temp_new();
> + tcg_gen_qemu_ld32u(tmp, cpu_spreg, dc->mem_idx);
> + tcg_gen_andi_tl(tmp, tmp, 0xff);
> + tmp64 = tcg_temp_new_i64();
> + tcg_gen_extu_i32_i64(tmp64, tmp);
> + tcg_temp_free(tmp);
> +
> + tcg_gen_andi_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], 0xffffffff);
> + tcg_gen_shli_i64(tmp64, tmp64, 32);
> + tcg_gen_or_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], tmp64);
> + tcg_temp_free_i64(tmp64);
Drop the andi with 0xff and use
tcg_gen_deposit_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], tmp64, 32, 8)
> + } else if (grp == 4 && (reg == 1 || reg == 3)) {
> + /* Pop A#.W */
> + tcg_gen_andi_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], 0xff00000000);
> + tmp = tcg_temp_new();
> + tcg_gen_qemu_ld32u(tmp, cpu_spreg, dc->mem_idx);
> + tmp64 = tcg_temp_new_i64();
> + tcg_gen_extu_i32_i64(tmp64, tmp);
> + tcg_temp_free(tmp);
> + tcg_gen_or_i64(cpu_areg[reg >> 1], cpu_areg[reg >> 1], tmp64);
> + tcg_temp_free_i64(tmp64);
And then this one becomes deposit(areg, areg, tmp64, 0, 32).
> + } else if (grp == 4 && (reg == 0 || reg == 2)) {
> + /* Push A#.X */
> + tmp64 = tcg_temp_new_i64();
> + tcg_gen_shri_i64(tmp64, cpu_areg[reg >> 1], 32);
> + tmp = tcg_temp_new();
> + tcg_gen_trunc_i64_i32(tmp, tmp64);
> + tcg_temp_free_i64(tmp64);
> + tcg_gen_andi_tl(tmp, tmp, 0xff);
Do we ever allow the high 24 bits to be non-zero? Is this andi actually redundant?
> + if (W == 1) {
> + /* [--SP] = ({d}R7:imm{dr}, {p}P5:imm{pr}); */
> + if (d) {
> + for (i = dr; i < 8; i++) {
> + tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
> + tcg_gen_qemu_st32(cpu_dreg[i], cpu_spreg, dc->mem_idx);
> + }
> + }
What's the cpu exception effect of the second store causing a page fault?
Normally one needs to do the address increment in a temporary and only update
the real SP register at the end, so that the instruction can be restarted.
> + /* CC = CC; is invalid. */
> + if (cbit == 5)
> + illegal_instruction(dc);
Please handle all checkpatch.pl style errors.
> + if (opc == 0) {
> + /* CC = ! BITTST (Dreg{dst}, imm{uimm}); */
> + tmp = tcg_temp_new();
> + tcg_gen_movi_tl(tmp, 1 << uimm);
> + tcg_gen_and_tl(tmp, tmp, cpu_dreg[dst]);
> + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_cc, tmp, 0);
> + tcg_temp_free(tmp);
> + } else if (opc == 1) {
> + /* CC = BITTST (Dreg{dst}, imm{uimm}); */
> + tmp = tcg_temp_new();
> + tcg_gen_movi_tl(tmp, 1 << uimm);
> + tcg_gen_and_tl(tmp, tmp, cpu_dreg[dst]);
> + tcg_gen_setcondi_tl(TCG_COND_NE, cpu_cc, tmp, 0);
> + tcg_temp_free(tmp);
You're writing
(x & (1 << I)) != 0
whereas the alternative
(x >> I) & 1
does not require the setcond, and will be faster on most hosts.
> + if (aop == 1 && W == 0 && idx == ptr) {
> + /* Dreg_lo{reg} = W[Preg{ptr}]; */
> + tmp = tcg_temp_local_new();
> + tcg_gen_andi_tl(cpu_dreg[reg], cpu_dreg[reg], 0xffff0000);
> + gen_aligned_qemu_ld16u(dc, tmp, cpu_preg[ptr]);
> + tcg_gen_or_tl(cpu_dreg[reg], cpu_dreg[reg], tmp);
> + tcg_temp_free(tmp);
Deposit again. Lots of instances in this function.
> + /* LINK imm{framesize}; */
> + int size = uimm16s4(framesize);
> + tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
> + tcg_gen_qemu_st32(cpu_rets, cpu_spreg, dc->mem_idx);
> + tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
> + tcg_gen_qemu_st32(cpu_fpreg, cpu_spreg, dc->mem_idx);
> + tcg_gen_mov_tl(cpu_fpreg, cpu_spreg);
> + tcg_gen_subi_tl(cpu_spreg, cpu_spreg, size);
> + } else if (framesize == 0) {
> + /* UNLINK; */
> + /* Restore SP from FP. */
> + tcg_gen_mov_tl(cpu_spreg, cpu_fpreg);
> + tcg_gen_qemu_ld32u(cpu_fpreg, cpu_spreg, dc->mem_idx);
> + tcg_gen_addi_tl(cpu_spreg, cpu_spreg, 4);
> + tcg_gen_qemu_ld32u(cpu_rets, cpu_spreg, dc->mem_idx);
> + tcg_gen_addi_tl(cpu_spreg, cpu_spreg, 4);
Similarly to push/pop multiple wrt intermediate SP.
> + if ((aop == 0 || aop == 2) && aopcde == 9 && HL == 0 && s == 0) {
> + int a = aop >> 1;
> + /* Areg_lo{a} = Dreg_lo{src0}; */
> + tcg_gen_andi_i64(cpu_areg[a], cpu_areg[a], ~0xffff);
> + tmp64 = tcg_temp_new_i64();
> + tcg_gen_extu_i32_i64(tmp64, cpu_dreg[src0]);
> + tcg_gen_andi_i64(tmp64, tmp64, 0xffff);
> + tcg_gen_or_i64(cpu_areg[a], cpu_areg[a], tmp64);
> + tcg_temp_free_i64(tmp64);
More deposits in this function. I'll stop mentioning them, but pretty much
every place you touch aregs can use this.
> +#include "linux-fixed-code.h"
> +
> +static uint32_t bfin_lduw_code(DisasContext *dc, target_ulong pc)
> +{
> +#ifdef CONFIG_USER_ONLY
> + /* Intercept jump to the magic kernel page */
> + if (((dc->env->personality & 0xff/*PER_MASK*/) == 0/*PER_LINUX*/) &&
> + (pc & 0xFFFFFF00) == 0x400) {
> + uint32_t off = pc - 0x400;
> + if (off < sizeof(bfin_linux_fixed_code)) {
> + return ((uint16_t)bfin_linux_fixed_code[off + 1] << 8) |
> + bfin_linux_fixed_code[off];
> + }
> + }
> +#endif
Surely this memory setup belongs in linux-user/.
> +/* Interpret a single Blackfin insn; breaks up parallel insns */
> +static void
> +interp_insn_bfin(DisasContext *dc)
> +{
> + _interp_insn_bfin(dc, dc->pc);
I'd prefer a suffix like "1" rather than a prefix of "_".
> +typedef struct CPUBfinState {
> + CPU_COMMON
COMMON should come last, or just about.
Certainly the cpu registers should come first, for most
efficient translation access on the host.
> +static inline void bfin_astat_write(CPUArchState *env, uint32_t astat)
> +{
> + unsigned int i;
> + for (i = 0; i < 32; ++i)
> + env->astat[i] = !!(astat & (1 << i));
= (astat >> i) & 1
> +typedef void (*hwloop_callback)(struct DisasContext *dc, int loop);
> +
> +typedef struct DisasContext {
> + CPUArchState *env;
> + struct TranslationBlock *tb;
> + /* The current PC we're decoding (could be middle of parallel insn) */
> + target_ulong pc;
> + /* Length of current insn (2/4/8) */
> + target_ulong insn_len;
> +
> + /* For delayed ASTAT handling */
> + enum astat_ops astat_op;
> +
> + /* For hardware lop processing */
> + hwloop_callback hwloop_callback;
> + void *hwloop_data;
> +
> + /* Was a DISALGNEXCPT used in this parallel insn ? */
> + int disalgnexcpt;
> +
> + int is_jmp;
> + int mem_idx;
> +} DisasContext;
Really, this type should be private to translate.c.
> +static inline void cpu_get_tb_cpu_state(CPUArchState *env, target_ulong *pc,
> + target_ulong *cs_base, int *flags)
> +{
> + *pc = cpu_get_pc(env);
> + *cs_base = 0;
> + *flags = env->astat[ASTAT_RND_MOD];
> +}
You'll probably be better off with a bit that notes whether the loop registers
are active, or something, so that you don't have to always generate code that
handles them.
> +DEF_HELPER_3(raise_exception, void, env, i32, i32)
Lots of these can use better settings for flags. Here, the only side effect is
to raise an exception, which leads to reading the globals. So TCG_CALL_NO_WG.
> +DEF_HELPER_5(memalign, void, env, i32, i32, i32, i32)
> +
> +DEF_HELPER_4(dbga_l, void, env, i32, i32, i32)
> +DEF_HELPER_4(dbga_h, void, env, i32, i32, i32)
Likewise.
> +/* Count the number of bits set to 1 in the 32bit value */
> +uint32_t HELPER(ones)(uint32_t val)
> +{
> + uint32_t i;
> + uint32_t ret;
> +
> + ret = 0;
> + for (i = 0; i < 32; ++i)
> + ret += !!(val & (1 << i));
ctpop32.
> +/* Count number of leading bits that match the sign bit */
> +uint32_t HELPER(signbits)(uint32_t val, uint32_t size)
...
> +/* Count number of leading bits that match the sign bit */
> +uint32_t HELPER(signbits_64)(uint64_t val, uint32_t size)
Surely we can make some use of clz here. But I guess for now this is ok.
> +static void gen_goto_tb(DisasContext *dc, int tb_num, TCGv dest)
> +{
> +/*
> + TranslationBlock *tb;
> + tb = dc->tb;
> +
> + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
> + tcg_gen_goto_tb(tb_num);
> + tcg_gen_mov_tl(cpu_pc, dest);
> + tcg_gen_exit_tb((long)tb + tb_num);
> + } else */{
> + gen_astat_update(dc, false);
> + tcg_gen_mov_tl(cpu_pc, dest);
> + tcg_gen_exit_tb(0);
> + }
Why the astat update here, when you have it on almost no other exits from the tb?
> + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
> + tcg_gen_debug_insn_start(dc->pc);
CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT
r~
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port
2013-06-25 21:23 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Richard Henderson
@ 2013-06-25 23:14 ` Mike Frysinger
0 siblings, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2013-06-25 23:14 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
[-- Attachment #1: Type: Text/Plain, Size: 11044 bytes --]
On Tuesday 25 June 2013 17:23:57 Richard Henderson wrote:
whee, got a review! :) i've snipped items that were obvious in the "i'll go
do this" category rather than just copying & pasting "OK" many times. got a
long flight coming up soon, so hopefully i can tackle the majority of this work
then.
> > diff --git a/target-bfin/bfin-sim.c b/target-bfin/bfin-sim.c
>
> Why this separate file from translate.c?
because this port is based on the GNU/sim Blackfin port. bfin-sim.c focuses on
the actual opcode translation while the higher level file (translate.c in QEMU
and interp.c in GNU/sim) takes care of the higher layers (like clock ticking).
i like keeping the core structure the same between the two sims so that i can
more easily merge changes between them.
> > +#include <stdbool.h>
> > +#include <stdint.h>
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <inttypes.h>
>
> Certainly you shouldn't need these, since this isn't a separately
> compiled object -- you're included from translate.c.
yes, this is most likely true. it's due to the previous reason. maybe i
should make it a sep compiled file then there won't be any confusion ...
> > +#define HOST_LONG_WORD_SIZE (sizeof(long) * 8)
>
> You mean TCG_TARGET_REG_BITS?
maybe? this is for extracting target encoded immediates and properly
extending them up to the system that is running the code (e.g. x86_64) so that
it can then be checked naturally (like comparing it to a -1). but this is
done in the decode logic, not in the tcg output logic, so i'm not sure TCG is
the right abstraction.
> > +static TCGv
> > +get_allreg(DisasContext *dc, int grp, int reg)
> > +{
> > + TCGv *ret = cpu_regs[(grp << 3) | reg];
> > + if (ret) {
> > + return *ret;
> > + }
> > + abort();
> > + illegal_instruction(dc);
> > +}
>
> Well, which is it? abort or illegal_instruction.
i had this in there while doing the initial port to track down bad things. i
can probably cut it over to illegal_instruction() now.
> And come to that, how is
> abort any better than SEGV from dereferecing the null? Certainly the later
> will generate a faster translator...
QEMU doesn't need any help segfaulting :p. an abort() is much better at
showing the source of the problem.
> > +decode_multfunc_tl(DisasContext *dc, int h0, int h1, int src0, int src1,
> > + int mmod, int MM, TCGv psat)
> > +{
> > + TCGv s0, s1, val;
> > +
> > + s0 = tcg_temp_local_new();
>
> You'll really want to avoid local temps and branches, if at all possible.
> For some of the more complex stuff that you're open-coding, you may be
> better off with helper functions instead.
it seemed like having generated (and cached) opcodes was better than relying
on helpers since helpers requires interrupting the native code flow and muck
around with state ? is there a good (or even semi-decent) rule of thumb i can
use to decide when to use one over the other ?
> > +static void
> > +saturate_s32(TCGv_i64 val, TCGv overflow)
>
> I shall now stop mentioning movcond. I sense there are many locations to
> come.
looks like movcond was introduced after i did the initial (bulk) port. so
there are probably many locations that can take advantage of it. i'll have to
go through the code top-to-bottom looking for things. and probably look at
the history of tcg/README to see what other interesting opcodes have been
added since.
> > + } else if (prgfunc == 11 && poprnd < 6) {
> > + /* TESTSET (Preg{poprnd}); */
> > + TCGv tmp = tcg_temp_new();
> > + tcg_gen_qemu_ld8u(tmp, cpu_preg[poprnd], dc->mem_idx);
> > + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_cc, tmp, 0);
> > + tcg_gen_ori_tl(tmp, tmp, 0x80);
> > + tcg_gen_qemu_st8(tmp, cpu_preg[poprnd], dc->mem_idx);
> > + tcg_temp_free(tmp);
>
> I'll note that this is fine for system code, but for user code ought to be
> atomic. There are a bunch of really bad examples in the tree, and no real
> good solutions atm.
i general, i completely agree with you. in practice, i think a (mis)feature
of the Blackfin arch helps out here. TESTSET doesn't work on cached memory,
and it only works on system memory (i.e. not L1), and every Linux build runs
with caches turned on. so maybe flaky misbehavior is a good thing ? :)
i can drop a note in there noting the issue though
> > + /* Everything here needs to be aligned, so check once */
> > + gen_align_check(dc, cpu_spreg, 4, false);
>
> You ought not need to generate explicit alignment checks. Yes, we don't do
> that correctly for user-mode, but we do for system mode.
>
> My hope is that user mode eventually has the option of using the system
> mode page tables too -- there are just too many things that don't work
> correctly when host and target page sizes don't match, or the host and
> target don't have the same unaligned access characteristics.
i had this code because it wasn't working in user mode, and someone in a
previous review suggested i check out gen_helper_memalign(). i actually have
this disabled by default because the speed impact is fairly substantial. i
was debating turning this into a configure time check.
> > + } else if (grp == 4 && (reg == 0 || reg == 2)) {
> > + /* Push A#.X */
> > + tmp64 = tcg_temp_new_i64();
> > + tcg_gen_shri_i64(tmp64, cpu_areg[reg >> 1], 32);
> > + tmp = tcg_temp_new();
> > + tcg_gen_trunc_i64_i32(tmp, tmp64);
> > + tcg_temp_free_i64(tmp64);
> > + tcg_gen_andi_tl(tmp, tmp, 0xff);
>
> Do we ever allow the high 24 bits to be non-zero? Is this andi actually
> redundant?
yes & no. in the hardware, it'll always be 0. there is some code which will
might sign extend things (so that you can correctly compare the 40bit
accumulator using 64bit regs), and that would interact badly here. maybe it
would be better to drop this and force the accumulator handling code to do the
right thing with the sign rather than store the result.
> > + if (W == 1) {
> > + /* [--SP] = ({d}R7:imm{dr}, {p}P5:imm{pr}); */
> > + if (d) {
> > + for (i = dr; i < 8; i++) {
> > + tcg_gen_subi_tl(cpu_spreg, cpu_spreg, 4);
> > + tcg_gen_qemu_st32(cpu_dreg[i], cpu_spreg, dc->mem_idx);
> > + }
> > + }
>
> What's the cpu exception effect of the second store causing a page fault?
> Normally one needs to do the address increment in a temporary and only
> update the real SP register at the end, so that the instruction can be
> restarted.
this was me being lazy when getting started with the port ;). the GNU/sim
code matches the hardware and that is as you suspected -- the SP reg isn't
updated until after all the push/pops finish. i wasn't sweating the difference
here too much as in user mode, the exception would just kill the program
(ignoring apps that catch like SIGSEGV).
i'll have to generate a tmp reg based on SP and do it correctly though now
that this port is out of the infant stage.
> > +#include "linux-fixed-code.h"
> > +
> > +static uint32_t bfin_lduw_code(DisasContext *dc, target_ulong pc)
> > +{
> > +#ifdef CONFIG_USER_ONLY
> > + /* Intercept jump to the magic kernel page */
> > + if (((dc->env->personality & 0xff/*PER_MASK*/) == 0/*PER_LINUX*/) &&
> > + (pc & 0xFFFFFF00) == 0x400) {
> > + uint32_t off = pc - 0x400;
> > + if (off < sizeof(bfin_linux_fixed_code)) {
> > + return ((uint16_t)bfin_linux_fixed_code[off + 1] << 8) |
> > + bfin_linux_fixed_code[off];
> > + }
> > + }
> > +#endif
>
> Surely this memory setup belongs in linux-user/.
i couldn't find good examples previously to make this work so i put it in here.
i came across the arm handling of its fixed code recently though (which i think
does it in linux-user), so i'll see about moving it there.
> > +/* Interpret a single Blackfin insn; breaks up parallel insns */
> > +static void
> > +interp_insn_bfin(DisasContext *dc)
> > +{
> > + _interp_insn_bfin(dc, dc->pc);
>
> I'd prefer a suffix like "1" rather than a prefix of "_".
this matches the GNU/sim code, so i'd prefer to stick to that where possible.
underscore prefix is a common "this is internal" indicator.
> > +static inline void cpu_get_tb_cpu_state(CPUArchState *env, target_ulong
> > *pc, + target_ulong *cs_base, int
> > *flags) +{
> > + *pc = cpu_get_pc(env);
> > + *cs_base = 0;
> > + *flags = env->astat[ASTAT_RND_MOD];
> > +}
>
> You'll probably be better off with a bit that notes whether the loop
> registers are active, or something, so that you don't have to always
> generate code that handles them.
whether loop registers are active is purely based on the PC and the current
values in the loop registers/counters. the hardware logic is basically:
# After every single insn is executed.
oldpc = PC
PC += insn_length;
if (oldpc == LB1 && LC1) {
PC = LT1;
--LC1;
}
if (oldpc == LB0 && LB0) {
PC = LT0;
--LC0;
}
i didn't think it was really possible to check the cpu state at runtime since
ideally you'd generate a bunch of TB's, cache them, and then let them run
w/out invoking the translator again.
> > +DEF_HELPER_3(raise_exception, void, env, i32, i32)
>
> Lots of these can use better settings for flags. Here, the only side
> effect is to raise an exception, which leads to reading the globals. So
> TCG_CALL_NO_WG.
the flags are newer than the port, so i'll have to go through them all for a
refresh
> > +static void gen_goto_tb(DisasContext *dc, int tb_num, TCGv dest)
> > +{
> > +/*
> > + TranslationBlock *tb;
> > + tb = dc->tb;
> > +
> > + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
> > + tcg_gen_goto_tb(tb_num);
> > + tcg_gen_mov_tl(cpu_pc, dest);
> > + tcg_gen_exit_tb((long)tb + tb_num);
> > + } else */{
> > + gen_astat_update(dc, false);
> > + tcg_gen_mov_tl(cpu_pc, dest);
> > + tcg_gen_exit_tb(0);
> > + }
>
> Why the astat update here, when you have it on almost no other exits from
> the tb?
it's really the only way i could get it to [mostly] work :/. i tried to figure
out how x86 was handling its delayed eflags updates (since Blackfin will do
pretty much the same exact thing for the same reason), but i failed at that
too.
in general, the TB logic is magic to me. there are a number of optimizations
that are blocked because i haven't been able to figure it out. i'm surprised
it really works at all. you can see how my gen_goto_tb always does
tct_gen_exit_tb(0) which forces a PC look up every time.
-mike
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
` (3 preceding siblings ...)
2013-06-25 21:23 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Richard Henderson
@ 2013-06-28 13:47 ` Eric Blake
2013-06-28 14:24 ` Andreas Färber
5 siblings, 0 replies; 10+ messages in thread
From: Eric Blake @ 2013-06-28 13:47 UTC (permalink / raw)
To: Mike Frysinger; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1858 bytes --]
On 06/17/2013 01:16 AM, Mike Frysinger wrote:
> This is the core Blackfin support. While most things work that gcc will
> generate, there are notable things missing at this point:
> - many dsp/alu/mac insns not supported
> - no saturation support
> - many astat flags not updated
> - probably other stuff
> Details as to what is missing "by design" vs "not done due to laziness"
> can be sorted out in the Blackfin README/TODO files.
>
> FLAT and FDPIC ELFs however seem to work nicely, as do random samplings of
> apps from a typical build.
>
> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> ---
> MAINTAINERS | 5 +
> configure | 4 +
> cpu-exec.c | 5 +-
> gdbstub.c | 103 ++
> include/elf.h | 6 +
> qapi-schema.json | 9 +-
> +++ b/qapi-schema.json
> @@ -3023,10 +3023,11 @@
> # Since: 1.2.0
> ##
> { 'enum': 'TargetType',
> - 'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel',
> - 'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'moxie',
> - 'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4',
> - 'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] }
> + 'data': [ 'alpha', 'arm', 'bfin', 'cris', 'i386', 'lm32', 'm68k',
> + 'microblazeel', 'microblaze', 'mips64el', 'mips64', 'mipsel',
> + 'mips', 'moxie', 'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb',
> + 'sh4', 'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb',
> + 'xtensa' ] }
This conflicts with Paolo's patches that removed TargetType. Just drop
this hunk.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
` (4 preceding siblings ...)
2013-06-28 13:47 ` Eric Blake
@ 2013-06-28 14:24 ` Andreas Färber
5 siblings, 0 replies; 10+ messages in thread
From: Andreas Färber @ 2013-06-28 14:24 UTC (permalink / raw)
To: Mike Frysinger; +Cc: qemu-devel
Hi,
Am 17.06.2013 09:16, schrieb Mike Frysinger:
> diff --git a/target-bfin/cpu-qom.h b/target-bfin/cpu-qom.h
> new file mode 100644
> index 0000000..697797b
> --- /dev/null
> +++ b/target-bfin/cpu-qom.h
For a new target, a separate cpu-qom.h should be unnecessary - it has
become impossible to include it without cpu.h. Just inline it into cpu.h
and group CPUState vs. CPUBfinState stuff together there.
> @@ -0,0 +1,61 @@
> +/*
> + * QEMU Blackfin CPU
> + *
> + * Copyright 2007-2013 Mike Frysinger
> + * Copyright 2007-2011 Analog Devices, Inc.
> + *
> + * Licensed under the Lesser GPL 2 or later.
> + */
> +
> +#ifndef QEMU_BFIN_CPU_QOM_H
> +#define QEMU_BFIN_CPU_QOM_H
> +
> +#include "qom/cpu.h"
> +
> +#define TYPE_BFIN_CPU "bfin-cpu"
> +
> +#define BFIN_CPU_CLASS(klass) \
> + OBJECT_CLASS_CHECK(BfinCPUClass, (klass), TYPE_BFIN_CPU)
> +#define BFIN_CPU(obj) \
> + OBJECT_CHECK(BfinCPU, (obj), TYPE_BFIN_CPU)
> +#define BFIN_CPU_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(BfinCPUClass, (obj), TYPE_BFIN_CPU)
> +
> +/**
> + * BfinCPUClass:
> + * @parent_reset: The parent class' reset handler.
> + *
> + * An Bfin CPU model.
> + */
> +typedef struct BfinCPUClass {
> + /*< private >*/
> + CPUClass parent_class;
> + /*< public >*/
> +
> + void (*parent_reset)(CPUState *cpu);
> +} BfinCPUClass;
> +
> +/**
> + * BfinCPU:
QOM types should have verbose, readable names. Please use BlackfinCPU,
BlackfinCPUClass, TYPE_BLACKFIN_CPU.
By contrast, CPUBfinState, bfin_cpu_... and bfin-cpu are totally fine, I
guess.
> + * @env: #CPUArchState
Please don't use CPUArchState anywhere in bfin code except for the
#define CPUArchState CPUBfinState.
> + *
> + * An Bfin CPU.
> + */
> +typedef struct BfinCPU {
> + /*< private >*/
> + CPUState parent_obj;
> + /*< public >*/
> +
> + CPUArchState env;
> +} BfinCPU;
> +
> +static inline BfinCPU *bfin_env_get_cpu(CPUArchState *env)
CPUbfinState *env
> +{
> + return BFIN_CPU(container_of(env, BfinCPU, env));
I've just posted a patch to drop these FOO_CPU() casts from all targets.
While there's no ACK yet, there was agreement on v1, so please just
return the container_of() here.
> +}
> +
> +#define ENV_GET_CPU(e) CPU(bfin_env_get_cpu(e))
> +
> +#define ENV_OFFSET offsetof(BfinCPU, env)
> +
> +#endif
> diff --git a/target-bfin/cpu.c b/target-bfin/cpu.c
> new file mode 100644
> index 0000000..871a1a1
> --- /dev/null
> +++ b/target-bfin/cpu.c
> @@ -0,0 +1,55 @@
> +/*
> + * QEMU Blackfin CPU
> + *
> + * Copyright 2007-2013 Mike Frysinger
> + * Copyright 2007-2011 Analog Devices, Inc.
> + *
> + * Licensed under the Lesser GPL 2 or later.
> + */
> +
> +#include "cpu.h"
> +#include "qemu-common.h"
> +
> +
> +/* CPUClass::reset() */
> +static void bfin_cpu_reset(CPUState *s)
> +{
> + BfinCPU *cpu = BFIN_CPU(s);
> + CPUArchState *env = &cpu->env;
CPUBfinState *
Missing memset(env, 0, offsetof(CPUBfinState, breakpoints)).
> +
> + env->pc = 0xEF000000;
> +}
> +
> +static void bfin_cpu_initfn(Object *obj)
> +{
> + CPUState *cs = CPU(obj);
> + BfinCPU *cpu = BFIN_CPU(obj);
> + CPUArchState *env = &cpu->env;
> +
> + cs->env_ptr = env;
> + cpu_exec_init(env);
> +}
> +
> +static void bfin_cpu_class_init(ObjectClass *oc, void *data)
> +{
> + CPUClass *cc = CPU_CLASS(oc);
> +
> + cc->reset = bfin_cpu_reset;
> +}
> +
> +static const TypeInfo bfin_cpu_type_info = {
> + .name = TYPE_BFIN_CPU,
> + .parent = TYPE_CPU,
> + .instance_size = sizeof(BfinCPU),
> + .instance_init = bfin_cpu_initfn,
> + .abstract = false,
> + .class_size = sizeof(BfinCPUClass),
> + .class_init = bfin_cpu_class_init,
> +};
> +
> +static void bfin_cpu_register_types(void)
> +{
> + type_register_static(&bfin_cpu_type_info);
> +}
> +
> +type_init(bfin_cpu_register_types)
> diff --git a/target-bfin/cpu.h b/target-bfin/cpu.h
> new file mode 100644
> index 0000000..d288197
> --- /dev/null
> +++ b/target-bfin/cpu.h
> @@ -0,0 +1,236 @@
> +/*
> + * Blackfin emulation
> + *
> + * Copyright 2007-2013 Mike Frysinger
> + * Copyright 2007-2011 Analog Devices, Inc.
> + *
> + * Licensed under the Lesser GPL 2 or later.
> + */
> +
> +#ifndef CPU_BFIN_H
> +#define CPU_BFIN_H
> +
> +struct DisasContext;
> +
> +#define TARGET_LONG_BITS 32
> +
> +#define ELF_MACHINE EM_BLACKFIN
> +
> +#define CPUArchState struct CPUBfinState
> +
> +#include "config.h"
> +#include "qemu-common.h"
> +#include "exec/cpu-defs.h"
> +
> +#define TARGET_HAS_ICE 1
> +
> +#define EXCP_SYSCALL 0
> +#define EXCP_SOFT_BP 1
> +#define EXCP_STACK_OVERFLOW 3
> +#define EXCP_SINGLE_STEP 0x10
> +#define EXCP_TRACE_FULL 0x11
> +#define EXCP_UNDEF_INST 0x21
> +#define EXCP_ILL_INST 0x22
> +#define EXCP_DCPLB_VIOLATE 0x23
> +#define EXCP_DATA_MISALGIN 0x24
> +#define EXCP_UNRECOVERABLE 0x25
> +#define EXCP_DCPLB_MISS 0x26
> +#define EXCP_DCPLB_MULT 0x27
> +#define EXCP_EMU_WATCH 0x28
> +#define EXCP_MISALIG_INST 0x2a
> +#define EXCP_ICPLB_PROT 0x2b
> +#define EXCP_ICPLB_MISS 0x2c
> +#define EXCP_ICPLB_MULT 0x2d
> +#define EXCP_ILL_SUPV 0x2e
> +#define EXCP_ABORT 0x100
> +#define EXCP_DBGA 0x101
> +#define EXCP_OUTC 0x102
> +
> +#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_1
> +
> +#define BFIN_L1_CACHE_BYTES 32
> +
> +/* Blackfin does 1K/4K/1M/4M, but for now only support 4k */
> +#define TARGET_PAGE_BITS 12
> +#define NB_MMU_MODES 2
> +
> +#define TARGET_PHYS_ADDR_SPACE_BITS 32
> +#define TARGET_VIRT_ADDR_SPACE_BITS 32
> +
> +#define cpu_init cpu_bfin_init
> +#define cpu_exec cpu_bfin_exec
> +#define cpu_gen_code cpu_bfin_gen_code
> +#define cpu_signal_handler cpu_bfin_signal_handler
> +
> +/* Indexes into astat array; matches bitpos in hardware too */
> +enum {
> + ASTAT_AZ = 0,
> + ASTAT_AN,
> + ASTAT_AC0_COPY,
> + ASTAT_V_COPY,
> + ASTAT_CC = 5,
> + ASTAT_AQ,
> + ASTAT_RND_MOD = 8,
> + ASTAT_AC0 = 12,
> + ASTAT_AC1,
> + ASTAT_AV0 = 16,
> + ASTAT_AV0S,
> + ASTAT_AV1,
> + ASTAT_AV1S,
> + ASTAT_V = 24,
> + ASTAT_VS
> +};
> +
> +typedef struct CPUBfinState {
> + CPU_COMMON
> + int personality;
> +
> + uint32_t dreg[8];
> + uint32_t preg[8];
> + uint32_t ireg[4];
> + uint32_t mreg[4];
> + uint32_t breg[4];
> + uint32_t lreg[4];
> + uint64_t areg[2];
> + uint32_t rets;
> + uint32_t lcreg[2], ltreg[2], lbreg[2];
> + uint32_t cycles[2];
> + uint32_t uspreg;
> + uint32_t seqstat;
> + uint32_t syscfg;
> + uint32_t reti;
> + uint32_t retx;
> + uint32_t retn;
> + uint32_t rete;
> + uint32_t emudat;
> + uint32_t pc;
> +
> + /* ASTAT bits; broken up for speeeeeeeed */
> + uint32_t astat[32];
> + /* ASTAT delayed helpers */
> + uint32_t astat_op, astat_arg[3];
Are you sure this field placement is what you want? Usually reset
memset()s all fields up to breakpoints (inside CPU_COMMON) so registers
are usually placed before CPU_COMMON.
Any field that is not a register accessed by TCG should rather be in
BlackfinCPU or BlackfinCPUClass - personality sounds like a candidate?
> +} CPUBfinState;
> +#define spreg preg[6]
> +#define fpreg preg[7]
> +
> +static inline uint32_t bfin_astat_read(CPUArchState *env)
> +{
> + unsigned int i, ret;
> +
> + ret = 0;
> + for (i = 0; i < 32; ++i)
> + ret |= (env->astat[i] << i);
> +
> + return ret;
> +}
> +
> +static inline void bfin_astat_write(CPUArchState *env, uint32_t astat)
> +{
> + unsigned int i;
> + for (i = 0; i < 32; ++i)
> + env->astat[i] = !!(astat & (1 << i));
> +}
> +
> +enum astat_ops {
> + ASTAT_OP_NONE,
> + ASTAT_OP_DYNAMIC,
> + ASTAT_OP_ABS,
> + ASTAT_OP_ABS_VECTOR,
> + ASTAT_OP_ADD16,
> + ASTAT_OP_ADD32,
> + ASTAT_OP_ASHIFT16,
> + ASTAT_OP_ASHIFT32,
> + ASTAT_OP_COMPARE_SIGNED,
> + ASTAT_OP_COMPARE_UNSIGNED,
> + ASTAT_OP_LOGICAL,
> + ASTAT_OP_LSHIFT16,
> + ASTAT_OP_LSHIFT32,
> + ASTAT_OP_LSHIFT_RT16,
> + ASTAT_OP_LSHIFT_RT32,
> + ASTAT_OP_MIN_MAX,
> + ASTAT_OP_MIN_MAX_VECTOR,
> + ASTAT_OP_NEGATE,
> + ASTAT_OP_SUB16,
> + ASTAT_OP_SUB32,
> + ASTAT_OP_VECTOR_ADD_ADD, /* +|+ */
> + ASTAT_OP_VECTOR_ADD_SUB, /* +|- */
> + ASTAT_OP_VECTOR_SUB_SUB, /* -|- */
> + ASTAT_OP_VECTOR_SUB_ADD, /* -|+ */
> +};
> +
> +typedef void (*hwloop_callback)(struct DisasContext *dc, int loop);
> +
> +typedef struct DisasContext {
> + CPUArchState *env;
> + struct TranslationBlock *tb;
> + /* The current PC we're decoding (could be middle of parallel insn) */
> + target_ulong pc;
> + /* Length of current insn (2/4/8) */
> + target_ulong insn_len;
> +
> + /* For delayed ASTAT handling */
> + enum astat_ops astat_op;
> +
> + /* For hardware loop processing */
> + hwloop_callback hwloop_callback;
> + void *hwloop_data;
> +
> + /* Was a DISALGNEXCPT used in this parallel insn ? */
> + int disalgnexcpt;
> +
> + int is_jmp;
> + int mem_idx;
> +} DisasContext;
> +
> +void do_interrupt(CPUArchState *env);
do_interrupt() has recently been converted to a CPUClass hook.
> +CPUArchState *cpu_init(const char *cpu_model);
> +int cpu_exec(CPUArchState *s);
> +int cpu_bfin_signal_handler(int host_signum, void *pinfo, void *puc);
> +
> +extern const char * const greg_names[];
> +extern const char *get_allreg_name(int grp, int reg);
> +
> +#define MMU_KERNEL_IDX 0
> +#define MMU_USER_IDX 1
> +
> +int cpu_bfin_handle_mmu_fault(CPUArchState *env, target_ulong address, int rw,
> + int mmu_idx);
> +#define cpu_handle_mmu_fault cpu_bfin_handle_mmu_fault
> +
> +#if defined(CONFIG_USER_ONLY)
> +static inline void cpu_clone_regs(CPUArchState *env, target_ulong newsp)
> +{
> + if (newsp)
> + env->spreg = newsp;
> +}
> +#endif
Note there's a pending patch moving cpu_clone_regs() to
linux-user/*/target_cpu.h.
> +
> +#include "exec/cpu-all.h"
> +#include "cpu-qom.h"
> +
> +static inline bool cpu_has_work(CPUState *cpu)
> +{
> + return (cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
> +}
> +
> +#include "exec/exec-all.h"
> +
> +static inline void cpu_pc_from_tb(CPUArchState *env, TranslationBlock *tb)
> +{
> + env->pc = tb->pc;
> +}
> +
> +static inline target_ulong cpu_get_pc(CPUArchState *env)
> +{
> + return env->pc;
> +}
Unused?
> +
> +static inline void cpu_get_tb_cpu_state(CPUArchState *env, target_ulong *pc,
> + target_ulong *cs_base, int *flags)
> +{
> + *pc = cpu_get_pc(env);
> + *cs_base = 0;
> + *flags = env->astat[ASTAT_RND_MOD];
> +}
> +
> +#endif
[...]
> diff --git a/target-bfin/translate.c b/target-bfin/translate.c
> new file mode 100644
> index 0000000..a619f66
> --- /dev/null
> +++ b/target-bfin/translate.c
[...]
> +
> +CPUArchState *cpu_init(const char *cpu_model)
> +{
> + BfinCPU *cpu;
> + CPUArchState *env;
> + static int tcg_initialized = 0;
> +
> + cpu = BFIN_CPU(object_new(TYPE_BFIN_CPU));
> + env = &cpu->env;
> +
> + cpu_reset(CPU(cpu));
> + qemu_init_vcpu(env);
> +
> + if (tcg_initialized)
> + return env;
> +
> + tcg_initialized = 1;
Please place this into the CPU realizefn. Note that qemu_init_vcpu() is
being moved to generic code with my next pull.
In light of possible bfin-softmmu support, please turn this function
into BlackfinCPU *cpu_bfin_init(const char *cpu_model) and place
cpu_init() as a static inline compatibility wrapper into cpu.h.
> +
> +#define GEN_HELPER 2
> +#include "helper.h"
> +
> + cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
> +
> + cpu_pc = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUArchState, pc), "PC");
> + cpu_cc = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUArchState, astat[ASTAT_CC]), "CC");
> +
> + /*cpu_astat_op = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUArchState, astat_op), "astat_op");*/
> + cpu_astat_arg[0] = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUArchState, astat_arg[0]), "astat_arg[0]");
> + cpu_astat_arg[1] = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUArchState, astat_arg[1]), "astat_arg[1]");
> + cpu_astat_arg[2] = tcg_global_mem_new(TCG_AREG0,
> + offsetof(CPUArchState, astat_arg[2]), "astat_arg[2]");
> +
> + cpu_areg[0] = tcg_global_mem_new_i64(TCG_AREG0,
> + offsetof(CPUArchState, areg[0]), "A0");
> + cpu_areg[1] = tcg_global_mem_new_i64(TCG_AREG0,
> + offsetof(CPUArchState, areg[1]), "A1");
> +
> + bfin_tcg_new_set(dreg, 0);
> + bfin_tcg_new_set(preg, 8);
> + bfin_tcg_new_set(ireg, 16);
> + bfin_tcg_new_set(mreg, 20);
> + bfin_tcg_new_set(breg, 24);
> + bfin_tcg_new_set(lreg, 28);
> + bfin_tcg_new(rets, 39);
> + bfin_tcg_new(lcreg[0], 48);
> + bfin_tcg_new(ltreg[0], 49);
> + bfin_tcg_new(lbreg[0], 50);
> + bfin_tcg_new(lcreg[1], 51);
> + bfin_tcg_new(ltreg[1], 52);
> + bfin_tcg_new(lbreg[1], 53);
> + bfin_tcg_new_set(cycles, 54);
> + bfin_tcg_new(uspreg, 56);
> + bfin_tcg_new(seqstat, 57);
> + bfin_tcg_new(syscfg, 58);
> + bfin_tcg_new(reti, 59);
> + bfin_tcg_new(retx, 60);
> + bfin_tcg_new(retn, 61);
> + bfin_tcg_new(rete, 62);
> + bfin_tcg_new(emudat, 63);
> +
> + return env;
> +}
> +
> +#define _astat_printf(bit) cpu_fprintf(f, "%s" #bit " ", (env->astat[ASTAT_##bit] ? "" : "~"))
> +void cpu_dump_state(CPUArchState *env, FILE *f,
> + int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
> + int flags)
> +{
This will be converted to a CPUClass hook in my next pull.
[...]
> +static void
> +gen_intermediate_code_internal(CPUArchState *env, TranslationBlock *tb,
> + int search_pc)
> +{
Please use BlackfinCPU and bool arguments here, I am about to convert
all other targets (github.com/afaerber/qemu-cpu.git qom-cpu-11).
[...]
> +
> +void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb)
> +{
> + gen_intermediate_code_internal(env, tb, 0);
> +}
> +
> +void gen_intermediate_code_pc(CPUArchState *env, struct TranslationBlock *tb)
> +{
> + gen_intermediate_code_internal(env, tb, 1);
> +}
> +
> +void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb, int pc_pos)
> +{
> + env->pc = tcg_ctx.gen_opc_pc[pc_pos];
> +}
> +
> +#include "bfin-sim.c"
Regards,
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-06-28 14:24 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-17 7:13 [Qemu-devel] [PATCH 0/5] Initial Blackfin support (linux-user only) Mike Frysinger
2013-06-17 7:13 ` [Qemu-devel] [PATCH 1/5] Blackfin: add disassembler support Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 4/5] Blackfin: add test suite Mike Frysinger
2013-06-17 7:16 ` [Qemu-devel] [PATCH 5/5] linux-user: add support for Blackfin syscalls Mike Frysinger
2013-06-25 21:23 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Richard Henderson
2013-06-25 23:14 ` Mike Frysinger
2013-06-28 13:47 ` Eric Blake
2013-06-28 14:24 ` Andreas Färber
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).