Index: include/opcode/mips.h =================================================================== RCS file: /cvs/src/src/include/opcode/mips.h,v retrieving revision 1.44 diff -c -3 -p -r1.44 mips.h *** include/opcode/mips.h 25 Aug 2005 18:09:24 -0000 1.44 --- include/opcode/mips.h 29 Aug 2005 23:00:09 -0000 *************** Software Foundation, 51 Franklin Street *** 170,175 **** --- 170,185 ---- #define OP_SH_RDDSP 16 #define OP_MASK_RDDSP 0x3f + /* MIPS MT ASE */ + #define OP_SH_MT_U 5 + #define OP_MASK_MT_U 0x1 + #define OP_SH_MT_H 4 + #define OP_MASK_MT_H 0x1 + #define OP_SH_MTACC_T 18 + #define OP_MASK_MTACC_T 0x3 + #define OP_SH_MTACC_D 13 + #define OP_MASK_MTACC_D 0x3 + #define OP_OP_COP0 0x10 #define OP_OP_COP1 0x11 #define OP_OP_COP2 0x12 *************** struct mips_opcode *** 331,336 **** --- 341,355 ---- "'" 6 bit unsigned immediate (OP_*_RDDSP) "@" 10 bit signed immediate (OP_*_IMM10) + MT ASE usage: + "!" 1 bit immediate at bit 5 + "$" 1 bit immediate at bit 4 + "*" 2 bit dsp/smartmips accumulator register (OP_*_MTACC_T) + "&" 2 bit dsp/smartmips accumulator register (OP_*_MTACC_D) + "g" 5 bit coprocessor 1 and 2 destination register (OP_*_RD) + "+t" 5 bit coprocessor 0 destination register (OP_*_RT) + "+T" 5 bit coprocessor 0 destination register (OP_*_RT) - disassembly only + Other: "()" parens surrounding optional value "," separates operands *************** struct mips_opcode *** 339,351 **** Characters used so far, for quick reference when adding more: "34567890" ! "%[]<>(),+:'@" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ! "abcdefhijklopqrstuvwxz" Extension character sequences used so far ("+" followed by the following), for quick reference when adding more: ! "ABCDEFGHI" */ /* These are the bits which may be set in the pinfo field of an --- 358,371 ---- Characters used so far, for quick reference when adding more: "34567890" ! "%[]<>(),+:'@!$*&" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ! "abcdefghijklopqrstuvwxz" Extension character sequences used so far ("+" followed by the following), for quick reference when adding more: ! "ABCDEFGHIT" ! "t" */ /* These are the bits which may be set in the pinfo field of an *************** struct mips_opcode *** 447,453 **** #define INSN_ISA64R2 0x00000100 /* Masks used for MIPS-defined ASEs. */ ! #define INSN_ASE_MASK 0x0000f000 /* DSP ASE */ #define INSN_DSP 0x00001000 --- 467,473 ---- #define INSN_ISA64R2 0x00000100 /* Masks used for MIPS-defined ASEs. */ ! #define INSN_ASE_MASK 0x0400f000 /* DSP ASE */ #define INSN_DSP 0x00001000 *************** struct mips_opcode *** 480,485 **** --- 500,507 ---- #define INSN_5400 0x01000000 /* NEC VR5500 instruction. */ #define INSN_5500 0x02000000 + /* MT ASE */ + #define INSN_MT 0x04000000 /* MIPS ISA defines, use instead of hardcoding ISA level. */ Index: opcodes/mips-opc.c =================================================================== RCS file: /cvs/src/src/opcodes/mips-opc.c,v retrieving revision 1.52 diff -c -3 -p -r1.52 mips-opc.c *** opcodes/mips-opc.c 25 Aug 2005 18:12:43 -0000 1.52 --- opcodes/mips-opc.c 29 Aug 2005 23:00:10 -0000 *************** Software Foundation, 51 Franklin Street *** 146,151 **** --- 146,154 ---- #define DSP_VOLA INSN_TRAP #define D32 (INSN_DSP) + /* MIPS MT ASE support. */ + #define MT32 (INSN_MT) + /* The order of overloaded instructions matters. Label arguments and register arguments look the same. Instructions that can have either for arguments must apear in the correct order in this table for the *************** const struct mips_opcode mips_builtin_op *** 220,229 **** {"andi", "t,r,i", 0x30000000, 0xfc000000, WR_t|RD_s, 0, I1 }, /* b is at the top of the table. */ /* bal is at the top of the table. */ ! {"bc0f", "p", 0x41000000, 0xffff0000, CBD|RD_CC, 0, I1 }, ! {"bc0fl", "p", 0x41020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, ! {"bc0t", "p", 0x41010000, 0xffff0000, CBD|RD_CC, 0, I1 }, ! {"bc0tl", "p", 0x41030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, {"bc1any2f", "N,p", 0x45200000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, {"bc1any2t", "N,p", 0x45210000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, {"bc1any4f", "N,p", 0x45400000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, --- 223,229 ---- {"andi", "t,r,i", 0x30000000, 0xfc000000, WR_t|RD_s, 0, I1 }, /* b is at the top of the table. */ /* bal is at the top of the table. */ ! /* bc0[tf]l? are at the bottom of the table. */ {"bc1any2f", "N,p", 0x45200000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, {"bc1any2t", "N,p", 0x45210000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, {"bc1any4f", "N,p", 0x45400000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, *************** const struct mips_opcode mips_builtin_op *** 469,474 **** --- 469,477 ---- {"cfc1", "t,S", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 }, /* cfc2 is at the bottom of the table. */ {"cfc3", "t,G", 0x4c400000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 }, + {"cftc1", "d,E", 0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0, MT32 }, + {"cftc1", "d,T", 0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0, MT32 }, + {"cftc2", "d,E", 0x41000025, 0xffe007ff, TRAP|LCD|WR_d|RD_C2, 0, MT32 }, {"clo", "U,s", 0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, {"clz", "U,s", 0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, {"ctc0", "t,G", 0x40c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, *************** const struct mips_opcode mips_builtin_op *** 476,481 **** --- 479,487 ---- {"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, /* ctc2 is at the bottom of the table. */ {"ctc3", "t,G", 0x4cc00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, + {"cttc1", "t,g", 0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0, MT32 }, + {"cttc1", "t,S", 0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0, MT32 }, + {"cttc2", "t,g", 0x41800025, 0xffe007ff, TRAP|COD|RD_t|WR_CC, 0, MT32 }, {"cvt.d.l", "D,S", 0x46a00021, 0xffff003f, WR_D|RD_S|FP_D, 0, I3 }, {"cvt.d.s", "D,S", 0x46000021, 0xffff003f, WR_D|RD_S|FP_D|FP_S, 0, I1 }, {"cvt.d.w", "D,S", 0x46800021, 0xffff003f, WR_D|RD_S|FP_D, 0, I1 }, *************** const struct mips_opcode mips_builtin_op *** 556,561 **** --- 562,569 ---- {"dmfc0", "t,G", 0x40200000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I3 }, {"dmfc0", "t,+D", 0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I64 }, {"dmfc0", "t,G,H", 0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I64 }, + {"dmt", "", 0x41600bc1, 0xffffffff, TRAP, 0, MT32 }, + {"dmt", "t", 0x41600bc1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, {"dmtc0", "t,G", 0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, I3 }, {"dmtc0", "t,+D", 0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I64 }, {"dmtc0", "t,G,H", 0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I64 }, *************** const struct mips_opcode mips_builtin_op *** 620,628 **** --- 628,642 ---- {"dsub", "d,v,I", 0, (int) M_DSUB_I, INSN_MACRO, 0, I3 }, {"dsubu", "d,v,t", 0x0000002f, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, {"dsubu", "d,v,I", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I3 }, + {"dvpe", "", 0x41600001, 0xffffffff, TRAP, 0, MT32 }, + {"dvpe", "t", 0x41600001, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, {"ei", "", 0x41606020, 0xffffffff, WR_t|WR_C0, 0, I33 }, {"ei", "t", 0x41606020, 0xffe0ffff, WR_t|WR_C0, 0, I33 }, + {"emt", "", 0x41600be1, 0xffffffff, TRAP, 0, MT32 }, + {"emt", "t", 0x41600be1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, {"eret", "", 0x42000018, 0xffffffff, 0, 0, I3|I32 }, + {"evpe", "", 0x41600021, 0xffffffff, TRAP, 0, MT32 }, + {"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, {"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33 }, {"floor.l.d", "D,S", 0x4620000b, 0xffff003f, WR_D|RD_S|FP_D, 0, I3 }, {"floor.l.s", "D,S", 0x4600000b, 0xffff003f, WR_D|RD_S|FP_S, 0, I3 }, *************** const struct mips_opcode mips_builtin_op *** 719,724 **** --- 733,739 ---- {"lwr", "t,A(b)", 0, (int) M_LWR_AB, INSN_MACRO, 0, I1 }, {"flush", "t,o(b)", 0x98000000, 0xfc000000, LDD|RD_b|WR_t, 0, I2 }, /* same */ {"flush", "t,A(b)", 0, (int) M_LWR_AB, INSN_MACRO, 0, I2 }, /* as lwr */ + {"fork", "d,s,t", 0x7c000008, 0xfc0007ff, TRAP|WR_d|RD_s|RD_t, 0, MT32 }, {"lwu", "t,o(b)", 0x9c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 }, {"lwu", "t,A(b)", 0, (int) M_LWU_AB, INSN_MACRO, 0, I3 }, {"lwxc1", "D,t(b)", 0x4c000000, 0xfc00f83f, LDD|WR_D|RD_t|RD_b, 0, I4 }, *************** const struct mips_opcode mips_builtin_op *** 755,760 **** --- 770,793 ---- {"max.qh", "X,Y,Q", 0x78200007, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, {"mfpc", "t,P", 0x4000c801, 0xffe0ffc1, LCD|WR_t|RD_C0, 0, M1|N5 }, {"mfps", "t,P", 0x4000c800, 0xffe0ffc1, LCD|WR_t|RD_C0, 0, M1|N5 }, + {"mftacx", "d", 0x41020021, 0xffff07ff, TRAP|WR_d|RD_a, 0, MT32 }, + {"mftacx", "d,*", 0x41020021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, + {"mftc0", "d,+t", 0x41000000, 0xffe007ff, TRAP|LCD|WR_d|RD_C0, 0, MT32 }, + {"mftc0", "d,+T", 0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0, 0, MT32 }, + {"mftc0", "d,E,H", 0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0, 0, MT32 }, + {"mftc1", "d,T", 0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0, MT32 }, + {"mftc1", "d,E", 0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0, MT32 }, + {"mftc2", "d,E", 0x41000024, 0xffe007ff, TRAP|LCD|WR_d|RD_C2, 0, MT32 }, + {"mftdsp", "d", 0x41100021, 0xffff07ff, TRAP|WR_d, 0, MT32 }, + {"mftgpr", "d,t", 0x41000020, 0xffe007ff, TRAP|WR_d|RD_t, 0, MT32 }, + {"mfthc1", "d,T", 0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0, MT32 }, + {"mfthc1", "d,E", 0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0, MT32 }, + {"mfthc2", "d,E", 0x41000034, 0xffe007ff, TRAP|LCD|WR_d|RD_C2, 0, MT32 }, + {"mfthi", "d", 0x41010021, 0xffff07ff, TRAP|WR_d|RD_a, 0, MT32 }, + {"mfthi", "d,*", 0x41010021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, + {"mftlo", "d", 0x41000021, 0xffff07ff, TRAP|WR_d|RD_a, 0, MT32 }, + {"mftlo", "d,*", 0x41000021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, + {"mftr", "t,d,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d, 0, MT32 }, {"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 }, {"mfc0", "t,+D", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, {"mfc0", "t,G,H", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, *************** const struct mips_opcode mips_builtin_op *** 836,841 **** --- 869,892 ---- {"mthi", "s,7", 0x00000011, 0xfc1fe7ff, RD_s|WR_HI, 0, D32 }, {"mtlo", "s", 0x00000013, 0xfc1fffff, RD_s|WR_LO, 0, I1 }, {"mtlo", "s,7", 0x00000013, 0xfc1fe7ff, RD_s|WR_LO, 0, D32 }, + {"mttc0", "t,G", 0x41800000, 0xffe007ff, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, + {"mttc0", "t,+D", 0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, + {"mttc0", "t,G,H", 0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, + {"mttc1", "t,S", 0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0, MT32 }, + {"mttc1", "t,G", 0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0, MT32 }, + {"mttc2", "t,g", 0x41800024, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0, MT32 }, + {"mttacx", "t", 0x41801021, 0xffe0ffff, TRAP|WR_a|RD_t, 0, MT32 }, + {"mttacx", "t,&", 0x41801021, 0xffe09fff, TRAP|WR_a|RD_t, 0, MT32 }, + {"mttdsp", "t", 0x41808021, 0xffe0ffff, TRAP|RD_t, 0, MT32 }, + {"mttgpr", "t,d", 0x41800020, 0xffe007ff, TRAP|WR_d|RD_t, 0, MT32 }, + {"mtthc1", "t,S", 0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0, MT32 }, + {"mtthc1", "t,G", 0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0, MT32 }, + {"mtthc2", "t,g", 0x41800034, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0, MT32 }, + {"mtthi", "t", 0x41800821, 0xffe0ffff, TRAP|WR_a|RD_t, 0, MT32 }, + {"mtthi", "t,&", 0x41800821, 0xffe09fff, TRAP|WR_a|RD_t, 0, MT32 }, + {"mttlo", "t", 0x41800021, 0xffe0ffff, TRAP|WR_a|RD_t, 0, MT32 }, + {"mttlo", "t,&", 0x41800021, 0xffe09fff, TRAP|WR_a|RD_t, 0, MT32 }, + {"mttr", "t,d,!,H,$", 0x41800000, 0xffe007c8, TRAP|RD_t, 0, MT32 }, {"mul.d", "D,V,T", 0x46200002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I1 }, {"mul.s", "D,V,T", 0x46000002, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I1 }, {"mul.ob", "X,Y,Q", 0x78000030, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, *************** const struct mips_opcode mips_builtin_op *** 1209,1214 **** --- 1260,1267 ---- {"xor.ob", "D,S,k", 0x4bc0000d, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, {"xor.qh", "X,Y,Q", 0x7820000d, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, {"xori", "t,r,i", 0x38000000, 0xfc000000, WR_t|RD_s, 0, I1 }, + {"yield", "s", 0x7c000009, 0xfc1fffff, TRAP|RD_s, 0, MT32 }, + {"yield", "d,s", 0x7c000009, 0xfc1f07ff, TRAP|WR_d|RD_s, 0, MT32 }, /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format instructions so they are here for the latters to take precedence. */ *************** const struct mips_opcode mips_builtin_op *** 1352,1357 **** --- 1405,1415 ---- {"subu_s.qb", "d,s,t", 0x7c000150, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, {"wrdsp", "s", 0x7c1ffcf8, 0xfc1fffff, RD_s|DSP_VOLA, 0, D32 }, {"wrdsp", "s,8", 0x7c0004f8, 0xfc1e07ff, RD_s|DSP_VOLA, 0, D32 }, + /* Move bc0* after mftr and mttr to avoid opcode collision. */ + {"bc0f", "p", 0x41000000, 0xffff0000, CBD|RD_CC, 0, I1 }, + {"bc0fl", "p", 0x41020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, + {"bc0t", "p", 0x41010000, 0xffff0000, CBD|RD_CC, 0, I1 }, + {"bc0tl", "p", 0x41030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, }; #define MIPS_NUM_OPCODES \ Index: opcodes/mips-dis.c =================================================================== RCS file: /cvs/src/src/opcodes/mips-dis.c,v retrieving revision 1.53 diff -c -3 -p -r1.53 mips-dis.c *** opcodes/mips-dis.c 25 Aug 2005 18:12:44 -0000 1.53 --- opcodes/mips-dis.c 29 Aug 2005 23:00:10 -0000 *************** const struct mips_arch_choice mips_arch_ *** 376,382 **** mips_hwr_names_numeric }, { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, ! ISA_MIPS32R2 | INSN_MIPS16 | INSN_DSP, mips_cp0_names_mips3264r2, mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_hwr_names_mips3264r2 }, --- 376,382 ---- mips_hwr_names_numeric }, { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, ! ISA_MIPS32R2 | INSN_MIPS16 | INSN_DSP | INSN_MT, mips_cp0_names_mips3264r2, mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_hwr_names_mips3264r2 }, *************** print_insn_args (const char *d, *** 771,776 **** --- 771,804 ---- (*info->fprintf_func) (info->stream, "0x%x", msbd + 1); break; + case 't': /* Coprocessor 0 reg name */ + (*info->fprintf_func) (info->stream, "%s", + mips_cp0_names[(l >> OP_SH_RT) & + OP_MASK_RT]); + break; + + case 'T': /* Coprocessor 0 reg name */ + { + const struct mips_cp0sel_name *n; + unsigned int cp0reg, sel; + + cp0reg = (l >> OP_SH_RT) & OP_MASK_RT; + sel = (l >> OP_SH_SEL) & OP_MASK_SEL; + + /* CP0 register including 'sel' code for mftc0, to be + printed textually if known. If not known, print both + CP0 register name and sel numerically since CP0 register + with sel 0 may have a name unrelated to register being + printed. */ + n = lookup_mips_cp0sel_name(mips_cp0sel_names, + mips_cp0sel_names_len, cp0reg, sel); + if (n != NULL) + (*info->fprintf_func) (info->stream, "%s", n->name); + else + (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel); + break; + } + default: /* xgettext:c-format */ (*info->fprintf_func) (info->stream, *************** print_insn_args (const char *d, *** 841,846 **** --- 869,900 ---- (*info->fprintf_func) (info->stream, "%d", delta); break; + case '!': + (*info->fprintf_func) (info->stream, "%ld", + (l >> OP_SH_MT_U) & OP_MASK_MT_U); + break; + + case '$': + (*info->fprintf_func) (info->stream, "%ld", + (l >> OP_SH_MT_H) & OP_MASK_MT_H); + break; + + case '*': + (*info->fprintf_func) (info->stream, "$ac%ld", + (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T); + break; + + case '&': + (*info->fprintf_func) (info->stream, "$ac%ld", + (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D); + break; + + case 'g': + /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */ + (*info->fprintf_func) (info->stream, "$%ld", + (l >> OP_SH_RD) & OP_MASK_RD); + break; + case 's': case 'b': case 'r': Index: gas/config/tc-mips.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-mips.c,v retrieving revision 1.318 diff -c -3 -p -r1.318 tc-mips.c *** gas/config/tc-mips.c 25 Aug 2005 18:17:36 -0000 1.318 --- gas/config/tc-mips.c 29 Aug 2005 23:00:12 -0000 *************** struct mips_set_options *** 194,199 **** --- 194,200 ---- int ase_mips3d; int ase_mdmx; int ase_dsp; + int ase_mt; /* Whether we are assembling for the mips16 processor. 0 if we are not, 1 if we are, and -1 if the value has not been initialized. Changed by `.set mips16' and `.set nomips16', and the -mips16 and *************** static int file_mips_fp32 = -1; *** 244,250 **** static struct mips_set_options mips_opts = { ! ISA_UNKNOWN, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE }; /* These variables are filled in with the masks of registers used. --- 245,251 ---- static struct mips_set_options mips_opts = { ! ISA_UNKNOWN, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE }; /* These variables are filled in with the masks of registers used. *************** static int file_ase_mdmx; *** 272,277 **** --- 273,282 ---- command line (e.g., by -march). */ static int file_ase_dsp; + /* True if -mt was passed or implied by arguments passed on the + command line (e.g., by -march). */ + static int file_ase_mt; + /* The argument of the -march= flag. The architecture we are assembling. */ static int file_mips_arch = CPU_UNKNOWN; static const char *mips_arch_string; *************** static int mips_32bitmode = 0; *** 374,379 **** --- 379,388 ---- #define CPU_HAS_DSP(cpu) (FALSE \ ) + /* Return true if the given CPU supports the MT ASE. */ + #define CPU_HAS_MT(cpu) (FALSE \ + ) + /* True if CPU has a dror instruction. */ #define CPU_HAS_DROR(CPU) ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500) *************** validate_mips_insn (const struct mips_op *** 7765,7770 **** --- 7774,7782 ---- case 'G': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break; case 'H': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break; case 'I': break; + case 't': USE_BITS (OP_MASK_RT, OP_SH_RT); break; + case 'T': USE_BITS (OP_MASK_RT, OP_SH_RT); + USE_BITS (OP_MASK_SEL, OP_SH_SEL); break; default: as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"), c, opc->name, opc->args); *************** validate_mips_insn (const struct mips_op *** 7837,7842 **** --- 7849,7859 ---- case '\'': USE_BITS (OP_MASK_RDDSP, OP_SH_RDDSP); break; case ':': USE_BITS (OP_MASK_DSPSFT_7, OP_SH_DSPSFT_7);break; case '@': USE_BITS (OP_MASK_IMM10, OP_SH_IMM10); break; + case '!': USE_BITS (OP_MASK_MT_U, OP_SH_MT_U); break; + case '$': USE_BITS (OP_MASK_MT_H, OP_SH_MT_H); break; + case '*': USE_BITS (OP_MASK_MTACC_T, OP_SH_MTACC_T); break; + case '&': USE_BITS (OP_MASK_MTACC_D, OP_SH_MTACC_D); break; + case 'g': USE_BITS (OP_MASK_RD, OP_SH_RD); break; default: as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"), c, opc->name, opc->args); *************** mips_ip (char *str, struct mips_cl_insn *** 7935,7940 **** --- 7952,7958 ---- | (file_ase_mips16 ? INSN_MIPS16 : 0) | (mips_opts.ase_mdmx ? INSN_MDMX : 0) | (mips_opts.ase_dsp ? INSN_DSP : 0) + | (mips_opts.ase_mt ? INSN_MT : 0) | (mips_opts.ase_mips3d ? INSN_MIPS3D : 0)), mips_opts.arch)) ok = TRUE; *************** mips_ip (char *str, struct mips_cl_insn *** 8156,8161 **** --- 8174,8233 ---- s = expr_end; continue; + case '!': /* mt 1-bit unsigned immediate in bit 5 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_MT_U) + { + as_warn (_("MT immediate not in range 0..%d (%lu)"), + OP_MASK_MT_U, (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_MT_U; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_MT_U; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '$': /* mt 1-bit unsigned immediate in bit 4 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_MT_H) + { + as_warn (_("MT immediate not in range 0..%d (%lu)"), + OP_MASK_MT_H, (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_MT_H; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_MT_H; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '*': /* four dsp accumulators in bits 18,19 */ + if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' && + s[3] >= '0' && s[3] <= '3') + { + regno = s[3] - '0'; + s += 4; + ip->insn_opcode |= regno << OP_SH_MTACC_T; + continue; + } + else + as_bad (_("Invalid dsp/smartmips acc register")); + break; + + case '&': /* four dsp accumulators in bits 13,14 */ + if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' && + s[3] >= '0' && s[3] <= '3') + { + regno = s[3] - '0'; + s += 4; + ip->insn_opcode |= regno << OP_SH_MTACC_D; + continue; + } + else + as_bad (_("Invalid dsp/smartmips acc register")); + break; + case ',': if (*s++ == *args) continue; *************** do_msbd: *** 8308,8313 **** --- 8380,8413 ---- s = expr_end; continue; + case 'T': /* Coprocessor register */ + /* +T is for disassembly only; never match. */ + break; + + case 't': /* Coprocessor register number */ + if (s[0] == '$' && ISDIGIT (s[1])) + { + ++s; + regno = 0; + do + { + regno *= 10; + regno += *s - '0'; + ++s; + } + while (ISDIGIT (*s)); + if (regno > 31) + as_bad (_("Invalid register number (%d)"), regno); + else + { + ip->insn_opcode |= regno << OP_SH_RT; + continue; + } + } + else + as_bad (_("Invalid coprocessor 0 register number")); + break; + default: as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"), *args, insn->name, insn->args); *************** do_msbd: *** 8442,8447 **** --- 8542,8548 ---- case 'x': /* ignore register name */ case 'z': /* must be zero register */ case 'U': /* destination register (clo/clz). */ + case 'g': /* coprocessor destination register */ s_reset = s; if (s[0] == '$') { *************** do_msbd: *** 8566,8571 **** --- 8667,8673 ---- case 'd': case 'G': case 'K': + case 'g': INSERT_OPERAND (RD, *ip, regno); break; case 'U': *************** do_msbd: *** 8681,8687 **** || strcmp (str, "lwc1") == 0 || strcmp (str, "swc1") == 0 || strcmp (str, "l.s") == 0 ! || strcmp (str, "s.s") == 0)) as_warn (_("Float register should be even, was %d"), regno); --- 8783,8795 ---- || strcmp (str, "lwc1") == 0 || strcmp (str, "swc1") == 0 || strcmp (str, "l.s") == 0 ! || strcmp (str, "s.s") == 0 ! || strcmp (str, "mftc1") == 0 ! || strcmp (str, "mfthc1") == 0 ! || strcmp (str, "cftc1") == 0 ! || strcmp (str, "mttc1") == 0 ! || strcmp (str, "mtthc1") == 0 ! || strcmp (str, "cttc1") == 0)) as_warn (_("Float register should be even, was %d"), regno); *************** struct option md_longopts[] = *** 10222,10230 **** {"mdsp", no_argument, NULL, OPTION_DSP}, #define OPTION_NO_DSP (OPTION_ASE_BASE + 7) {"mno-dsp", no_argument, NULL, OPTION_NO_DSP}, /* Old-style architecture options. Don't add more of these. */ ! #define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 8) #define OPTION_M4650 (OPTION_COMPAT_ARCH_BASE + 0) {"m4650", no_argument, NULL, OPTION_M4650}, #define OPTION_NO_M4650 (OPTION_COMPAT_ARCH_BASE + 1) --- 10330,10342 ---- {"mdsp", no_argument, NULL, OPTION_DSP}, #define OPTION_NO_DSP (OPTION_ASE_BASE + 7) {"mno-dsp", no_argument, NULL, OPTION_NO_DSP}, + #define OPTION_MT (OPTION_ASE_BASE + 8) + {"mt", no_argument, NULL, OPTION_MT}, + #define OPTION_NO_MT (OPTION_ASE_BASE + 9) + {"mno-mt", no_argument, NULL, OPTION_NO_MT}, /* Old-style architecture options. Don't add more of these. */ ! #define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 10) #define OPTION_M4650 (OPTION_COMPAT_ARCH_BASE + 0) {"m4650", no_argument, NULL, OPTION_M4650}, #define OPTION_NO_M4650 (OPTION_COMPAT_ARCH_BASE + 1) *************** md_parse_option (int c, char *arg) *** 10484,10489 **** --- 10596,10609 ---- mips_opts.ase_dsp = 0; break; + case OPTION_MT: + mips_opts.ase_mt = 1; + break; + + case OPTION_NO_MT: + mips_opts.ase_mt = 0; + break; + case OPTION_MIPS16: mips_opts.mips16 = 1; mips_no_prev_insn (); *************** mips_after_parse_args (void) *** 10840,10851 **** --- 10960,10974 ---- mips_opts.ase_mdmx = (CPU_HAS_MDMX (file_mips_arch)) ? 1 : 0; if (mips_opts.ase_dsp == -1) mips_opts.ase_dsp = (CPU_HAS_DSP (file_mips_arch)) ? 1 : 0; + if (mips_opts.ase_mt == -1) + mips_opts.ase_mt = (CPU_HAS_MT (file_mips_arch)) ? 1 : 0; file_mips_isa = mips_opts.isa; file_ase_mips16 = mips_opts.mips16; file_ase_mips3d = mips_opts.ase_mips3d; file_ase_mdmx = mips_opts.ase_mdmx; file_ase_dsp = mips_opts.ase_dsp; + file_ase_mt = mips_opts.ase_mt; mips_opts.gp32 = file_mips_gp32; mips_opts.fp32 = file_mips_fp32; *************** s_mipsset (int x ATTRIBUTE_UNUSED) *** 11787,11792 **** --- 11910,11919 ---- mips_opts.ase_dsp = 1; else if (strcmp (name, "nodsp") == 0) mips_opts.ase_dsp = 0; + else if (strcmp (name, "mt") == 0) + mips_opts.ase_mt = 1; + else if (strcmp (name, "nomt") == 0) + mips_opts.ase_mt = 0; else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0) { int reset = 0; *************** mips_elf_final_processing (void) *** 13523,13528 **** --- 13650,13657 ---- /* Set MIPS ELF flags for ASEs. */ /* We may need to define a new flag for DSP ASE, and set this flag when file_ase_dsp is true. */ + /* We may need to define a new flag for MT ASE, and set this flag when + file_ase_mt is true. */ if (file_ase_mips16) elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16; #if 0 /* XXX FIXME */ *************** MIPS options:\n\ *** 14230,14235 **** --- 14359,14367 ---- -mdsp generate DSP instructions\n\ -mno-dsp do not generate DSP instructions\n")); fprintf (stream, _("\ + -mt generate MT instructions\n\ + -mno-mt do not generate MT instructions\n")); + fprintf (stream, _("\ -mfix-vr4120 work around certain VR4120 errata\n\ -mfix-vr4130 work around VR4130 mflo/mfhi errata\n\ -mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\ Index: gas/testsuite/gas/mips/mips.exp =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v retrieving revision 1.108 diff -c -3 -p -r1.108 mips.exp *** gas/testsuite/gas/mips/mips.exp 25 Aug 2005 18:21:47 -0000 1.108 --- gas/testsuite/gas/mips/mips.exp 29 Aug 2005 23:00:12 -0000 *************** if { [istarget mips*-*-*] } then { *** 763,768 **** --- 763,769 ---- run_list_test "noat-7" "" run_dump_test_arches "mips32-dsp" [mips_arch_list_matching mips32 !sb1] + run_dump_test_arches "mips32-mt" [mips_arch_list_matching mips32r2 !gpr64] if { $elf && !$no_mips16 } { run_dump_test "mips16-dwarf2"