diff options
author | Andrew Bennett <andrew.bennett@imgtec.com> | 2015-09-25 15:52:18 +0100 |
---|---|---|
committer | Andrew Bennett <andrew.bennett@imgtec.com> | 2015-09-25 15:52:18 +0100 |
commit | 8e394ffc7ab691eafcf276d7ae578454a8c5548f (patch) | |
tree | 309466c282f5b0adc8a27e5f8fa3b6a6f2e64ee0 /sim/mips/mips3264r2.igen | |
parent | 8a9e7a9121490a8c64d8c17f5be510e43104f6d9 (diff) | |
download | fsf-binutils-gdb-8e394ffc7ab691eafcf276d7ae578454a8c5548f.zip fsf-binutils-gdb-8e394ffc7ab691eafcf276d7ae578454a8c5548f.tar.gz fsf-binutils-gdb-8e394ffc7ab691eafcf276d7ae578454a8c5548f.tar.bz2 |
[PATCH] Add micromips support to the MIPS simulator
2015-09-25 Andrew Bennett <andrew.bennett@imgtec.com>
Ali Lown <ali.lown@imgtec.com>
sim/common/
* sim-bits.h (EXTEND6): New macro.
(EXTEND12): New macro.
(EXTEND25): New macro.
sim/mips/
* Makefile.in (tmp-micromips): New rule.
(tmp-mach-multi): Add support for micromips.
* configure.ac (mips*-sde-elf* | mips*-mti-elf*): Made a multi sim
that works for both mips64 and micromips64.
(mipsisa32r2*-*-*): Made a multi sim that works for mips32 and
micromips32.
Add build support for micromips.
* dsp.igen (do_ph_s_absq, do_w_s_absq, do_qb_s_absq, do_addsc,
do_addwc, do_bitrev, do_extpv, do_extrv, do_extrv_s_h, do_insv,
do_lxx do_modsub, do_mthlip, do_mulsaq_s_w_ph, do_ph_packrl, do_qb_pick
do_ph_pick, do_qb_ph_precequ, do_qb_ph_preceu, do_w_preceq
do_w_ph_precrq, do_ph_qb_precrq, do_w_ph_rs_precrq do_qb_w_raddu,
do_rddsp, do_repl, do_shilov, do_ph_shl, do_qb_shl do_w_s_shllv,
do_ph_shrlv, do_w_r_shrav, do_wrdsp, do_qb_shrav, do_append,
do_balign, do_ph_w_mulsa, do_ph_qb_precr, do_prepend): New functions.
Refactored instruction code to use these functions.
* dsp2.igen: Refactored instruction code to use the new functions.
* interp.c (decode_coproc): Refactored to work with any instruction
encoding.
(isa_mode): New variable
(RSVD_INSTRUCTION): Changed to 0x00000039.
* m16.igen (BREAK16): Refactored instruction to use do_break16.
(JALX32): Add mips32, mips64, mips32r2 and mips64r2 models.
* micromips.dc: New file.
* micromips.igen: New file.
* micromips16.dc: New file.
* micromipsdsp.igen: New file.
* micromipsrun.c: New file.
* mips.igen (do_swc1): Changed to work with any instruction encoding.
(do_add do_addi do_andi do_dadd do_daddi do_dsll32 do_dsra32
do_dsrl32, do_dsub, do_break, do_break16, do_clo, do_clz, do_dclo
do_dclz, do_lb, do_lh, do_lwr, do_lwl, do_lwc, do_lw, do_lwu, do_lhu
do_ldc, do_lbu, do_ll, do_lld, do_lui, do_madd, do_dsp_madd, do_maddu
do_dsp_maddu, do_dsp_mfhi, do_dsp_mflo, do_movn, do_movz, do_msub
do_dsp_msub, do_msubu, do_dsp_msubu, do_mthi, do_dsp_mthi, do_mtlo
do_dsp_mtlo, do_mul, do_dsp_mult, do_dsp_multu, do_pref, do_sc, do_scd
do_sub, do_sw, do_teq, do_teqi, do_tge, do_tgei, do_tgeiu, do_tgeu, do_tlt
do_tlti, do_tltiu, do_tltu, do_tne, do_tnei, do_abs_fmt, do_add_fmt
do_alnv_ps, do_c_cond_fmt, do_ceil_fmt, do_cfc1, do_ctc1, do_cvt_d_fmt
do_cvt_l_fmt, do_cvt_ps_s, do_cvt_s_fmt, do_cvt_s_pl, do_cvt_s_pu
do_cvt_w_fmt, do_div_fmt, do_dmfc1b, do_dmtc1b, do_floor_fmt, do_luxc1_32
do_luxc1_64, do_lwc1, do_lwxc1, do_madd_fmt, do_mfc1b, do_mov_fmt, do_movtf
do_movtf_fmt, do_movn_fmt, do_movz_fmt, do_msub_fmt, do_mtc1b, do_mul_fmt
do_neg_fmt, do_nmadd_fmt, do_nmsub_fmt, do_pll_ps, do_plu_ps, do_pul_ps
do_puu_ps, do_recip_fmt, do_round_fmt, do_rsqrt_fmt, do_prefx, do_sdc1
do_suxc1_32, do_suxc1_64, do_sqrt_fmt, do_sub_fmt, do_swc1, do_swxc1
do_trunc_fmt): New functions, refactored from existing instructions.
Refactored instruction code to use these functions.
(RSVD): Changed to use new reserved instruction.
(loadstore_ea, not_word_value, unpredictable, check_mt_hilo, check_mf_hilo,
check_mult_hilo, check_div_hilo, check_u64, do_luxc1_32, do_sdc1, do_suxc1_32,
check_fmt_p, check_fpu, do_load_double, do_store_double): Added micromips32
and micromips64 models.
Added include for micromips.igen and micromipsdsp.igen
Add micromips32 and micromips64 models.
(DecodeCoproc): Updated to use new macro definition.
* mips3264r2.igen (do_dsbh, do_dshd, do_dext, do_dextm, do_dextu, do_di,
do_dins, do_dinsm, do_ei, do_ext, do_mfhc1, do_mthc1, do_ins, do_dinsu,
do_seb, do_seh do_rdhwr, do_wsbh): New functions.
Refactored instruction code to use these functions.
* sim-main.h (CP0_operation): New enum.
(DecodeCoproc): Updated macro.
(IMEM32_MICROMIPS, IMEM16_MICROMIPS, MICROMIPS_MINOR_OPCODE,
MICROMIPS_DELAYSLOT_SIZE_ANY, MICROMIPS_DELAYSLOT_SIZE_16, MICROMIPS_DELAYSLOT_SIZE_32,
ISA_MODE_MIPS32 and ISA_MODE_MICROMIPS): New defines.
(sim_state): Add isa_mode field.
sim/testsuite/sim/mips/
* basic.exp (run_micromips_test, run_sim_tests): New functions
Add support for micromips tests.
* hilo-hazard-4.s: New file.
* testutils.inc (_dowrite): Changed reserved instruction encoding.
(writemsg): Moved the la and li instructions before the data they are
assigned to, which prevents a bug where MIPS32 relocations are used instead
of micromips relocations when building for micromips.
Diffstat (limited to 'sim/mips/mips3264r2.igen')
-rw-r--r-- | sim/mips/mips3264r2.igen | 290 |
1 files changed, 189 insertions, 101 deletions
diff --git a/sim/mips/mips3264r2.igen b/sim/mips/mips3264r2.igen index 90ad554..1c299c3 100644 --- a/sim/mips/mips3264r2.igen +++ b/sim/mips/mips3264r2.igen @@ -4,7 +4,7 @@ // Copyright (C) 2004-2015 Free Software Foundation, Inc. // Contributed by David Ung, of MIPS Technologies. // -// This file is part of GDB, the GNU debugger. +// This file is part of the MIPS sim. // // 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 @@ -19,15 +19,183 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +:function:::void:do_dsbh:int rd, int rt +{ + union { unsigned64 d; unsigned16 h[4]; } u; + TRACE_ALU_INPUT1 (GPR[rt]); + u.d = GPR[rt]; + u.h[0] = SWAP_2 (u.h[0]); + u.h[1] = SWAP_2 (u.h[1]); + u.h[2] = SWAP_2 (u.h[2]); + u.h[3] = SWAP_2 (u.h[3]); + GPR[rd] = u.d; + TRACE_ALU_RESULT1 (GPR[rd]); +} + +:function:::void:do_dshd:int rd, int rt +{ + unsigned64 d; + TRACE_ALU_INPUT1 (GPR[rt]); + d = GPR[rt]; + GPR[rd] = ((d >> 48) + | (d << 48) + | ((d & 0x0000ffff00000000ULL) >> 16) + | ((d & 0x00000000ffff0000ULL) << 16)); + TRACE_ALU_RESULT1 (GPR[rd]); +} + +:function:::void:do_dext:int rt, int rs, int lsb, int size +{ + TRACE_ALU_INPUT3 (GPR[rs], lsb, size); + GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size, lsb); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_dextm:int rt, int rs, int lsb, int size +{ + TRACE_ALU_INPUT3 (GPR[rs], lsb, size); + GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size + 32, lsb); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_dextu:int rt, int rs, int lsb, int size +{ + TRACE_ALU_INPUT3 (GPR[rs], lsb, size); + GPR[rt] = EXTRACTED64 (GPR[rs], lsb + 32 + size, lsb + 32); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_di:int rt +{ + TRACE_ALU_INPUT0 (); + GPR[rt] = EXTEND32 (SR); + SR &= ~status_IE; + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_dins:int rt, int rs, int lsb, int msb +{ + TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); + if (lsb <= msb) + GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb, lsb); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_dinsm:int rt, int rs, int lsb, int msb +{ + TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); + if (lsb <= msb + 32) + GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb + 32, lsb); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_ei:int rt +{ + TRACE_ALU_INPUT0 (); + GPR[rt] = EXTEND32 (SR); + SR |= status_IE; + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_ext:int rt, int rs, int lsb, int size +{ + TRACE_ALU_INPUT3 (GPR[rs], lsb, size); + GPR[rt] = EXTEND32 (EXTRACTED32 (GPR[rs], lsb + size, lsb)); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_mfhc1:int rt, int fs +{ + check_fpu (SD_); + if (SizeFGR() == 64) + GPR[rt] = EXTEND32 (WORD64HI (FGR[fs])); + else if ((fs & 0x1) == 0) + GPR[rt] = EXTEND32 (FGR[fs + 1]); + else + { + if (STATE_VERBOSE_P(SD)) + sim_io_eprintf (SD, + "Warning: PC 0x%lx: MFHC1 32-bit use of odd FPR number\n", + (long) CIA); + GPR[rt] = EXTEND32 (0xBADF00D); + } + TRACE_ALU_RESULT (GPR[rt]); +} + +:function:::void:do_mthc1:int rt, int fs +{ + check_fpu (SD_); + if (SizeFGR() == 64) + StoreFPR (fs, fmt_uninterpreted_64, SET64HI (GPR[rt]) | VL4_8 (FGR[fs])); + else if ((fs & 0x1) == 0) + StoreFPR (fs + 1, fmt_uninterpreted_32, VL4_8 (GPR[rt])); + else + { + if (STATE_VERBOSE_P(SD)) + sim_io_eprintf (SD, + "Warning: PC 0x%lx: MTHC1 32-bit use of odd FPR number\n", + (long) CIA); + StoreFPR (fs, fmt_uninterpreted_32, 0xDEADC0DE); + } + TRACE_FP_RESULT (GPR[rt]); +} + +:function:::void:do_ins:int rt, int rs, int lsb, int msb +{ + TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); + if (lsb <= msb) + GPR[rt] = EXTEND32 (GPR[rt] ^ + ((GPR[rt] ^ (GPR[rs] << lsb)) & MASK32 (msb, lsb))); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_dinsu:int rt, int rs, int lsb, int msb +{ + TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); + if (lsb <= msb) + GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << (lsb + 32))) + & MASK64 (msb + 32, lsb + 32); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_seb:int rd, int rt +{ + TRACE_ALU_INPUT1 (GPR[rt]); + GPR[rd] = EXTEND8 (GPR[rt]); + TRACE_ALU_RESULT1 (GPR[rd]); +} + +:function:::void:do_seh:int rd, int rt +{ + TRACE_ALU_INPUT1 (GPR[rt]); + GPR[rd] = EXTEND16 (GPR[rt]); + TRACE_ALU_RESULT1 (GPR[rd]); +} + +:function:::void:do_rdhwr:int rt, int rd +{ + // Return 0 for all hardware registers currently + GPR[rt] = EXTEND32 (0); + TRACE_ALU_RESULT1 (GPR[rt]); +} + +:function:::void:do_wsbh:int rd, int rt +{ + union { unsigned32 w; unsigned16 h[2]; } u; + TRACE_ALU_INPUT1 (GPR[rt]); + u.w = GPR[rt]; + u.h[0] = SWAP_2 (u.h[0]); + u.h[1] = SWAP_2 (u.h[1]); + GPR[rd] = EXTEND32 (u.w); + TRACE_ALU_RESULT1 (GPR[rd]); +} 011111,5.RS,5.RT,5.SIZE,5.LSB,000011::64::DEXT "dext r<RT>, r<RS>, <LSB>, <SIZE+1>" *mips64r2: { check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE); - GPR[RT] = EXTRACTED64 (GPR[RS], LSB + SIZE, LSB); - TRACE_ALU_RESULT1 (GPR[RT]); + do_dext (SD_, RT, RS, LSB, SIZE); } 011111,5.RS,5.RT,5.SIZE,5.LSB,000001::64::DEXTM @@ -35,9 +203,7 @@ *mips64r2: { check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE); - GPR[RT] = EXTRACTED64 (GPR[RS], LSB + SIZE + 32, LSB); - TRACE_ALU_RESULT1 (GPR[RT]); + do_dextm (SD_, RT, RS, LSB, SIZE); } 011111,5.RS,5.RT,5.SIZE,5.LSB,000010::64::DEXTU @@ -45,9 +211,7 @@ *mips64r2: { check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE); - GPR[RT] = EXTRACTED64 (GPR[RS], LSB + 32 + SIZE, LSB + 32); - TRACE_ALU_RESULT1 (GPR[RT]); + do_dextu (SD_, RT, RS, LSB, SIZE); } @@ -57,10 +221,7 @@ *mips32r2: *mips64r2: { - TRACE_ALU_INPUT0 (); - GPR[RT] = EXTEND32 (SR); - SR &= ~status_IE; - TRACE_ALU_RESULT1 (GPR[RT]); + do_di (SD_, RT); } @@ -69,10 +230,7 @@ *mips64r2: { check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB); - if (LSB <= MSB) - GPR[RT] ^= (GPR[RT] ^ (GPR[RS] << LSB)) & MASK64 (MSB, LSB); - TRACE_ALU_RESULT1 (GPR[RT]); + do_dins (SD_, RT, RS, LSB, MSB); } 011111,5.RS,5.RT,5.MSB,5.LSB,000101::64::DINSM @@ -80,10 +238,7 @@ *mips64r2: { check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB); - if (LSB <= MSB + 32) - GPR[RT] ^= (GPR[RT] ^ (GPR[RS] << LSB)) & MASK64 (MSB + 32, LSB); - TRACE_ALU_RESULT1 (GPR[RT]); + do_dinsm (SD_, RT, RS, LSB, MSB); } 011111,5.RS,5.RT,5.MSB,5.LSB,000110::64::DINSU @@ -91,11 +246,7 @@ *mips64r2: { check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB); - if (LSB <= MSB) - GPR[RT] ^= (GPR[RT] ^ (GPR[RS] << (LSB + 32))) - & MASK64 (MSB + 32, LSB + 32); - TRACE_ALU_RESULT1 (GPR[RT]); + do_dinsu (SD_, RT, RS, LSB, MSB); } @@ -103,44 +254,25 @@ "dsbh r<RD>, r<RT>" *mips64r2: { - union { unsigned64 d; unsigned16 h[4]; } u; check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT1 (GPR[RT]); - u.d = GPR[RT]; - u.h[0] = SWAP_2 (u.h[0]); - u.h[1] = SWAP_2 (u.h[1]); - u.h[2] = SWAP_2 (u.h[2]); - u.h[3] = SWAP_2 (u.h[3]); - GPR[RD] = u.d; - TRACE_ALU_RESULT1 (GPR[RD]); + do_dsbh (SD_, RD, RT); } 011111,00000,5.RT,5.RD,00101,100100::64::DSHD "dshd r<RD>, r<RT>" *mips64r2: { - unsigned64 d; check_u64 (SD_, instruction_0); - TRACE_ALU_INPUT1 (GPR[RT]); - d = GPR[RT]; - GPR[RD] = ((d >> 48) - | (d << 48) - | ((d & 0x0000ffff00000000ULL) >> 16) - | ((d & 0x00000000ffff0000ULL) << 16)); - TRACE_ALU_RESULT1 (GPR[RD]); + do_dshd (SD_, RD, RT); } - 010000,01011,5.RT,01100,00000,1,00,000::32::EI "ei":RT == 0 "ei r<RT>" *mips32r2: *mips64r2: { - TRACE_ALU_INPUT0 (); - GPR[RT] = EXTEND32 (SR); - SR |= status_IE; - TRACE_ALU_RESULT1 (GPR[RT]); + do_ei (SD_, RT); } @@ -149,9 +281,7 @@ *mips32r2: *mips64r2: { - TRACE_ALU_INPUT3 (GPR[RS], LSB, SIZE); - GPR[RT] = EXTEND32 (EXTRACTED32 (GPR[RS], LSB + SIZE, LSB)); - TRACE_ALU_RESULT1 (GPR[RT]); + do_ext (SD_, RT, RS, LSB, SIZE); } @@ -160,20 +290,7 @@ *mips32r2: *mips64r2: { - check_fpu (SD_); - if (SizeFGR() == 64) - GPR[RT] = EXTEND32 (WORD64HI (FGR[FS])); - else if ((FS & 0x1) == 0) - GPR[RT] = EXTEND32 (FGR[FS + 1]); - else - { - if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, - "Warning: PC 0x%lx: MFHC1 32-bit use of odd FPR number\n", - (long) CIA); - GPR[RT] = EXTEND32 (0xBADF00D); - } - TRACE_ALU_RESULT (GPR[RT]); + do_mfhc1 (SD_, RT, FS); } 010001,00111,5.RT,5.FS,00000000000:COP1Sa:32,f::MTHC1 @@ -181,20 +298,7 @@ *mips32r2: *mips64r2: { - check_fpu (SD_); - if (SizeFGR() == 64) - StoreFPR (FS, fmt_uninterpreted_64, SET64HI (GPR[RT]) | VL4_8 (FGR[FS])); - else if ((FS & 0x1) == 0) - StoreFPR (FS + 1, fmt_uninterpreted_32, VL4_8 (GPR[RT])); - else - { - if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, - "Warning: PC 0x%lx: MTHC1 32-bit use of odd FPR number\n", - (long) CIA); - StoreFPR (FS, fmt_uninterpreted_32, 0xDEADC0DE); - } - TRACE_FP_RESULT (GPR[RT]); + do_mthc1 (SD_, RT, FS); } @@ -203,11 +307,7 @@ *mips32r2: *mips64r2: { - TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], LSB, MSB); - if (LSB <= MSB) - GPR[RT] = EXTEND32 (GPR[RT] ^ - ((GPR[RT] ^ (GPR[RS] << LSB)) & MASK32 (MSB, LSB))); - TRACE_ALU_RESULT1 (GPR[RT]); + do_ins (SD_, RT, RS, LSB, MSB); } @@ -216,9 +316,7 @@ *mips32r2: *mips64r2: { - TRACE_ALU_INPUT1 (GPR[RT]); - GPR[RD] = EXTEND8 (GPR[RT]); - TRACE_ALU_RESULT1 (GPR[RD]); + do_seb (SD_, RD, RT); } 011111,00000,5.RT,5.RD,11000,100000::32::SEH @@ -226,9 +324,7 @@ *mips32r2: *mips64r2: { - TRACE_ALU_INPUT1 (GPR[RT]); - GPR[RD] = EXTEND16 (GPR[RT]); - TRACE_ALU_RESULT1 (GPR[RD]); + do_seh (SD_, RD, RT); } @@ -246,9 +342,7 @@ *mips32r2: *mips64r2: { - // Return 0 for all hardware registers currently - GPR[RT] = EXTEND32 (0); - TRACE_ALU_RESULT1 (GPR[RT]); + do_rdhwr (SD_, RT, RD); } @@ -257,13 +351,7 @@ *mips32r2: *mips64r2: { - union { unsigned32 w; unsigned16 h[2]; } u; - TRACE_ALU_INPUT1 (GPR[RT]); - u.w = GPR[RT]; - u.h[0] = SWAP_2 (u.h[0]); - u.h[1] = SWAP_2 (u.h[1]); - GPR[RD] = EXTEND32 (u.w); - TRACE_ALU_RESULT1 (GPR[RD]); + do_wsbh (SD_, RD, RT); } |