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:
Peter Maydell 2014-10-22 12:06:47 +01:00
commit 31cc9514a5
11 changed files with 3530 additions and 1186 deletions

View File

@ -119,6 +119,8 @@ see <http://www.gnu.org/licenses/>. */
#define OP_SH_IMMEDIATE 0 #define OP_SH_IMMEDIATE 0
#define OP_MASK_DELTA 0xffff #define OP_MASK_DELTA 0xffff
#define OP_SH_DELTA 0 #define OP_SH_DELTA 0
#define OP_MASK_DELTA_R6 0x1ff
#define OP_SH_DELTA_R6 7
#define OP_MASK_FUNCT 0x3f #define OP_MASK_FUNCT 0x3f
#define OP_SH_FUNCT 0 #define OP_SH_FUNCT 0
#define OP_MASK_SPEC 0x3f #define OP_MASK_SPEC 0x3f
@ -405,6 +407,12 @@ struct mips_opcode
"+3" UDI immediate bits 6-20 "+3" UDI immediate bits 6-20
"+4" UDI immediate bits 6-25 "+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: Other:
"()" parens surrounding optional value "()" parens surrounding optional value
"," separates operands "," separates operands
@ -521,6 +529,8 @@ struct mips_opcode
#define INSN_ISA64 0x00000040 #define INSN_ISA64 0x00000040
#define INSN_ISA32R2 0x00000080 #define INSN_ISA32R2 0x00000080
#define INSN_ISA64R2 0x00000100 #define INSN_ISA64R2 0x00000100
#define INSN_ISA32R6 0x00000200
#define INSN_ISA64R6 0x00000400
/* Masks used for MIPS-defined ASEs. */ /* Masks used for MIPS-defined ASEs. */
#define INSN_ASE_MASK 0x0000f000 #define INSN_ASE_MASK 0x0000f000
@ -585,6 +595,8 @@ struct mips_opcode
#define ISA_MIPS32R2 (ISA_MIPS32 | INSN_ISA32R2) #define ISA_MIPS32R2 (ISA_MIPS32 | INSN_ISA32R2)
#define ISA_MIPS64R2 (ISA_MIPS64 | INSN_ISA32R2 | INSN_ISA64R2) #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 /* CPU defines, use instead of hardcoding processor number. Keep this
in sync with bfd/archures.c in order for machine selection to work. */ 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 I64 INSN_ISA64
#define I33 INSN_ISA32R2 #define I33 INSN_ISA32R2
#define I65 INSN_ISA64R2 #define I65 INSN_ISA64R2
#define I32R6 INSN_ISA32R6
#define I64R6 INSN_ISA64R6
/* MIPS64 MIPS-3D ASE support. */ /* MIPS64 MIPS-3D ASE support. */
#define I16 INSN_MIPS16 #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 them first. The assemblers uses a hash table based on the
instruction name anyhow. */ instruction name anyhow. */
/* name, args, match, mask, pinfo, membership */ /* 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 }, {"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 }, {"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t, 0, I4|I33 },
{"nop", "", 0x00000000, 0xffffffff, 0, INSN2_ALIAS, I1 }, /* sll */ {"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,o(b)", 0xd0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 },
{"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3 }, {"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3 },
{"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, 0, I1 }, {"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}, {"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,o(b)", 0x8c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 },
{"lw", "t,A(b)", 0, (int) M_LW_AB, INSN_MACRO, 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); (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
break; 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 */ case 't': /* Coprocessor 0 reg name */
(*info->fprintf_func) (info->stream, "%s", (*info->fprintf_func) (info->stream, "%s",
mips_cp0_names[(l >> OP_SH_RT) & 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 'j': /* Same as i, but sign-extended. */
case 'o': case 'o':
delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
if (delta & 0x8000) if (delta & 0x8000)
delta |= ~0xffff; delta |= ~0xffff;
(*info->fprintf_func) (info->stream, "%d", (*info->fprintf_func) (info->stream, "%d",
@ -4052,6 +4244,23 @@ print_insn_mips (bfd_vma memaddr,
&& strcmp (op->name, "jalx")) && strcmp (op->name, "jalx"))
continue; 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. */ /* Figure out instruction type and branch delay information. */
if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0) if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
{ {

View File

@ -7240,13 +7240,17 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
* minnum() and maxnum correspond to the IEEE 754-2008 minNum() * minnum() and maxnum correspond to the IEEE 754-2008 minNum()
* and maxNum() operations. min() and max() are the typical min/max * and maxNum() operations. min() and max() are the typical min/max
* semantics provided by many CPUs which predate that specification. * 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) \ #define MINMAX(s) \
static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, \ 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; \ flag aSign, bSign; \
uint ## s ## _t av, bv; \ uint ## s ## _t av, bv, aav, abv; \
a = float ## s ## _squash_input_denormal(a STATUS_VAR); \ a = float ## s ## _squash_input_denormal(a STATUS_VAR); \
b = float ## s ## _squash_input_denormal(b STATUS_VAR); \ b = float ## s ## _squash_input_denormal(b STATUS_VAR); \
if (float ## s ## _is_any_nan(a) || \ 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); \ bSign = extractFloat ## s ## Sign(b); \
av = float ## s ## _val(a); \ av = float ## s ## _val(a); \
bv = float ## s ## _val(b); \ 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 (aSign != bSign) { \
if (ismin) { \ if (ismin) { \
return aSign ? a : b; \ 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) \ 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) \ 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) \ 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) \ 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) MINMAX(32)

View File

@ -697,12 +697,12 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
/* Jump to kernel code */ /* Jump to kernel code */
stl_p(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */ 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++, 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 */ stl_p(p++, 0x00000000); /* nop */
/* YAMON subroutines */ /* YAMON subroutines */
p = (uint32_t *) (base + 0x800); p = (uint32_t *) (base + 0x800);
stl_p(p++, 0x03e00008); /* jr ra */ stl_p(p++, 0x03e00009); /* jalr ra */
stl_p(p++, 0x24020000); /* li v0,0 */ stl_p(p++, 0x24020000); /* li v0,0 */
/* 808 YAMON print */ /* 808 YAMON print */
stl_p(p++, 0x03e06821); /* move t5,ra */ 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++, 0x00000000); /* nop */
stl_p(p++, 0x08000205); /* j 814 */ stl_p(p++, 0x08000205); /* j 814 */
stl_p(p++, 0x00000000); /* nop */ stl_p(p++, 0x00000000); /* nop */
stl_p(p++, 0x01a00008); /* jr t5 */ stl_p(p++, 0x01a00009); /* jalr t5 */
stl_p(p++, 0x01602021); /* move a0,t3 */ stl_p(p++, 0x01602021); /* move a0,t3 */
/* 0x83c YAMON print_count */ /* 0x83c YAMON print_count */
stl_p(p++, 0x03e06821); /* move t5,ra */ 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++, 0x258cffff); /* addiu t4,t4,-1 */
stl_p(p++, 0x1580fffa); /* bnez t4,84c */ stl_p(p++, 0x1580fffa); /* bnez t4,84c */
stl_p(p++, 0x00000000); /* nop */ stl_p(p++, 0x00000000); /* nop */
stl_p(p++, 0x01a00008); /* jr t5 */ stl_p(p++, 0x01a00009); /* jalr t5 */
stl_p(p++, 0x01602021); /* move a0,t3 */ stl_p(p++, 0x01602021); /* move a0,t3 */
/* 0x870 */ /* 0x870 */
stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */ 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++, 0x31290040); /* andi t1,t1,0x40 */
stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */ stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
stl_p(p++, 0x00000000); /* nop */ 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) */ stl_p(p++, 0xa1040000); /* sb a0,0(t0) */
} }

View File

@ -374,6 +374,8 @@ float32 float32_min(float32, float32 STATUS_PARAM);
float32 float32_max(float32, float32 STATUS_PARAM); float32 float32_max(float32, float32 STATUS_PARAM);
float32 float32_minnum(float32, float32 STATUS_PARAM); float32 float32_minnum(float32, float32 STATUS_PARAM);
float32 float32_maxnum(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_quiet_nan( float32 );
int float32_is_signaling_nan( float32 ); int float32_is_signaling_nan( float32 );
float32 float32_maybe_silence_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_max(float64, float64 STATUS_PARAM);
float64 float64_minnum(float64, float64 STATUS_PARAM); float64 float64_minnum(float64, float64 STATUS_PARAM);
float64 float64_maxnum(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_quiet_nan( float64 a );
int float64_is_signaling_nan( float64 ); int float64_is_signaling_nan( float64 );
float64 float64_maybe_silence_nan( float64 ); float64 float64_maybe_silence_nan( float64 );

View File

@ -431,7 +431,7 @@ struct CPUMIPSState {
int error_code; int error_code;
uint32_t hflags; /* CPU State */ uint32_t hflags; /* CPU State */
/* TMASK defines different execution modes */ /* TMASK defines different execution modes */
#define MIPS_HFLAG_TMASK 0xC07FF #define MIPS_HFLAG_TMASK 0x1807FF
#define MIPS_HFLAG_MODE 0x00007 /* execution modes */ #define MIPS_HFLAG_MODE 0x00007 /* execution modes */
/* The KSU flags must be the lowest bits in hflags. The flag order /* 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 must be the same as defined for CP0 Status. This allows to use
@ -450,7 +450,7 @@ struct CPUMIPSState {
and RSQRT.D. */ and RSQRT.D. */
#define MIPS_HFLAG_COP1X 0x00080 /* COP1X instructions enabled */ #define MIPS_HFLAG_COP1X 0x00080 /* COP1X instructions enabled */
#define MIPS_HFLAG_RE 0x00100 /* Reversed endianness */ #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 0x00400 /* MIPS16 mode flag */
#define MIPS_HFLAG_M16_SHIFT 10 #define MIPS_HFLAG_M16_SHIFT 10
/* If translation is interrupted between the branch instruction and /* 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_BL 0x01800 /* Likely branch */
#define MIPS_HFLAG_BR 0x02000 /* branch to register (can't link TB) */ #define MIPS_HFLAG_BR 0x02000 /* branch to register (can't link TB) */
/* Extra flags about the current pending branch. */ /* 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_B16 0x04000 /* branch instruction was 16 bits */
#define MIPS_HFLAG_BDS16 0x08000 /* branch requires 16-bit delay slot */ #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_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) #define MIPS_HFLAG_BMASK (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT)
/* MIPS DSP resources access. */ /* MIPS DSP resources access. */
#define MIPS_HFLAG_DSP 0x40000 /* Enable access to MIPS DSP resources. */ #define MIPS_HFLAG_DSP 0x080000 /* Enable access to MIPS DSP resources. */
#define MIPS_HFLAG_DSPR2 0x80000 /* Enable access to MIPS DSPR2 resources. */ #define MIPS_HFLAG_DSPR2 0x100000 /* Enable access to MIPS DSPR2 resources. */
/* Extra flag about HWREna register. */ /* 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 btarget; /* Jump / branch target */
target_ulong bcond; /* Branch condition (if needed) */ 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 | env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | 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)) && if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
!(env->CP0_Status & (1 << CP0St_ERL)) && !(env->CP0_Status & (1 << CP0St_ERL)) &&
!(env->hflags & MIPS_HFLAG_DM)) { !(env->hflags & MIPS_HFLAG_DM)) {
@ -737,8 +738,18 @@ static inline void compute_hflags(CPUMIPSState *env)
(env->CP0_Status & (1 << CP0St_UX))) { (env->CP0_Status & (1 << CP0St_UX))) {
env->hflags |= MIPS_HFLAG_64; 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 #endif
if ((env->CP0_Status & (1 << CP0St_CU0)) || if ((env->CP0_Status & (1 << CP0St_CU0)) ||

View File

@ -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; 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) static inline void set_DSPControl_pos(uint32_t pos, CPUMIPSState *env)
{ {
target_ulong dspc; target_ulong dspc;
@ -283,6 +274,7 @@ static inline int32_t mipsdsp_sat32_acc_q31(int32_t acc, int32_t a,
return result; return result;
} }
#ifdef TARGET_MIPS64
/* a[0] is LO, a[1] is HI. */ /* a[0] is LO, a[1] is HI. */
static inline void mipsdsp_sat64_acc_add_q63(int64_t *ret, static inline void mipsdsp_sat64_acc_add_q63(int64_t *ret,
int32_t ac, 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); set_DSPControl_overflow_flag(1, 16 + ac, env);
} }
} }
#endif
static inline int32_t mipsdsp_mul_i16_i16(int16_t a, int16_t b, static inline int32_t mipsdsp_mul_i16_i16(int16_t a, int16_t b,
CPUMIPSState *env) CPUMIPSState *env)
@ -357,10 +350,12 @@ static inline int32_t mipsdsp_mul_u16_u16(int32_t a, int32_t b)
return a * b; return a * b;
} }
#ifdef TARGET_MIPS64
static inline int32_t mipsdsp_mul_i32_i32(int32_t a, int32_t b) static inline int32_t mipsdsp_mul_i32_i32(int32_t a, int32_t b)
{ {
return a * b; return a * b;
} }
#endif
static inline int32_t mipsdsp_sat16_mul_i16_i16(int16_t a, int16_t b, static inline int32_t mipsdsp_sat16_mul_i16_i16(int16_t a, int16_t b,
CPUMIPSState *env) CPUMIPSState *env)
@ -417,10 +412,12 @@ static inline int16_t mipsdsp_rashift16(int16_t a, target_ulong mov)
return a >> mov; return a >> mov;
} }
#ifdef TARGET_MIPS64
static inline int32_t mipsdsp_rashift32(int32_t a, target_ulong mov) static inline int32_t mipsdsp_rashift32(int32_t a, target_ulong mov)
{ {
return a >> mov; return a >> mov;
} }
#endif
static inline int16_t mipsdsp_rshift1_add_q16(int16_t a, int16_t b) 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; return (temp >> 1) & 0x00FF;
} }
#ifdef TARGET_MIPS64
static inline uint8_t mipsdsp_rshift1_sub_u8(uint8_t a, uint8_t b) static inline uint8_t mipsdsp_rshift1_sub_u8(uint8_t a, uint8_t b)
{ {
uint16_t temp; 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; return (temp >> 1) & 0x00FF;
} }
#endif
/* 128 bits long. p[0] is LO, p[1] is HI. */ /* 128 bits long. p[0] is LO, p[1] is HI. */
static inline void mipsdsp_rndrashift_short_acc(int64_t *p, 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; p[1] = (acc >> 63) & 0x01;
} }
#ifdef TARGET_MIPS64
/* 128 bits long. p[0] is LO, p[1] is HI */ /* 128 bits long. p[0] is LO, p[1] is HI */
static inline void mipsdsp_rashift_acc(uint64_t *p, static inline void mipsdsp_rashift_acc(uint64_t *p,
uint32_t ac, 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, static inline int32_t mipsdsp_mul_q15_q15(int32_t ac, uint16_t a, uint16_t b,
CPUMIPSState *env) CPUMIPSState *env)
@ -608,10 +609,12 @@ static inline uint16_t mipsdsp_mul_u8_u16(uint8_t a, uint16_t b,
return tempI & 0x0000FFFF; return tempI & 0x0000FFFF;
} }
#ifdef TARGET_MIPS64
static inline uint64_t mipsdsp_mul_u32_u32(uint32_t a, uint32_t b) static inline uint64_t mipsdsp_mul_u32_u32(uint32_t a, uint32_t b)
{ {
return (uint64_t)a * (uint64_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, static inline int16_t mipsdsp_rndq15_mul_q15_q15(uint16_t a, uint16_t b,
CPUMIPSState *env) CPUMIPSState *env)
@ -717,7 +720,7 @@ static inline uint16_t mipsdsp_lshift16(uint16_t a, uint8_t s,
return a << s; return a << s;
} }
#ifdef TARGET_MIPS64
static inline uint32_t mipsdsp_lshift32(uint32_t a, uint8_t s, static inline uint32_t mipsdsp_lshift32(uint32_t a, uint8_t s,
CPUMIPSState *env) CPUMIPSState *env)
{ {
@ -734,6 +737,7 @@ static inline uint32_t mipsdsp_lshift32(uint32_t a, uint8_t s,
return a << s; return a << s;
} }
} }
#endif
static inline uint16_t mipsdsp_sat16_lshift(uint16_t a, uint8_t s, static inline uint16_t mipsdsp_sat16_lshift(uint16_t a, uint8_t s,
CPUMIPSState *env) CPUMIPSState *env)
@ -973,6 +977,7 @@ static inline uint8_t mipsdsp_satu8_sub(uint8_t a, uint8_t b, CPUMIPSState *env)
return temp & 0x00FF; return temp & 0x00FF;
} }
#ifdef TARGET_MIPS64
static inline uint32_t mipsdsp_sub32(int32_t a, int32_t b, CPUMIPSState *env) static inline uint32_t mipsdsp_sub32(int32_t a, int32_t b, CPUMIPSState *env)
{ {
int32_t temp; int32_t temp;
@ -997,6 +1002,7 @@ static inline int32_t mipsdsp_add_i32(int32_t a, int32_t b, CPUMIPSState *env)
return temp; return temp;
} }
#endif
static inline int32_t mipsdsp_cmp_eq(int32_t a, int32_t b) static inline int32_t mipsdsp_cmp_eq(int32_t a, int32_t b)
{ {

View File

@ -39,6 +39,11 @@ DEF_HELPER_3(macchiu, tl, env, tl, tl)
DEF_HELPER_3(msachi, tl, env, tl, tl) DEF_HELPER_3(msachi, tl, env, tl, tl)
DEF_HELPER_3(msachiu, 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 #ifndef CONFIG_USER_ONLY
/* CP0 helpers */ /* CP0 helpers */
DEF_HELPER_1(mfc0_mvpcontrol, tl, env) 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_addr_ps, i64, env, i64, i64)
DEF_HELPER_3(float_mulr_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) \ #define FOP_PROTO(op) \
DEF_HELPER_2(float_ ## op ## l_s, i64, env, i32) \ DEF_HELPER_2(float_ ## op ## l_s, i64, env, i32) \
DEF_HELPER_2(float_ ## op ## l_d, i64, env, i64) \ 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(sqrt)
FOP_PROTO(rsqrt) FOP_PROTO(rsqrt)
FOP_PROTO(recip) FOP_PROTO(recip)
FOP_PROTO(rint)
#undef FOP_PROTO #undef FOP_PROTO
#define FOP_PROTO(op) \ #define FOP_PROTO(op) \
@ -279,6 +304,33 @@ FOP_PROTO(le)
FOP_PROTO(ngt) FOP_PROTO(ngt)
#undef FOP_PROTO #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 */ /* Special functions */
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
DEF_HELPER_1(tlbwi, void, env) DEF_HELPER_1(tlbwi, void, env)

View File

@ -30,17 +30,21 @@
#define ISA_MIPS64 0x00000080 #define ISA_MIPS64 0x00000080
#define ISA_MIPS64R2 0x00000100 #define ISA_MIPS64R2 0x00000100
#define ISA_MIPS32R3 0x00000200 #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. */ /* MIPS ASEs. */
#define ASE_MIPS16 0x00001000 #define ASE_MIPS16 0x00010000
#define ASE_MIPS3D 0x00002000 #define ASE_MIPS3D 0x00020000
#define ASE_MDMX 0x00004000 #define ASE_MDMX 0x00040000
#define ASE_DSP 0x00008000 #define ASE_DSP 0x00080000
#define ASE_DSPR2 0x00010000 #define ASE_DSPR2 0x00100000
#define ASE_MT 0x00020000 #define ASE_MT 0x00200000
#define ASE_SMARTMIPS 0x00040000 #define ASE_SMARTMIPS 0x00400000
#define ASE_MICROMIPS 0x00080000 #define ASE_MICROMIPS 0x00800000
/* Chip specific instructions. */ /* Chip specific instructions. */
#define INSN_LOONGSON2E 0x20000000 #define INSN_LOONGSON2E 0x20000000
@ -68,9 +72,15 @@
/* MIPS Technologies "Release 3" */ /* MIPS Technologies "Release 3" */
#define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) #define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3)
#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3)
/* MIPS Technologies "Release 5" */ /* MIPS Technologies "Release 5" */
#define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) #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: /* Strictly follow the architecture standard:
- Disallow "special" instruction handling for PMON/SPIM. - Disallow "special" instruction handling for PMON/SPIM.

View File

@ -90,7 +90,6 @@ static inline type do_##name(CPUMIPSState *env, target_ulong addr, \
} \ } \
} }
#endif #endif
HELPER_LD(lbu, ldub, uint8_t)
HELPER_LD(lw, ldl, int32_t) HELPER_LD(lw, ldl, int32_t)
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
HELPER_LD(ld, ldq, int64_t) HELPER_LD(ld, ldq, int64_t)
@ -266,6 +265,29 @@ target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1,
(uint64_t)(uint32_t)arg2); (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 #ifndef CONFIG_USER_ONLY
static inline hwaddr do_translate_address(CPUMIPSState *env, static inline hwaddr do_translate_address(CPUMIPSState *env,
@ -2786,6 +2808,110 @@ FLOAT_UNOP(abs)
FLOAT_UNOP(chs) FLOAT_UNOP(chs)
#undef FLOAT_UNOP #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 */ /* MIPS specific unary operations */
uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0) 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)) 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), 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)) 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

View File

@ -515,6 +515,36 @@ static const mips_def_t mips_defs[] =
.insn_flags = CPU_MIPS64R2 | ASE_MIPS3D, .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
.mmu_type = MMU_TYPE_R4000, .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", .name = "Loongson-2E",
.CP0_PRid = 0x6302, .CP0_PRid = 0x6302,