mirror of https://gitee.com/openkylin/qemu.git
Merge remote-tracking branch 'remotes/lalrae/tags/mips-20141015' into staging
* remotes/lalrae/tags/mips-20141015: (28 commits) target-mips: Remove unused gen_load_ACX, gen_store_ACX and cpu_ACX target-mips/dsp_helper.c: Add ifdef guards around various functions target-mips/translate.c: Add ifdef guard around check_mips64() target-mips/op_helper.c: Remove unused do_lbu() function target-mips/dsp_helper.c: Remove unused function get_DSPControl_24() target-mips: fix broken MIPS16 and microMIPS target-mips/translate.c: Update OPC_SYNCI target-mips: define a new generic CPU supporting MIPS64 Release 6 ISA mips_malta: update malta's pseudo-bootloader - replace JR with JALR target-mips: remove JR, BLTZAL, BGEZAL and add NAL, BAL instructions target-mips: do not allow Status.FR=0 mode in 64-bit FPU target-mips: add new Floating Point Comparison instructions target-mips: add new Floating Point instructions softfloat: add functions corresponding to IEEE-2008 min/maxNumMag target-mips: add AUI, LSA and PCREL instruction families target-mips: add compact and CP1 branches target-mips: add ALIGN, DALIGN, BITSWAP and DBITSWAP instructions target-mips: Status.UX/SX/KX enable 32-bit address wrapping target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6 target-mips: redefine Integer Multiply and Divide instructions ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
31cc9514a5
211
disas/mips.c
211
disas/mips.c
|
@ -119,6 +119,8 @@ see <http://www.gnu.org/licenses/>. */
|
|||
#define OP_SH_IMMEDIATE 0
|
||||
#define OP_MASK_DELTA 0xffff
|
||||
#define OP_SH_DELTA 0
|
||||
#define OP_MASK_DELTA_R6 0x1ff
|
||||
#define OP_SH_DELTA_R6 7
|
||||
#define OP_MASK_FUNCT 0x3f
|
||||
#define OP_SH_FUNCT 0
|
||||
#define OP_MASK_SPEC 0x3f
|
||||
|
@ -405,6 +407,12 @@ struct mips_opcode
|
|||
"+3" UDI immediate bits 6-20
|
||||
"+4" UDI immediate bits 6-25
|
||||
|
||||
R6 immediates/displacements :
|
||||
(adding suffix to 'o' to avoid adding new characters)
|
||||
"+o" 9 bits immediate/displacement (shift = 7)
|
||||
"+o1" 18 bits immediate/displacement (shift = 0)
|
||||
"+o2" 19 bits immediate/displacement (shift = 0)
|
||||
|
||||
Other:
|
||||
"()" parens surrounding optional value
|
||||
"," separates operands
|
||||
|
@ -521,6 +529,8 @@ struct mips_opcode
|
|||
#define INSN_ISA64 0x00000040
|
||||
#define INSN_ISA32R2 0x00000080
|
||||
#define INSN_ISA64R2 0x00000100
|
||||
#define INSN_ISA32R6 0x00000200
|
||||
#define INSN_ISA64R6 0x00000400
|
||||
|
||||
/* Masks used for MIPS-defined ASEs. */
|
||||
#define INSN_ASE_MASK 0x0000f000
|
||||
|
@ -585,6 +595,8 @@ struct mips_opcode
|
|||
#define ISA_MIPS32R2 (ISA_MIPS32 | INSN_ISA32R2)
|
||||
#define ISA_MIPS64R2 (ISA_MIPS64 | INSN_ISA32R2 | INSN_ISA64R2)
|
||||
|
||||
#define ISA_MIPS32R6 (ISA_MIPS32R2 | INSN_ISA32R6)
|
||||
#define ISA_MIPS64R6 (ISA_MIPS64R2 | INSN_ISA32R6 | INSN_ISA64R6)
|
||||
|
||||
/* CPU defines, use instead of hardcoding processor number. Keep this
|
||||
in sync with bfd/archures.c in order for machine selection to work. */
|
||||
|
@ -1121,6 +1133,8 @@ extern const int bfd_mips16_num_opcodes;
|
|||
#define I64 INSN_ISA64
|
||||
#define I33 INSN_ISA32R2
|
||||
#define I65 INSN_ISA64R2
|
||||
#define I32R6 INSN_ISA32R6
|
||||
#define I64R6 INSN_ISA64R6
|
||||
|
||||
/* MIPS64 MIPS-3D ASE support. */
|
||||
#define I16 INSN_MIPS16
|
||||
|
@ -1209,6 +1223,146 @@ const struct mips_opcode mips_builtin_opcodes[] =
|
|||
them first. The assemblers uses a hash table based on the
|
||||
instruction name anyhow. */
|
||||
/* name, args, match, mask, pinfo, membership */
|
||||
{"lwpc", "s,+o2", 0xec080000, 0xfc180000, WR_d, 0, I32R6},
|
||||
{"lwupc", "s,+o2", 0xec100000, 0xfc180000, WR_d, 0, I64R6},
|
||||
{"ldpc", "s,+o1", 0xec180000, 0xfc1c0000, WR_d, 0, I64R6},
|
||||
{"addiupc", "s,+o2", 0xec000000, 0xfc180000, WR_d, 0, I32R6},
|
||||
{"auipc", "s,u", 0xec1e0000, 0xfc1f0000, WR_d, 0, I32R6},
|
||||
{"aluipc", "s,u", 0xec1f0000, 0xfc1f0000, WR_d, 0, I32R6},
|
||||
{"daui", "s,t,u", 0x74000000, 0xfc000000, RD_s|WR_t, 0, I64R6},
|
||||
{"dahi", "s,u", 0x04060000, 0xfc1f0000, RD_s, 0, I64R6},
|
||||
{"dati", "s,u", 0x041e0000, 0xfc1f0000, RD_s, 0, I64R6},
|
||||
{"lsa", "d,s,t", 0x00000005, 0xfc00073f, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"dlsa", "d,s,t", 0x00000015, 0xfc00073f, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"clz", "U,s", 0x00000050, 0xfc1f07ff, WR_d|RD_s, 0, I32R6},
|
||||
{"clo", "U,s", 0x00000051, 0xfc1f07ff, WR_d|RD_s, 0, I32R6},
|
||||
{"dclz", "U,s", 0x00000052, 0xfc1f07ff, WR_d|RD_s, 0, I64R6},
|
||||
{"dclo", "U,s", 0x00000053, 0xfc1f07ff, WR_d|RD_s, 0, I64R6},
|
||||
{"sdbbp", "B", 0x0000000e, 0xfc00003f, TRAP, 0, I32R6},
|
||||
{"mul", "d,s,t", 0x00000098, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"muh", "d,s,t", 0x000000d8, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"mulu", "d,s,t", 0x00000099, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"muhu", "d,s,t", 0x000000d9, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"div", "d,s,t", 0x0000009a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"mod", "d,s,t", 0x000000da, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"divu", "d,s,t", 0x0000009b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"modu", "d,s,t", 0x000000db, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"dmul", "d,s,t", 0x0000009c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"dmuh", "d,s,t", 0x000000dc, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"dmulu", "d,s,t", 0x0000009d, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"dmuhu", "d,s,t", 0x000000dd, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"ddiv", "d,s,t", 0x0000009e, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"dmod", "d,s,t", 0x000000de, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"ddivu", "d,s,t", 0x0000009f, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"dmodu", "d,s,t", 0x000000df, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"ll", "t,o(b)", 0x7c000036, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6},
|
||||
{"sc", "t,o(b)", 0x7c000026, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6},
|
||||
{"lld", "t,o(b)", 0x7c000037, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6},
|
||||
{"scd", "t,o(b)", 0x7c000027, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6},
|
||||
{"pref", "h,o(b)", 0x7c000035, 0xfc00007f, RD_b, 0, I32R6},
|
||||
{"cache", "k,o(b)", 0x7c000025, 0xfc00007f, RD_b, 0, I32R6},
|
||||
{"seleqz", "d,v,t", 0x00000035, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"selnez", "d,v,t", 0x00000037, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"maddf.s", "D,S,T", 0x46000018, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"maddf.d", "D,S,T", 0x46200018, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"msubf.s", "D,S,T", 0x46000019, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"msubf.d", "D,S,T", 0x46200019, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"max.s", "D,S,T", 0x4600001e, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"max.d", "D,S,T", 0x4620001e, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"maxa.s", "D,S,T", 0x4600001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"maxa.d", "D,S,T", 0x4620001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"rint.s", "D,S", 0x4600001a, 0xffff003f, WR_D|RD_S|FP_S, 0, I32R6},
|
||||
{"rint.d", "D,S", 0x4620001a, 0xffff003f, WR_D|RD_S|FP_D, 0, I32R6},
|
||||
{"class.s", "D,S", 0x4600001b, 0xffff003f, WR_D|RD_S|FP_S, 0, I32R6},
|
||||
{"class.d", "D,S", 0x4620001b, 0xffff003f, WR_D|RD_S|FP_D, 0, I32R6},
|
||||
{"min.s", "D,S,T", 0x4600001c, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"min.d", "D,S,T", 0x4620001c, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"mina.s", "D,S,T", 0x4600001d, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"mina.d", "D,S,T", 0x4620001d, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"sel.s", "D,S,T", 0x46000010, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"sel.d", "D,S,T", 0x46200010, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"seleqz.s", "D,S,T", 0x46000014, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"seleqz.d", "D,S,T", 0x46200014, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"selnez.s", "D,S,T", 0x46000017, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},
|
||||
{"selnez.d", "D,S,T", 0x46200017, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I32R6},
|
||||
{"align", "d,v,t", 0x7c000220, 0xfc00073f, WR_d|RD_s|RD_t, 0, I32R6},
|
||||
{"dalign", "d,v,t", 0x7c000224, 0xfc00063f, WR_d|RD_s|RD_t, 0, I64R6},
|
||||
{"bitswap", "d,w", 0x7c000020, 0xffe007ff, WR_d|RD_t, 0, I32R6},
|
||||
{"dbitswap","d,w", 0x7c000024, 0xffe007ff, WR_d|RD_t, 0, I64R6},
|
||||
{"balc", "+p", 0xe8000000, 0xfc000000, UBD|WR_31, 0, I32R6},
|
||||
{"bc", "+p", 0xc8000000, 0xfc000000, UBD|WR_31, 0, I32R6},
|
||||
{"jic", "t,o", 0xd8000000, 0xffe00000, UBD|RD_t, 0, I32R6},
|
||||
{"beqzc", "s,+p", 0xd8000000, 0xfc000000, CBD|RD_s, 0, I32R6},
|
||||
{"jialc", "t,o", 0xf8000000, 0xffe00000, UBD|RD_t, 0, I32R6},
|
||||
{"bnezc", "s,+p", 0xf8000000, 0xfc000000, CBD|RD_s, 0, I32R6},
|
||||
{"beqzalc", "s,t,p", 0x20000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bovc", "s,t,p", 0x20000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"beqc", "s,t,p", 0x20000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bnezalc", "s,t,p", 0x60000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bnvc", "s,t,p", 0x60000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bnec", "s,t,p", 0x60000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"blezc", "s,t,p", 0x58000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bgezc", "s,t,p", 0x58000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bgec", "s,t,p", 0x58000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bgtzc", "s,t,p", 0x5c000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bltzc", "s,t,p", 0x5c000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bltc", "s,t,p", 0x5c000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"blezalc", "s,t,p", 0x18000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bgezalc", "s,t,p", 0x18000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bgeuc", "s,t,p", 0x18000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bgtzalc", "s,t,p", 0x1c000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bltzalc", "s,t,p", 0x1c000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"bltuc", "s,t,p", 0x1c000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6},
|
||||
{"nal", "p", 0x04100000, 0xffff0000, WR_31, 0, I32R6},
|
||||
{"bal", "p", 0x04110000, 0xffff0000, UBD|WR_31, 0, I32R6},
|
||||
{"bc1eqz", "T,p", 0x45200000, 0xffe00000, CBD|RD_T|FP_S|FP_D, 0, I32R6},
|
||||
{"bc1nez", "T,p", 0x45a00000, 0xffe00000, CBD|RD_T|FP_S|FP_D, 0, I32R6},
|
||||
{"bc2eqz", "E,p", 0x49200000, 0xffe00000, CBD|RD_C2, 0, I32R6},
|
||||
{"bc2nez", "E,p", 0x49a00000, 0xffe00000, CBD|RD_C2, 0, I32R6},
|
||||
{"cmp.af.s", "D,S,T", 0x46800000, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.un.s", "D,S,T", 0x46800001, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.eq.s", "D,S,T", 0x46800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ueq.s", "D,S,T", 0x46800003, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.lt.s", "D,S,T", 0x46800004, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ult.s", "D,S,T", 0x46800005, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.le.s", "D,S,T", 0x46800006, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ule.s", "D,S,T", 0x46800007, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.saf.s", "D,S,T", 0x46800008, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sun.s", "D,S,T", 0x46800009, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.seq.s", "D,S,T", 0x4680000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sueq.s", "D,S,T", 0x4680000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.slt.s", "D,S,T", 0x4680000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sult.s", "D,S,T", 0x4680000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sle.s", "D,S,T", 0x4680000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sule.s", "D,S,T", 0x4680000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.or.s", "D,S,T", 0x46800011, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.une.s", "D,S,T", 0x46800012, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.ne.s", "D,S,T", 0x46800013, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sor.s", "D,S,T", 0x46800019, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sune.s", "D,S,T", 0x4680001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.sne.s", "D,S,T", 0x4680001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6},
|
||||
{"cmp.af.d", "D,S,T", 0x46a00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.un.d", "D,S,T", 0x46a00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.eq.d", "D,S,T", 0x46a00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ueq.d", "D,S,T", 0x46a00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.lt.d", "D,S,T", 0x46a00004, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ult.d", "D,S,T", 0x46a00005, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.le.d", "D,S,T", 0x46a00006, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ule.d", "D,S,T", 0x46a00007, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.saf.d", "D,S,T", 0x46a00008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sun.d", "D,S,T", 0x46a00009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.seq.d", "D,S,T", 0x46a0000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sueq.d", "D,S,T", 0x46a0000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.slt.d", "D,S,T", 0x46a0000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sult.d", "D,S,T", 0x46a0000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sle.d", "D,S,T", 0x46a0000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sule.d", "D,S,T", 0x46a0000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.or.d", "D,S,T", 0x46a00011, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.une.d", "D,S,T", 0x46a00012, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.ne.d", "D,S,T", 0x46a00013, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sor.d", "D,S,T", 0x46a00019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sune.d", "D,S,T", 0x46a0001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"cmp.sne.d", "D,S,T", 0x46a0001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6},
|
||||
{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4|I32|G3 },
|
||||
{"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t, 0, I4|I33 },
|
||||
{"nop", "", 0x00000000, 0xffffffff, 0, INSN2_ALIAS, I1 }, /* sll */
|
||||
|
@ -1753,6 +1907,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
|
|||
{"lld", "t,o(b)", 0xd0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 },
|
||||
{"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3 },
|
||||
{"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, 0, I1 },
|
||||
{"aui", "s,t,u", 0x3c000000, 0xfc000000, RD_s|WR_t, 0, I32R6},
|
||||
{"luxc1", "D,t(b)", 0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I5|I33|N55},
|
||||
{"lw", "t,o(b)", 0x8c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 },
|
||||
{"lw", "t,A(b)", 0, (int) M_LW_AB, INSN_MACRO, 0, I1 },
|
||||
|
@ -3575,6 +3730,42 @@ print_insn_args (const char *d,
|
|||
(*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
switch (*(d+1)) {
|
||||
case '1':
|
||||
d++;
|
||||
delta = l & ((1 << 18) - 1);
|
||||
if (delta & 0x20000) {
|
||||
delta |= ~0x1ffff;
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
d++;
|
||||
delta = l & ((1 << 19) - 1);
|
||||
if (delta & 0x40000) {
|
||||
delta |= ~0x3ffff;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
delta = (l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6;
|
||||
if (delta & 0x8000) {
|
||||
delta |= ~0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
(*info->fprintf_func) (info->stream, "%d", delta);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
/* Sign extend the displacement with 26 bits. */
|
||||
delta = (l >> OP_SH_DELTA) & OP_MASK_TARGET;
|
||||
if (delta & 0x2000000) {
|
||||
delta |= ~0x3FFFFFF;
|
||||
}
|
||||
info->target = (delta << 2) + pc + INSNLEN;
|
||||
(*info->print_address_func) (info->target, info);
|
||||
break;
|
||||
|
||||
case 't': /* Coprocessor 0 reg name */
|
||||
(*info->fprintf_func) (info->stream, "%s",
|
||||
mips_cp0_names[(l >> OP_SH_RT) &
|
||||
|
@ -3726,7 +3917,8 @@ print_insn_args (const char *d,
|
|||
|
||||
case 'j': /* Same as i, but sign-extended. */
|
||||
case 'o':
|
||||
delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
|
||||
delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
|
||||
|
||||
if (delta & 0x8000)
|
||||
delta |= ~0xffff;
|
||||
(*info->fprintf_func) (info->stream, "%d",
|
||||
|
@ -4052,6 +4244,23 @@ print_insn_mips (bfd_vma memaddr,
|
|||
&& strcmp (op->name, "jalx"))
|
||||
continue;
|
||||
|
||||
if (strcmp(op->name, "bovc") == 0
|
||||
|| strcmp(op->name, "bnvc") == 0) {
|
||||
if (((word >> OP_SH_RS) & OP_MASK_RS) <
|
||||
((word >> OP_SH_RT) & OP_MASK_RT)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (strcmp(op->name, "bgezc") == 0
|
||||
|| strcmp(op->name, "bltzc") == 0
|
||||
|| strcmp(op->name, "bgezalc") == 0
|
||||
|| strcmp(op->name, "bltzalc") == 0) {
|
||||
if (((word >> OP_SH_RS) & OP_MASK_RS) !=
|
||||
((word >> OP_SH_RT) & OP_MASK_RT)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Figure out instruction type and branch delay information. */
|
||||
if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
|
||||
{
|
||||
|
|
|
@ -7240,13 +7240,17 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
|
|||
* minnum() and maxnum correspond to the IEEE 754-2008 minNum()
|
||||
* and maxNum() operations. min() and max() are the typical min/max
|
||||
* semantics provided by many CPUs which predate that specification.
|
||||
*
|
||||
* minnummag() and maxnummag() functions correspond to minNumMag()
|
||||
* and minNumMag() from the IEEE-754 2008.
|
||||
*/
|
||||
#define MINMAX(s) \
|
||||
static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, \
|
||||
int ismin, int isieee STATUS_PARAM) \
|
||||
int ismin, int isieee, \
|
||||
int ismag STATUS_PARAM) \
|
||||
{ \
|
||||
flag aSign, bSign; \
|
||||
uint ## s ## _t av, bv; \
|
||||
uint ## s ## _t av, bv, aav, abv; \
|
||||
a = float ## s ## _squash_input_denormal(a STATUS_VAR); \
|
||||
b = float ## s ## _squash_input_denormal(b STATUS_VAR); \
|
||||
if (float ## s ## _is_any_nan(a) || \
|
||||
|
@ -7266,6 +7270,17 @@ static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, \
|
|||
bSign = extractFloat ## s ## Sign(b); \
|
||||
av = float ## s ## _val(a); \
|
||||
bv = float ## s ## _val(b); \
|
||||
if (ismag) { \
|
||||
aav = float ## s ## _abs(av); \
|
||||
abv = float ## s ## _abs(bv); \
|
||||
if (aav != abv) { \
|
||||
if (ismin) { \
|
||||
return (aav < abv) ? a : b; \
|
||||
} else { \
|
||||
return (aav < abv) ? b : a; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (aSign != bSign) { \
|
||||
if (ismin) { \
|
||||
return aSign ? a : b; \
|
||||
|
@ -7283,22 +7298,32 @@ static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, \
|
|||
\
|
||||
float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM) \
|
||||
{ \
|
||||
return float ## s ## _minmax(a, b, 1, 0 STATUS_VAR); \
|
||||
return float ## s ## _minmax(a, b, 1, 0, 0 STATUS_VAR); \
|
||||
} \
|
||||
\
|
||||
float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM) \
|
||||
{ \
|
||||
return float ## s ## _minmax(a, b, 0, 0 STATUS_VAR); \
|
||||
return float ## s ## _minmax(a, b, 0, 0, 0 STATUS_VAR); \
|
||||
} \
|
||||
\
|
||||
float ## s float ## s ## _minnum(float ## s a, float ## s b STATUS_PARAM) \
|
||||
{ \
|
||||
return float ## s ## _minmax(a, b, 1, 1 STATUS_VAR); \
|
||||
return float ## s ## _minmax(a, b, 1, 1, 0 STATUS_VAR); \
|
||||
} \
|
||||
\
|
||||
float ## s float ## s ## _maxnum(float ## s a, float ## s b STATUS_PARAM) \
|
||||
{ \
|
||||
return float ## s ## _minmax(a, b, 0, 1 STATUS_VAR); \
|
||||
return float ## s ## _minmax(a, b, 0, 1, 0 STATUS_VAR); \
|
||||
} \
|
||||
\
|
||||
float ## s float ## s ## _minnummag(float ## s a, float ## s b STATUS_PARAM) \
|
||||
{ \
|
||||
return float ## s ## _minmax(a, b, 1, 1, 1 STATUS_VAR); \
|
||||
} \
|
||||
\
|
||||
float ## s float ## s ## _maxnummag(float ## s a, float ## s b STATUS_PARAM) \
|
||||
{ \
|
||||
return float ## s ## _minmax(a, b, 0, 1, 1 STATUS_VAR); \
|
||||
}
|
||||
|
||||
MINMAX(32)
|
||||
|
|
|
@ -697,12 +697,12 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
|
|||
/* Jump to kernel code */
|
||||
stl_p(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
|
||||
stl_p(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
|
||||
stl_p(p++, 0x03e00008); /* jr ra */
|
||||
stl_p(p++, 0x03e00009); /* jalr ra */
|
||||
stl_p(p++, 0x00000000); /* nop */
|
||||
|
||||
/* YAMON subroutines */
|
||||
p = (uint32_t *) (base + 0x800);
|
||||
stl_p(p++, 0x03e00008); /* jr ra */
|
||||
stl_p(p++, 0x03e00009); /* jalr ra */
|
||||
stl_p(p++, 0x24020000); /* li v0,0 */
|
||||
/* 808 YAMON print */
|
||||
stl_p(p++, 0x03e06821); /* move t5,ra */
|
||||
|
@ -716,7 +716,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
|
|||
stl_p(p++, 0x00000000); /* nop */
|
||||
stl_p(p++, 0x08000205); /* j 814 */
|
||||
stl_p(p++, 0x00000000); /* nop */
|
||||
stl_p(p++, 0x01a00008); /* jr t5 */
|
||||
stl_p(p++, 0x01a00009); /* jalr t5 */
|
||||
stl_p(p++, 0x01602021); /* move a0,t3 */
|
||||
/* 0x83c YAMON print_count */
|
||||
stl_p(p++, 0x03e06821); /* move t5,ra */
|
||||
|
@ -730,7 +730,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
|
|||
stl_p(p++, 0x258cffff); /* addiu t4,t4,-1 */
|
||||
stl_p(p++, 0x1580fffa); /* bnez t4,84c */
|
||||
stl_p(p++, 0x00000000); /* nop */
|
||||
stl_p(p++, 0x01a00008); /* jr t5 */
|
||||
stl_p(p++, 0x01a00009); /* jalr t5 */
|
||||
stl_p(p++, 0x01602021); /* move a0,t3 */
|
||||
/* 0x870 */
|
||||
stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */
|
||||
|
@ -740,7 +740,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
|
|||
stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */
|
||||
stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
|
||||
stl_p(p++, 0x00000000); /* nop */
|
||||
stl_p(p++, 0x03e00008); /* jr ra */
|
||||
stl_p(p++, 0x03e00009); /* jalr ra */
|
||||
stl_p(p++, 0xa1040000); /* sb a0,0(t0) */
|
||||
|
||||
}
|
||||
|
|
|
@ -374,6 +374,8 @@ float32 float32_min(float32, float32 STATUS_PARAM);
|
|||
float32 float32_max(float32, float32 STATUS_PARAM);
|
||||
float32 float32_minnum(float32, float32 STATUS_PARAM);
|
||||
float32 float32_maxnum(float32, float32 STATUS_PARAM);
|
||||
float32 float32_minnummag(float32, float32 STATUS_PARAM);
|
||||
float32 float32_maxnummag(float32, float32 STATUS_PARAM);
|
||||
int float32_is_quiet_nan( float32 );
|
||||
int float32_is_signaling_nan( float32 );
|
||||
float32 float32_maybe_silence_nan( float32 );
|
||||
|
@ -484,6 +486,8 @@ float64 float64_min(float64, float64 STATUS_PARAM);
|
|||
float64 float64_max(float64, float64 STATUS_PARAM);
|
||||
float64 float64_minnum(float64, float64 STATUS_PARAM);
|
||||
float64 float64_maxnum(float64, float64 STATUS_PARAM);
|
||||
float64 float64_minnummag(float64, float64 STATUS_PARAM);
|
||||
float64 float64_maxnummag(float64, float64 STATUS_PARAM);
|
||||
int float64_is_quiet_nan( float64 a );
|
||||
int float64_is_signaling_nan( float64 );
|
||||
float64 float64_maybe_silence_nan( float64 );
|
||||
|
|
|
@ -431,7 +431,7 @@ struct CPUMIPSState {
|
|||
int error_code;
|
||||
uint32_t hflags; /* CPU State */
|
||||
/* TMASK defines different execution modes */
|
||||
#define MIPS_HFLAG_TMASK 0xC07FF
|
||||
#define MIPS_HFLAG_TMASK 0x1807FF
|
||||
#define MIPS_HFLAG_MODE 0x00007 /* execution modes */
|
||||
/* The KSU flags must be the lowest bits in hflags. The flag order
|
||||
must be the same as defined for CP0 Status. This allows to use
|
||||
|
@ -450,7 +450,7 @@ struct CPUMIPSState {
|
|||
and RSQRT.D. */
|
||||
#define MIPS_HFLAG_COP1X 0x00080 /* COP1X instructions enabled */
|
||||
#define MIPS_HFLAG_RE 0x00100 /* Reversed endianness */
|
||||
#define MIPS_HFLAG_UX 0x00200 /* 64-bit user mode */
|
||||
#define MIPS_HFLAG_AWRAP 0x00200 /* 32-bit compatibility address wrapping */
|
||||
#define MIPS_HFLAG_M16 0x00400 /* MIPS16 mode flag */
|
||||
#define MIPS_HFLAG_M16_SHIFT 10
|
||||
/* If translation is interrupted between the branch instruction and
|
||||
|
@ -463,17 +463,18 @@ struct CPUMIPSState {
|
|||
#define MIPS_HFLAG_BL 0x01800 /* Likely branch */
|
||||
#define MIPS_HFLAG_BR 0x02000 /* branch to register (can't link TB) */
|
||||
/* Extra flags about the current pending branch. */
|
||||
#define MIPS_HFLAG_BMASK_EXT 0x3C000
|
||||
#define MIPS_HFLAG_BMASK_EXT 0x7C000
|
||||
#define MIPS_HFLAG_B16 0x04000 /* branch instruction was 16 bits */
|
||||
#define MIPS_HFLAG_BDS16 0x08000 /* branch requires 16-bit delay slot */
|
||||
#define MIPS_HFLAG_BDS32 0x10000 /* branch requires 32-bit delay slot */
|
||||
#define MIPS_HFLAG_BX 0x20000 /* branch exchanges execution mode */
|
||||
#define MIPS_HFLAG_BDS_STRICT 0x20000 /* Strict delay slot size */
|
||||
#define MIPS_HFLAG_BX 0x40000 /* branch exchanges execution mode */
|
||||
#define MIPS_HFLAG_BMASK (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT)
|
||||
/* MIPS DSP resources access. */
|
||||
#define MIPS_HFLAG_DSP 0x40000 /* Enable access to MIPS DSP resources. */
|
||||
#define MIPS_HFLAG_DSPR2 0x80000 /* Enable access to MIPS DSPR2 resources. */
|
||||
#define MIPS_HFLAG_DSP 0x080000 /* Enable access to MIPS DSP resources. */
|
||||
#define MIPS_HFLAG_DSPR2 0x100000 /* Enable access to MIPS DSPR2 resources. */
|
||||
/* Extra flag about HWREna register. */
|
||||
#define MIPS_HFLAG_HWRENA_ULR 0x100000 /* ULR bit from HWREna is set. */
|
||||
#define MIPS_HFLAG_HWRENA_ULR 0x200000 /* ULR bit from HWREna is set. */
|
||||
target_ulong btarget; /* Jump / branch target */
|
||||
target_ulong bcond; /* Branch condition (if needed) */
|
||||
|
||||
|
@ -725,7 +726,7 @@ static inline void compute_hflags(CPUMIPSState *env)
|
|||
{
|
||||
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
|
||||
MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
|
||||
MIPS_HFLAG_UX | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2);
|
||||
MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2);
|
||||
if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
|
||||
!(env->CP0_Status & (1 << CP0St_ERL)) &&
|
||||
!(env->hflags & MIPS_HFLAG_DM)) {
|
||||
|
@ -737,8 +738,18 @@ static inline void compute_hflags(CPUMIPSState *env)
|
|||
(env->CP0_Status & (1 << CP0St_UX))) {
|
||||
env->hflags |= MIPS_HFLAG_64;
|
||||
}
|
||||
if (env->CP0_Status & (1 << CP0St_UX)) {
|
||||
env->hflags |= MIPS_HFLAG_UX;
|
||||
|
||||
if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
|
||||
!(env->CP0_Status & (1 << CP0St_UX))) {
|
||||
env->hflags |= MIPS_HFLAG_AWRAP;
|
||||
} else if (env->insn_flags & ISA_MIPS32R6) {
|
||||
/* Address wrapping for Supervisor and Kernel is specified in R6 */
|
||||
if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) &&
|
||||
!(env->CP0_Status & (1 << CP0St_SX))) ||
|
||||
(((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_KM) &&
|
||||
!(env->CP0_Status & (1 << CP0St_KX)))) {
|
||||
env->hflags |= MIPS_HFLAG_AWRAP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ((env->CP0_Status & (1 << CP0St_CU0)) ||
|
||||
|
|
|
@ -76,15 +76,6 @@ static inline void set_DSPControl_24(uint32_t flag, int len, CPUMIPSState *env)
|
|||
env->active_tc.DSPControl |= (target_ulong)flag << 24;
|
||||
}
|
||||
|
||||
static inline uint32_t get_DSPControl_24(int len, CPUMIPSState *env)
|
||||
{
|
||||
uint32_t filter;
|
||||
|
||||
filter = (0x01 << len) - 1;
|
||||
|
||||
return (env->active_tc.DSPControl >> 24) & filter;
|
||||
}
|
||||
|
||||
static inline void set_DSPControl_pos(uint32_t pos, CPUMIPSState *env)
|
||||
{
|
||||
target_ulong dspc;
|
||||
|
@ -283,6 +274,7 @@ static inline int32_t mipsdsp_sat32_acc_q31(int32_t acc, int32_t a,
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
/* a[0] is LO, a[1] is HI. */
|
||||
static inline void mipsdsp_sat64_acc_add_q63(int64_t *ret,
|
||||
int32_t ac,
|
||||
|
@ -336,6 +328,7 @@ static inline void mipsdsp_sat64_acc_sub_q63(int64_t *ret,
|
|||
set_DSPControl_overflow_flag(1, 16 + ac, env);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int32_t mipsdsp_mul_i16_i16(int16_t a, int16_t b,
|
||||
CPUMIPSState *env)
|
||||
|
@ -357,10 +350,12 @@ static inline int32_t mipsdsp_mul_u16_u16(int32_t a, int32_t b)
|
|||
return a * b;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
static inline int32_t mipsdsp_mul_i32_i32(int32_t a, int32_t b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int32_t mipsdsp_sat16_mul_i16_i16(int16_t a, int16_t b,
|
||||
CPUMIPSState *env)
|
||||
|
@ -417,10 +412,12 @@ static inline int16_t mipsdsp_rashift16(int16_t a, target_ulong mov)
|
|||
return a >> mov;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
static inline int32_t mipsdsp_rashift32(int32_t a, target_ulong mov)
|
||||
{
|
||||
return a >> mov;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int16_t mipsdsp_rshift1_add_q16(int16_t a, int16_t b)
|
||||
{
|
||||
|
@ -479,6 +476,7 @@ static inline uint8_t mipsdsp_rrshift1_add_u8(uint8_t a, uint8_t b)
|
|||
return (temp >> 1) & 0x00FF;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
static inline uint8_t mipsdsp_rshift1_sub_u8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t temp;
|
||||
|
@ -496,6 +494,7 @@ static inline uint8_t mipsdsp_rrshift1_sub_u8(uint8_t a, uint8_t b)
|
|||
|
||||
return (temp >> 1) & 0x00FF;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 128 bits long. p[0] is LO, p[1] is HI. */
|
||||
static inline void mipsdsp_rndrashift_short_acc(int64_t *p,
|
||||
|
@ -511,6 +510,7 @@ static inline void mipsdsp_rndrashift_short_acc(int64_t *p,
|
|||
p[1] = (acc >> 63) & 0x01;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
/* 128 bits long. p[0] is LO, p[1] is HI */
|
||||
static inline void mipsdsp_rashift_acc(uint64_t *p,
|
||||
uint32_t ac,
|
||||
|
@ -558,6 +558,7 @@ static inline void mipsdsp_rndrashift_acc(uint64_t *p,
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int32_t mipsdsp_mul_q15_q15(int32_t ac, uint16_t a, uint16_t b,
|
||||
CPUMIPSState *env)
|
||||
|
@ -608,10 +609,12 @@ static inline uint16_t mipsdsp_mul_u8_u16(uint8_t a, uint16_t b,
|
|||
return tempI & 0x0000FFFF;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
static inline uint64_t mipsdsp_mul_u32_u32(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (uint64_t)a * (uint64_t)b;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int16_t mipsdsp_rndq15_mul_q15_q15(uint16_t a, uint16_t b,
|
||||
CPUMIPSState *env)
|
||||
|
@ -717,7 +720,7 @@ static inline uint16_t mipsdsp_lshift16(uint16_t a, uint8_t s,
|
|||
return a << s;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
static inline uint32_t mipsdsp_lshift32(uint32_t a, uint8_t s,
|
||||
CPUMIPSState *env)
|
||||
{
|
||||
|
@ -734,6 +737,7 @@ static inline uint32_t mipsdsp_lshift32(uint32_t a, uint8_t s,
|
|||
return a << s;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint16_t mipsdsp_sat16_lshift(uint16_t a, uint8_t s,
|
||||
CPUMIPSState *env)
|
||||
|
@ -973,6 +977,7 @@ static inline uint8_t mipsdsp_satu8_sub(uint8_t a, uint8_t b, CPUMIPSState *env)
|
|||
return temp & 0x00FF;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
static inline uint32_t mipsdsp_sub32(int32_t a, int32_t b, CPUMIPSState *env)
|
||||
{
|
||||
int32_t temp;
|
||||
|
@ -997,6 +1002,7 @@ static inline int32_t mipsdsp_add_i32(int32_t a, int32_t b, CPUMIPSState *env)
|
|||
|
||||
return temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int32_t mipsdsp_cmp_eq(int32_t a, int32_t b)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,11 @@ DEF_HELPER_3(macchiu, tl, env, tl, tl)
|
|||
DEF_HELPER_3(msachi, tl, env, tl, tl)
|
||||
DEF_HELPER_3(msachiu, tl, env, tl, tl)
|
||||
|
||||
DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
|
||||
#ifdef TARGET_MIPS64
|
||||
DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* CP0 helpers */
|
||||
DEF_HELPER_1(mfc0_mvpcontrol, tl, env)
|
||||
|
@ -197,6 +202,25 @@ DEF_HELPER_2(float_cvtw_d, i32, env, i64)
|
|||
DEF_HELPER_3(float_addr_ps, i64, env, i64, i64)
|
||||
DEF_HELPER_3(float_mulr_ps, i64, env, i64, i64)
|
||||
|
||||
DEF_HELPER_FLAGS_1(float_class_s, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(float_class_d, TCG_CALL_NO_RWG_SE, i64, i64)
|
||||
|
||||
#define FOP_PROTO(op) \
|
||||
DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32) \
|
||||
DEF_HELPER_4(float_ ## op ## _d, i64, env, i64, i64, i64)
|
||||
FOP_PROTO(maddf)
|
||||
FOP_PROTO(msubf)
|
||||
#undef FOP_PROTO
|
||||
|
||||
#define FOP_PROTO(op) \
|
||||
DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \
|
||||
DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64)
|
||||
FOP_PROTO(max)
|
||||
FOP_PROTO(maxa)
|
||||
FOP_PROTO(min)
|
||||
FOP_PROTO(mina)
|
||||
#undef FOP_PROTO
|
||||
|
||||
#define FOP_PROTO(op) \
|
||||
DEF_HELPER_2(float_ ## op ## l_s, i64, env, i32) \
|
||||
DEF_HELPER_2(float_ ## op ## l_d, i64, env, i64) \
|
||||
|
@ -214,6 +238,7 @@ DEF_HELPER_2(float_ ## op ## _d, i64, env, i64)
|
|||
FOP_PROTO(sqrt)
|
||||
FOP_PROTO(rsqrt)
|
||||
FOP_PROTO(recip)
|
||||
FOP_PROTO(rint)
|
||||
#undef FOP_PROTO
|
||||
|
||||
#define FOP_PROTO(op) \
|
||||
|
@ -279,6 +304,33 @@ FOP_PROTO(le)
|
|||
FOP_PROTO(ngt)
|
||||
#undef FOP_PROTO
|
||||
|
||||
#define FOP_PROTO(op) \
|
||||
DEF_HELPER_3(r6_cmp_d_ ## op, i64, env, i64, i64) \
|
||||
DEF_HELPER_3(r6_cmp_s_ ## op, i32, env, i32, i32)
|
||||
FOP_PROTO(af)
|
||||
FOP_PROTO(un)
|
||||
FOP_PROTO(eq)
|
||||
FOP_PROTO(ueq)
|
||||
FOP_PROTO(lt)
|
||||
FOP_PROTO(ult)
|
||||
FOP_PROTO(le)
|
||||
FOP_PROTO(ule)
|
||||
FOP_PROTO(saf)
|
||||
FOP_PROTO(sun)
|
||||
FOP_PROTO(seq)
|
||||
FOP_PROTO(sueq)
|
||||
FOP_PROTO(slt)
|
||||
FOP_PROTO(sult)
|
||||
FOP_PROTO(sle)
|
||||
FOP_PROTO(sule)
|
||||
FOP_PROTO(or)
|
||||
FOP_PROTO(une)
|
||||
FOP_PROTO(ne)
|
||||
FOP_PROTO(sor)
|
||||
FOP_PROTO(sune)
|
||||
FOP_PROTO(sne)
|
||||
#undef FOP_PROTO
|
||||
|
||||
/* Special functions */
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
DEF_HELPER_1(tlbwi, void, env)
|
||||
|
|
|
@ -30,17 +30,21 @@
|
|||
#define ISA_MIPS64 0x00000080
|
||||
#define ISA_MIPS64R2 0x00000100
|
||||
#define ISA_MIPS32R3 0x00000200
|
||||
#define ISA_MIPS32R5 0x00000400
|
||||
#define ISA_MIPS64R3 0x00000400
|
||||
#define ISA_MIPS32R5 0x00000800
|
||||
#define ISA_MIPS64R5 0x00001000
|
||||
#define ISA_MIPS32R6 0x00002000
|
||||
#define ISA_MIPS64R6 0x00004000
|
||||
|
||||
/* MIPS ASEs. */
|
||||
#define ASE_MIPS16 0x00001000
|
||||
#define ASE_MIPS3D 0x00002000
|
||||
#define ASE_MDMX 0x00004000
|
||||
#define ASE_DSP 0x00008000
|
||||
#define ASE_DSPR2 0x00010000
|
||||
#define ASE_MT 0x00020000
|
||||
#define ASE_SMARTMIPS 0x00040000
|
||||
#define ASE_MICROMIPS 0x00080000
|
||||
#define ASE_MIPS16 0x00010000
|
||||
#define ASE_MIPS3D 0x00020000
|
||||
#define ASE_MDMX 0x00040000
|
||||
#define ASE_DSP 0x00080000
|
||||
#define ASE_DSPR2 0x00100000
|
||||
#define ASE_MT 0x00200000
|
||||
#define ASE_SMARTMIPS 0x00400000
|
||||
#define ASE_MICROMIPS 0x00800000
|
||||
|
||||
/* Chip specific instructions. */
|
||||
#define INSN_LOONGSON2E 0x20000000
|
||||
|
@ -68,9 +72,15 @@
|
|||
|
||||
/* MIPS Technologies "Release 3" */
|
||||
#define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3)
|
||||
#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3)
|
||||
|
||||
/* MIPS Technologies "Release 5" */
|
||||
#define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5)
|
||||
#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5 | ISA_MIPS64R5)
|
||||
|
||||
/* MIPS Technologies "Release 6" */
|
||||
#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6)
|
||||
#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6)
|
||||
|
||||
/* Strictly follow the architecture standard:
|
||||
- Disallow "special" instruction handling for PMON/SPIM.
|
||||
|
|
|
@ -90,7 +90,6 @@ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \
|
|||
} \
|
||||
}
|
||||
#endif
|
||||
HELPER_LD(lbu, ldub, uint8_t)
|
||||
HELPER_LD(lw, ldl, int32_t)
|
||||
#ifdef TARGET_MIPS64
|
||||
HELPER_LD(ld, ldq, int64_t)
|
||||
|
@ -266,6 +265,29 @@ target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1,
|
|||
(uint64_t)(uint32_t)arg2);
|
||||
}
|
||||
|
||||
static inline target_ulong bitswap(target_ulong v)
|
||||
{
|
||||
v = ((v >> 1) & (target_ulong)0x5555555555555555) |
|
||||
((v & (target_ulong)0x5555555555555555) << 1);
|
||||
v = ((v >> 2) & (target_ulong)0x3333333333333333) |
|
||||
((v & (target_ulong)0x3333333333333333) << 2);
|
||||
v = ((v >> 4) & (target_ulong)0x0F0F0F0F0F0F0F0F) |
|
||||
((v & (target_ulong)0x0F0F0F0F0F0F0F0F) << 4);
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
target_ulong helper_dbitswap(target_ulong rt)
|
||||
{
|
||||
return bitswap(rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
target_ulong helper_bitswap(target_ulong rt)
|
||||
{
|
||||
return (int32_t)bitswap(rt);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
static inline hwaddr do_translate_address(CPUMIPSState *env,
|
||||
|
@ -2786,6 +2808,110 @@ FLOAT_UNOP(abs)
|
|||
FLOAT_UNOP(chs)
|
||||
#undef FLOAT_UNOP
|
||||
|
||||
#define FLOAT_FMADDSUB(name, bits, muladd_arg) \
|
||||
uint ## bits ## _t helper_float_ ## name (CPUMIPSState *env, \
|
||||
uint ## bits ## _t fs, \
|
||||
uint ## bits ## _t ft, \
|
||||
uint ## bits ## _t fd) \
|
||||
{ \
|
||||
uint ## bits ## _t fdret; \
|
||||
\
|
||||
fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \
|
||||
&env->active_fpu.fp_status); \
|
||||
update_fcr31(env, GETPC()); \
|
||||
return fdret; \
|
||||
}
|
||||
|
||||
FLOAT_FMADDSUB(maddf_s, 32, 0)
|
||||
FLOAT_FMADDSUB(maddf_d, 64, 0)
|
||||
FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product)
|
||||
FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product)
|
||||
#undef FLOAT_FMADDSUB
|
||||
|
||||
#define FLOAT_MINMAX(name, bits, minmaxfunc) \
|
||||
uint ## bits ## _t helper_float_ ## name (CPUMIPSState *env, \
|
||||
uint ## bits ## _t fs, \
|
||||
uint ## bits ## _t ft) \
|
||||
{ \
|
||||
uint ## bits ## _t fdret; \
|
||||
\
|
||||
fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \
|
||||
&env->active_fpu.fp_status); \
|
||||
update_fcr31(env, GETPC()); \
|
||||
return fdret; \
|
||||
}
|
||||
|
||||
FLOAT_MINMAX(max_s, 32, maxnum)
|
||||
FLOAT_MINMAX(max_d, 64, maxnum)
|
||||
FLOAT_MINMAX(maxa_s, 32, maxnummag)
|
||||
FLOAT_MINMAX(maxa_d, 64, maxnummag)
|
||||
|
||||
FLOAT_MINMAX(min_s, 32, minnum)
|
||||
FLOAT_MINMAX(min_d, 64, minnum)
|
||||
FLOAT_MINMAX(mina_s, 32, minnummag)
|
||||
FLOAT_MINMAX(mina_d, 64, minnummag)
|
||||
#undef FLOAT_MINMAX
|
||||
|
||||
#define FLOAT_RINT(name, bits) \
|
||||
uint ## bits ## _t helper_float_ ## name (CPUMIPSState *env, \
|
||||
uint ## bits ## _t fs) \
|
||||
{ \
|
||||
uint ## bits ## _t fdret; \
|
||||
\
|
||||
fdret = float ## bits ## _round_to_int(fs, &env->active_fpu.fp_status); \
|
||||
update_fcr31(env, GETPC()); \
|
||||
return fdret; \
|
||||
}
|
||||
|
||||
FLOAT_RINT(rint_s, 32)
|
||||
FLOAT_RINT(rint_d, 64)
|
||||
#undef FLOAT_RINT
|
||||
|
||||
#define FLOAT_CLASS_SIGNALING_NAN 0x001
|
||||
#define FLOAT_CLASS_QUIET_NAN 0x002
|
||||
#define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
|
||||
#define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
|
||||
#define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
|
||||
#define FLOAT_CLASS_NEGATIVE_ZERO 0x020
|
||||
#define FLOAT_CLASS_POSITIVE_INFINITY 0x040
|
||||
#define FLOAT_CLASS_POSITIVE_NORMAL 0x080
|
||||
#define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
|
||||
#define FLOAT_CLASS_POSITIVE_ZERO 0x200
|
||||
|
||||
#define FLOAT_CLASS(name, bits) \
|
||||
uint ## bits ## _t helper_float_ ## name (uint ## bits ## _t arg) \
|
||||
{ \
|
||||
if (float ## bits ## _is_signaling_nan(arg)) { \
|
||||
return FLOAT_CLASS_SIGNALING_NAN; \
|
||||
} else if (float ## bits ## _is_quiet_nan(arg)) { \
|
||||
return FLOAT_CLASS_QUIET_NAN; \
|
||||
} else if (float ## bits ## _is_neg(arg)) { \
|
||||
if (float ## bits ## _is_infinity(arg)) { \
|
||||
return FLOAT_CLASS_NEGATIVE_INFINITY; \
|
||||
} else if (float ## bits ## _is_zero(arg)) { \
|
||||
return FLOAT_CLASS_NEGATIVE_ZERO; \
|
||||
} else if (float ## bits ## _is_zero_or_denormal(arg)) { \
|
||||
return FLOAT_CLASS_NEGATIVE_SUBNORMAL; \
|
||||
} else { \
|
||||
return FLOAT_CLASS_NEGATIVE_NORMAL; \
|
||||
} \
|
||||
} else { \
|
||||
if (float ## bits ## _is_infinity(arg)) { \
|
||||
return FLOAT_CLASS_POSITIVE_INFINITY; \
|
||||
} else if (float ## bits ## _is_zero(arg)) { \
|
||||
return FLOAT_CLASS_POSITIVE_ZERO; \
|
||||
} else if (float ## bits ## _is_zero_or_denormal(arg)) { \
|
||||
return FLOAT_CLASS_POSITIVE_SUBNORMAL; \
|
||||
} else { \
|
||||
return FLOAT_CLASS_POSITIVE_NORMAL; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
FLOAT_CLASS(class_s, 32)
|
||||
FLOAT_CLASS(class_d, 64)
|
||||
#undef FLOAT_CLASS
|
||||
|
||||
/* MIPS specific unary operations */
|
||||
uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
|
||||
{
|
||||
|
@ -3261,3 +3387,114 @@ FOP_COND_PS(le, float32_le(fst0, fst1, &env->active_fpu.fp_status),
|
|||
float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
|
||||
FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status),
|
||||
float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
|
||||
|
||||
/* R6 compare operations */
|
||||
#define FOP_CONDN_D(op, cond) \
|
||||
uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState * env, uint64_t fdt0, \
|
||||
uint64_t fdt1) \
|
||||
{ \
|
||||
uint64_t c; \
|
||||
c = cond; \
|
||||
update_fcr31(env, GETPC()); \
|
||||
if (c) { \
|
||||
return -1; \
|
||||
} else { \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float64_unordered_quiet() is still called. */
|
||||
FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float64_unordered() is still called. */
|
||||
FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_le(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, &env->active_fpu.fp_status)
|
||||
|| float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)))
|
||||
|
||||
#define FOP_CONDN_S(op, cond) \
|
||||
uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState * env, uint32_t fst0, \
|
||||
uint32_t fst1) \
|
||||
{ \
|
||||
uint64_t c; \
|
||||
c = cond; \
|
||||
update_fcr31(env, GETPC()); \
|
||||
if (c) { \
|
||||
return -1; \
|
||||
} else { \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float32_unordered_quiet() is still called. */
|
||||
FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
/* NOTE: the comma operator will make "cond" to eval to false,
|
||||
* but float32_unordered() is still called. */
|
||||
FOP_CONDN_S(saf, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
|
||||
FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(seq, (float32_eq(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_eq(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(slt, (float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sle, (float32_le(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sor, (float32_le(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_le(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
FOP_CONDN_S(sne, (float32_lt(fst1, fst0, &env->active_fpu.fp_status)
|
||||
|| float32_lt(fst0, fst1, &env->active_fpu.fp_status)))
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -515,6 +515,36 @@ static const mips_def_t mips_defs[] =
|
|||
.insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
{
|
||||
/* A generic CPU supporting MIPS64 Release 6 ISA.
|
||||
FIXME: It does not support all the MIPS64R6 features yet.
|
||||
Eventually this should be replaced by a real CPU model. */
|
||||
.name = "MIPS64R6-generic",
|
||||
.CP0_PRid = 0x00010000,
|
||||
.CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) |
|
||||
(MMU_TYPE_R4000 << CP0C0_MT),
|
||||
.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
|
||||
(2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
|
||||
(2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
|
||||
(0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
|
||||
.CP0_Config2 = MIPS_CONFIG2,
|
||||
.CP0_Config3 = MIPS_CONFIG3,
|
||||
.CP0_LLAddr_rw_bitmask = 0,
|
||||
.CP0_LLAddr_shift = 0,
|
||||
.SYNCI_Step = 32,
|
||||
.CCRes = 2,
|
||||
.CP0_Status_rw_bitmask = 0x30D8FFFF,
|
||||
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
|
||||
(1 << FCR0_D) | (1 << FCR0_S) | (0x00 << FCR0_PRID) |
|
||||
(0x0 << FCR0_REV),
|
||||
.SEGBITS = 42,
|
||||
/* The architectural limit is 59, but we have hardcoded 36 bit
|
||||
in some places...
|
||||
.PABITS = 59, */ /* the architectural limit */
|
||||
.PABITS = 36,
|
||||
.insn_flags = CPU_MIPS64R6,
|
||||
.mmu_type = MMU_TYPE_R4000,
|
||||
},
|
||||
{
|
||||
.name = "Loongson-2E",
|
||||
.CP0_PRid = 0x6302,
|
||||
|
|
Loading…
Reference in New Issue