Index: include/opcode/mips.h =================================================================== RCS file: /cvs/src/src/include/opcode/mips.h,v retrieving revision 1.43 diff -c -3 -p -r1.43 mips.h *** include/opcode/mips.h 10 May 2005 10:21:13 -0000 1.43 --- include/opcode/mips.h 12 Aug 2005 23:56:56 -0000 *************** Software Foundation, 51 Franklin Street *** 148,153 **** --- 148,175 ---- #define OP_MASK_EXTMSBD 0x1f /* "ext" MSBD. */ #define OP_SH_EXTMSBD 11 + /* MIPS DSP ASE */ + #define OP_SH_DSPACC 11 + #define OP_MASK_DSPACC 0x3 + #define OP_SH_DSPACC_S 21 + #define OP_MASK_DSPACC_S 0x3 + #define OP_SH_DSPSFT 20 + #define OP_MASK_DSPSFT 0x3f + #define OP_SH_DSPSFT_7 19 + #define OP_MASK_DSPSFT_7 0x7f + #define OP_SH_SA3 21 + #define OP_MASK_SA3 0x7 + #define OP_SH_SA4 21 + #define OP_MASK_SA4 0xf + #define OP_SH_IMM8 16 + #define OP_MASK_IMM8 0xff + #define OP_SH_IMM10 16 + #define OP_MASK_IMM10 0x3ff + #define OP_SH_WRDSP 11 + #define OP_MASK_WRDSP 0x3f + #define OP_SH_RDDSP 16 + #define OP_MASK_RDDSP 0x3f + #define OP_OP_COP0 0x10 #define OP_OP_COP1 0x11 #define OP_OP_COP2 0x12 *************** struct mips_opcode *** 296,301 **** --- 318,336 ---- "Y" MDMX source register (OP_*_FS) "Z" MDMX source register (OP_*_FT) + DSP ASE usage: + "3" 3 bit unsigned immediate (OP_*_SA3) + "4" 4 bit unsigned immediate (OP_*_SA4) + "5" 8 bit unsigned immediate (OP_*_IMM8) + "6" 5 bit unsigned immediate (OP_*_RS) + "7" 2 bit dsp accumulator register (OP_*_DSPACC) + "8" 6 bit unsigned immediate (OP_*_WRDSP) + "9" 2 bit dsp accumulator register (OP_*_DSPACC_S) + "0" 6 bit signed immediate (OP_*_DSPSFT) + ":" 7 bit signed immediate (OP_*_DSPSFT_7) + "'" 6 bit unsigned immediate (OP_*_RDDSP) + "@" 10 bit signed immediate (OP_*_IMM10) + Other: "()" parens surrounding optional value "," separates operands *************** struct mips_opcode *** 303,309 **** "+" Start of extension sequence. Characters used so far, for quick reference when adding more: ! "%[]<>(),+" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefhijklopqrstuvwxz" --- 338,345 ---- "+" Start of extension sequence. Characters used so far, for quick reference when adding more: ! "34567890" ! "%[]<>(),+:'@" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefhijklopqrstuvwxz" *************** struct mips_opcode *** 411,417 **** #define INSN_ISA64R2 0x00000100 /* Masks used for MIPS-defined ASEs. */ ! #define INSN_ASE_MASK 0x0000f000 /* MIPS 16 ASE */ #define INSN_MIPS16 0x00002000 --- 447,453 ---- #define INSN_ISA64R2 0x00000100 /* Masks used for MIPS-defined ASEs. */ ! #define INSN_ASE_MASK 0x0400f000 /* MIPS 16 ASE */ #define INSN_MIPS16 0x00002000 *************** struct mips_opcode *** 419,424 **** --- 455,462 ---- #define INSN_MIPS3D 0x00004000 /* MDMX ASE */ #define INSN_MDMX 0x00008000 + /* DSP ASE */ + #define INSN_DSP 0x04000000 /* Chip specific instructions. These are bitmasks. */ Index: opcodes/mips-opc.c =================================================================== RCS file: /cvs/src/src/opcodes/mips-opc.c,v retrieving revision 1.51 diff -c -3 -p -r1.51 mips-opc.c *** opcodes/mips-opc.c 7 May 2005 07:34:30 -0000 1.51 --- opcodes/mips-opc.c 12 Aug 2005 23:56:57 -0000 *************** Software Foundation, 51 Franklin Street *** 119,124 **** --- 119,151 ---- #define G3 (I4 \ ) + /* MIPS DSP ASE support. + NOTE: + 1. MIPS DSP ASE includes 4 accumulators ($ac0 - $ac3). $ac0 is the pair + of original HI and LO. $ac1, $ac2 and $ac3 are new registers, and have + the same structure as $ac0 (HI + LO). For DSP instructions that write or + read accumulators (that may be $ac0), we add WR_a (WR_HILO) or RD_a + (RD_HILO) attritubes, such that HILO dependences are maintained + conservatively. + + 2. For some mul. instructions that use integer registers as destinations + but destroy HI+LO as side-effect, we add WR_HILO to their attritubes. + + 3. MIPS DSP ASE includes a new DSP control register, which has 6 fields + (ccond, outflag, EFI, c, scount, pos). Many DSP instructions read or write + certain fields of the DSP control register. For simplicity, we decide not + to track dependences of these fields. + However, "bposge32" is a branch instruction that depends on the "pos" + field. In order to make sure that GAS does not reorder DSP instructions + that writes the "pos" field and "bposge32", we add DSP_VOLA (INSN_TRAP) + attritube to those instructions that write the "pos" field. */ + + #define WR_a WR_HILO /* Write dsp accumulators (reuse WR_HILO) */ + #define RD_a RD_HILO /* Read dsp accumulators (reuse RD_HILO) */ + #define MOD_a WR_a|RD_a + #define DSP_VOLA INSN_TRAP + #define D32 (INSN_DSP) + /* 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 *** 741,747 **** --- 768,776 ---- {"mfc3", "t,G,H", 0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 0, I32 }, {"mfdr", "t,G", 0x7000003d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5 }, {"mfhi", "d", 0x00000010, 0xffff07ff, WR_d|RD_HI, 0, I1 }, + {"mfhi", "d,9", 0x00000010, 0xff9f07ff, WR_d|RD_HI, 0, D32 }, {"mflo", "d", 0x00000012, 0xffff07ff, WR_d|RD_LO, 0, I1 }, + {"mflo", "d,9", 0x00000012, 0xff9f07ff, WR_d|RD_LO, 0, D32 }, {"min.ob", "X,Y,Q", 0x78000006, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, {"min.ob", "D,S,T", 0x4ac00006, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, {"min.ob", "D,S,T[e]", 0x48000006, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, *************** const struct mips_opcode mips_builtin_op *** 804,810 **** --- 833,841 ---- {"mtc3", "t,G,H", 0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC, 0, I32 }, {"mtdr", "t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5 }, {"mthi", "s", 0x00000011, 0xfc1fffff, RD_s|WR_HI, 0, I1 }, + {"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 }, {"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 *** 1215,1220 **** --- 1246,1357 ---- 4010 any more, so move this insn out of the way. If the object format gave us more info, we could do this right. */ {"addciu", "t,r,j", 0x70000000, 0xfc000000, WR_t|RD_s, 0, L1 }, + /* MIPS DSP ASE */ + {"absq_s.ph", "d,t", 0x7c000252, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"absq_s.w", "d,t", 0x7c000452, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"addq.ph", "d,s,t", 0x7c000290, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"addq_s.ph", "d,s,t", 0x7c000390, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"addq_s.w", "d,s,t", 0x7c000590, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"addsc", "d,s,t", 0x7c000410, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"addu.qb", "d,s,t", 0x7c000010, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"addu_s.qb", "d,s,t", 0x7c000110, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"addwc", "d,s,t", 0x7c000450, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"bitrev", "d,t", 0x7c0006d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"bposge32", "p", 0x041c0000, 0xffff0000, CBD, 0, D32 }, + {"cmp.eq.ph", "s,t", 0x7c000211, 0xfc00ffff, RD_s|RD_t, 0, D32 }, + {"cmpgu.eq.qb", "d,s,t", 0x7c000111, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"cmpgu.le.qb", "d,s,t", 0x7c000191, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"cmpgu.lt.qb", "d,s,t", 0x7c000151, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"cmp.le.ph", "s,t", 0x7c000291, 0xfc00ffff, RD_s|RD_t, 0, D32 }, + {"cmp.lt.ph", "s,t", 0x7c000251, 0xfc00ffff, RD_s|RD_t, 0, D32 }, + {"cmpu.eq.qb", "s,t", 0x7c000011, 0xfc00ffff, RD_s|RD_t, 0, D32 }, + {"cmpu.le.qb", "s,t", 0x7c000091, 0xfc00ffff, RD_s|RD_t, 0, D32 }, + {"cmpu.lt.qb", "s,t", 0x7c000051, 0xfc00ffff, RD_s|RD_t, 0, D32 }, + {"dpaq_sa.l.w", "7,s,t", 0x7c000330, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"dpaq_s.w.ph", "7,s,t", 0x7c000130, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"dpau.h.qbl", "7,s,t", 0x7c0000f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"dpau.h.qbr", "7,s,t", 0x7c0001f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"dpsq_sa.l.w", "7,s,t", 0x7c000370, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"dpsq_s.w.ph", "7,s,t", 0x7c000170, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"dpsu.h.qbl", "7,s,t", 0x7c0002f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"dpsu.h.qbr", "7,s,t", 0x7c0003f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"extpdp", "t,7,6", 0x7c0002b8, 0xfc00e7ff, WR_t|RD_a|DSP_VOLA, 0, D32 }, + {"extpdpv", "t,7,s", 0x7c0002f8, 0xfc00e7ff, WR_t|RD_a|RD_s|DSP_VOLA, 0, D32 }, + {"extp", "t,7,6", 0x7c0000b8, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, + {"extpv", "t,7,s", 0x7c0000f8, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, + {"extr_rs.w", "t,7,6", 0x7c0001b8, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, + {"extr_r.w", "t,7,6", 0x7c000138, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, + {"extr_s.h", "t,7,6", 0x7c0003b8, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, + {"extrv_rs.w", "t,7,s", 0x7c0001f8, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, + {"extrv_r.w", "t,7,s", 0x7c000178, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, + {"extrv_s.h", "t,7,s", 0x7c0003f8, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, + {"extrv.w", "t,7,s", 0x7c000078, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, + {"extr.w", "t,7,6", 0x7c000038, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, + {"insv", "t,s", 0x7c00000c, 0xfc00ffff, WR_t|RD_s, 0, D32 }, + {"lbux", "d,t(b)", 0x7c00018a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b, 0, D32 }, + {"lhx", "d,t(b)", 0x7c00010a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b, 0, D32 }, + {"lwx", "d,t(b)", 0x7c00000a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b, 0, D32 }, + {"maq_sa.w.phl", "7,s,t", 0x7c000430, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"maq_sa.w.phr", "7,s,t", 0x7c0004b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"maq_s.w.phl", "7,s,t", 0x7c000530, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"maq_s.w.phr", "7,s,t", 0x7c0005b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"modsub", "d,s,t", 0x7c000490, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"mthlip", "s,7", 0x7c0007f8, 0xfc1fe7ff, RD_s|MOD_a|DSP_VOLA, 0, D32 }, + {"muleq_s.w.phl", "d,s,t", 0x7c000710, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, + {"muleq_s.w.phr", "d,s,t", 0x7c000750, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, + {"muleu_s.ph.qbl", "d,s,t", 0x7c000190, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, + {"muleu_s.ph.qbr", "d,s,t", 0x7c0001d0, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, + {"mulq_rs.ph", "d,s,t", 0x7c0007d0, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, + {"mulsaq_s.w.ph", "7,s,t", 0x7c0001b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, + {"packrl.ph", "d,s,t", 0x7c000391, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"pick.ph", "d,s,t", 0x7c0002d1, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"pick.qb", "d,s,t", 0x7c0000d1, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"precequ.ph.qbla", "d,t", 0x7c000192, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"precequ.ph.qbl", "d,t", 0x7c000112, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"precequ.ph.qbra", "d,t", 0x7c0001d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"precequ.ph.qbr", "d,t", 0x7c000152, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"preceq.w.phl", "d,t", 0x7c000312, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"preceq.w.phr", "d,t", 0x7c000352, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"preceu.ph.qbla", "d,t", 0x7c000792, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"preceu.ph.qbl", "d,t", 0x7c000712, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"preceu.ph.qbra", "d,t", 0x7c0007d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"preceu.ph.qbr", "d,t", 0x7c000752, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"precrq.ph.w", "d,s,t", 0x7c000511, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"precrq.qb.ph", "d,s,t", 0x7c000311, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"precrq_rs.ph.w", "d,s,t", 0x7c000551, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"precrqu_s.qb.ph", "d,s,t", 0x7c0003d1, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"raddu.w.qb", "d,s", 0x7c000510, 0xfc1f07ff, WR_d|RD_s, 0, D32 }, + {"rddsp", "d", 0x7fff04b8, 0xffff07ff, WR_d, 0, D32 }, + {"rddsp", "d,'", 0x7c0004b8, 0xffc007ff, WR_d, 0, D32 }, + {"repl.ph", "d,@", 0x7c000292, 0xfc0007ff, WR_d, 0, D32 }, + {"repl.qb", "d,5", 0x7c000092, 0xff0007ff, WR_d, 0, D32 }, + {"replv.ph", "d,t", 0x7c0002d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"replv.qb", "d,t", 0x7c0000d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, + {"shilo", "7,0", 0x7c0006b8, 0xfc0fe7ff, MOD_a, 0, D32 }, + {"shilov", "7,s", 0x7c0006f8, 0xfc1fe7ff, MOD_a|RD_s, 0, D32 }, + {"shll.ph", "d,t,4", 0x7c000213, 0xfe0007ff, WR_d|RD_t, 0, D32 }, + {"shll.qb", "d,t,3", 0x7c000013, 0xff0007ff, WR_d|RD_t, 0, D32 }, + {"shll_s.ph", "d,t,4", 0x7c000313, 0xfe0007ff, WR_d|RD_t, 0, D32 }, + {"shll_s.w", "d,t,6", 0x7c000513, 0xfc0007ff, WR_d|RD_t, 0, D32 }, + {"shllv.ph", "d,t,s", 0x7c000293, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"shllv.qb", "d,t,s", 0x7c000093, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"shllv_s.ph", "d,t,s", 0x7c000393, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"shllv_s.w", "d,t,s", 0x7c000593, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"shra.ph", "d,t,4", 0x7c000253, 0xfe0007ff, WR_d|RD_t, 0, D32 }, + {"shra_r.ph", "d,t,4", 0x7c000353, 0xfe0007ff, WR_d|RD_t, 0, D32 }, + {"shra_r.w", "d,t,6", 0x7c000553, 0xfc0007ff, WR_d|RD_t, 0, D32 }, + {"shrav.ph", "d,t,s", 0x7c0002d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"shrav_r.ph", "d,t,s", 0x7c0003d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"shrav_r.w", "d,t,s", 0x7c0005d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"shrl.qb", "d,t,3", 0x7c000053, 0xff0007ff, WR_d|RD_t, 0, D32 }, + {"shrlv.qb", "d,t,s", 0x7c0000d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"subq.ph", "d,s,t", 0x7c0002d0, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"subq_s.ph", "d,s,t", 0x7c0003d0, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"subq_s.w", "d,s,t", 0x7c0005d0, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"subu.qb", "d,s,t", 0x7c000050, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, + {"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 }, }; #define MIPS_NUM_OPCODES \ Index: opcodes/mips-dis.c =================================================================== RCS file: /cvs/src/src/opcodes/mips-dis.c,v retrieving revision 1.52 diff -c -3 -p -r1.52 mips-dis.c *** opcodes/mips-dis.c 7 Jul 2005 19:27:51 -0000 1.52 --- opcodes/mips-dis.c 12 Aug 2005 23:56:57 -0000 *************** const struct mips_arch_choice mips_arch_ *** 370,395 **** MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), page 1. */ { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, ! ISA_MIPS32 | INSN_MIPS16, mips_cp0_names_mips3264, mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), mips_hwr_names_numeric }, { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, ! ISA_MIPS32R2 | INSN_MIPS16, mips_cp0_names_mips3264r2, mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_hwr_names_mips3264r2 }, /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */ { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64, ! ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX, mips_cp0_names_mips3264, mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), mips_hwr_names_numeric }, { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2, ! ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX, mips_cp0_names_mips3264r2, mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_hwr_names_mips3264r2 }, --- 370,395 ---- MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), page 1. */ { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, ! ISA_MIPS32 | INSN_MIPS16 | INSN_DSP, mips_cp0_names_mips3264, mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), 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 }, /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */ { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64, ! ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX | INSN_DSP, mips_cp0_names_mips3264, mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), mips_hwr_names_numeric }, { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2, ! ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX | INSN_DSP, mips_cp0_names_mips3264r2, mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_hwr_names_mips3264r2 }, *************** print_insn_args (const char *d, *** 780,785 **** --- 780,846 ---- } break; + case '3': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_SA3) & OP_MASK_SA3); + break; + + case '4': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_SA4) & OP_MASK_SA4); + break; + + case '5': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_IMM8) & OP_MASK_IMM8); + break; + + case '6': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_RS) & OP_MASK_RS); + break; + + case '7': + (*info->fprintf_func) (info->stream, "$ac%ld", + (l >> OP_SH_DSPACC) & OP_MASK_DSPACC); + break; + + case '8': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_WRDSP) & OP_MASK_WRDSP); + break; + + case '9': + (*info->fprintf_func) (info->stream, "$ac%ld", + (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S); + break; + + case '0': /* dsp 6-bit signed immediate in bit 20 */ + delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT); + if (delta & 0x20) /* test sign bit */ + delta |= ~OP_MASK_DSPSFT; + (*info->fprintf_func) (info->stream, "%d", delta); + break; + + case ':': /* dsp 7-bit signed immediate in bit 19 */ + delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7); + if (delta & 0x40) /* test sign bit */ + delta |= ~OP_MASK_DSPSFT_7; + (*info->fprintf_func) (info->stream, "%d", delta); + break; + + case '\'': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_RDDSP) & OP_MASK_RDDSP); + break; + + case '@': /* dsp 10-bit signed immediate in bit 16 */ + delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10); + if (delta & 0x200) /* test sign bit */ + delta |= ~OP_MASK_IMM10; + (*info->fprintf_func) (info->stream, "%d", delta); + 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.316 diff -c -3 -p -r1.316 tc-mips.c *** gas/config/tc-mips.c 30 Jul 2005 13:53:11 -0000 1.316 --- gas/config/tc-mips.c 12 Aug 2005 23:56:58 -0000 *************** struct mips_set_options *** 193,198 **** --- 193,199 ---- command line options, and based on the default architecture. */ int ase_mips3d; int ase_mdmx; + int ase_dsp; /* 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; *** 243,249 **** static struct mips_set_options mips_opts = { ! ISA_UNKNOWN, -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. --- 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. *************** static int file_ase_mips3d; *** 267,272 **** --- 268,277 ---- command line (e.g., by -march). */ static int file_ase_mdmx; + /* True if -mdsp was passed or implied by arguments passed on the + command line (e.g., by -march). */ + static int file_ase_dsp; + /* 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; *** 365,370 **** --- 370,379 ---- #define CPU_HAS_MDMX(cpu) (FALSE \ ) + /* Return true if the given CPU supports the DSP ASE. */ + #define CPU_HAS_DSP(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 *** 7817,7822 **** --- 7826,7842 ---- case '%': USE_BITS (OP_MASK_VECALIGN, OP_SH_VECALIGN); break; case '[': break; case ']': break; + case '3': USE_BITS (OP_MASK_SA3, OP_SH_SA3); break; + case '4': USE_BITS (OP_MASK_SA4, OP_SH_SA4); break; + case '5': USE_BITS (OP_MASK_IMM8, OP_SH_IMM8); break; + case '6': USE_BITS (OP_MASK_RS, OP_SH_RS); break; + case '7': USE_BITS (OP_MASK_DSPACC, OP_SH_DSPACC); break; + case '8': USE_BITS (OP_MASK_WRDSP, OP_SH_WRDSP); break; + case '9': USE_BITS (OP_MASK_DSPACC_S, OP_SH_DSPACC_S);break; + case '0': USE_BITS (OP_MASK_DSPSFT, OP_SH_DSPSFT); break; + 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; 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 *** 7851,7856 **** --- 7871,7877 ---- unsigned int limlo, limhi; char *s_reset; char save_c = 0; + offsetT min_range, max_range; insn_error = NULL; *************** mips_ip (char *str, struct mips_cl_insn *** 7913,7918 **** --- 7934,7940 ---- (mips_opts.isa | (file_ase_mips16 ? INSN_MIPS16 : 0) | (mips_opts.ase_mdmx ? INSN_MDMX : 0) + | (mips_opts.ase_dsp ? INSN_DSP : 0) | (mips_opts.ase_mips3d ? INSN_MIPS3D : 0)), mips_opts.arch)) ok = TRUE; *************** mips_ip (char *str, struct mips_cl_insn *** 7965,7970 **** --- 7987,8161 ---- return; break; + case '3': /* dsp 3-bit unsigned immediate in bit 21 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_SA3) + { + as_warn (_("DSP immediate not in range 0..%d (%lu)"), + OP_MASK_SA3, (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_SA3; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SA3; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '4': /* dsp 4-bit unsigned immediate in bit 21 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_SA4) + { + as_warn (_("DSP immediate not in range 0..%d (%lu)"), + OP_MASK_SA4, (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_SA4; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SA4; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '5': /* dsp 8-bit unsigned immediate in bit 16 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_IMM8) + { + as_warn (_("DSP immediate not in range 0..%d (%lu)"), + OP_MASK_IMM8, (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_IMM8; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_IMM8; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '6': /* dsp 5-bit unsigned immediate in bit 21 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_RS) + { + as_warn (_("DSP immediate not in range 0..%d (%lu)"), + OP_MASK_RS, (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_RS; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_RS; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '7': /* four dsp accumulators in bits 11,12 */ + 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_DSPACC; + continue; + } + else + as_bad (_("Invalid dsp acc register")); + break; + + case '8': /* dsp 6-bit unsigned immediate in bit 11 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_WRDSP) + { + as_warn (_("DSP immediate not in range 0..%d (%lu)"), + OP_MASK_WRDSP, + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_WRDSP; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_WRDSP; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '9': /* four dsp accumulators in bits 21,22 */ + 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_DSPACC_S; + continue; + } + else + as_bad (_("Invalid dsp acc register")); + break; + + case '0': /* dsp 6-bit signed immediate in bit 20 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + min_range = -((OP_MASK_DSPSFT + 1) >> 1); + max_range = ((OP_MASK_DSPSFT + 1) >> 1) - 1; + if (imm_expr.X_add_number < min_range || + imm_expr.X_add_number > max_range) + { + as_warn (_("DSP immediate not in range %ld..%ld (%ld)"), + (long) min_range, (long) max_range, + (long) imm_expr.X_add_number); + } + imm_expr.X_add_number &= OP_MASK_DSPSFT; + ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number + << OP_SH_DSPSFT); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '\'': /* dsp 6-bit unsigned immediate in bit 16 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if (imm_expr.X_add_number & ~OP_MASK_RDDSP) + { + as_warn (_("DSP immediate not in range 0..%d (%lu)"), + OP_MASK_RDDSP, + (unsigned long) imm_expr.X_add_number); + imm_expr.X_add_number &= OP_MASK_RDDSP; + } + ip->insn_opcode |= imm_expr.X_add_number << OP_SH_RDDSP; + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case ':': /* dsp 7-bit signed immediate in bit 19 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + min_range = -((OP_MASK_DSPSFT_7 + 1) >> 1); + max_range = ((OP_MASK_DSPSFT_7 + 1) >> 1) - 1; + if (imm_expr.X_add_number < min_range || + imm_expr.X_add_number > max_range) + { + as_warn (_("DSP immediate not in range %ld..%ld (%ld)"), + (long) min_range, (long) max_range, + (long) imm_expr.X_add_number); + } + imm_expr.X_add_number &= OP_MASK_DSPSFT_7; + ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number + << OP_SH_DSPSFT_7); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + + case '@': /* dsp 10-bit signed immediate in bit 16 */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + min_range = -((OP_MASK_IMM10 + 1) >> 1); + max_range = ((OP_MASK_IMM10 + 1) >> 1) - 1; + if (imm_expr.X_add_number < min_range || + imm_expr.X_add_number > max_range) + { + as_warn (_("DSP immediate not in range %ld..%ld (%ld)"), + (long) min_range, (long) max_range, + (long) imm_expr.X_add_number); + } + imm_expr.X_add_number &= OP_MASK_IMM10; + ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number + << OP_SH_IMM10); + imm_expr.X_op = O_absent; + s = expr_end; + continue; + case ',': if (*s++ == *args) continue; *************** struct option md_longopts[] = *** 10027,10035 **** {"mdmx", no_argument, NULL, OPTION_MDMX}, #define OPTION_NO_MDMX (OPTION_ASE_BASE + 5) {"no-mdmx", no_argument, NULL, OPTION_NO_MDMX}, /* Old-style architecture options. Don't add more of these. */ ! #define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 6) #define OPTION_M4650 (OPTION_COMPAT_ARCH_BASE + 0) {"m4650", no_argument, NULL, OPTION_M4650}, #define OPTION_NO_M4650 (OPTION_COMPAT_ARCH_BASE + 1) --- 10218,10230 ---- {"mdmx", no_argument, NULL, OPTION_MDMX}, #define OPTION_NO_MDMX (OPTION_ASE_BASE + 5) {"no-mdmx", no_argument, NULL, OPTION_NO_MDMX}, + #define OPTION_DSP (OPTION_ASE_BASE + 6) + {"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) *************** md_parse_option (int c, char *arg) *** 10281,10286 **** --- 10476,10489 ---- mips_opts.ase_mdmx = 0; break; + case OPTION_DSP: + mips_opts.ase_dsp = 1; + break; + + case OPTION_NO_DSP: + mips_opts.ase_dsp = 0; + break; + case OPTION_MIPS16: mips_opts.mips16 = 1; mips_no_prev_insn (); *************** mips_after_parse_args (void) *** 10635,10645 **** --- 10838,10851 ---- mips_opts.ase_mips3d = (CPU_HAS_MIPS3D (file_mips_arch)) ? 1 : 0; if (mips_opts.ase_mdmx == -1) 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; 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; mips_opts.gp32 = file_mips_gp32; mips_opts.fp32 = file_mips_fp32; *************** s_mipsset (int x ATTRIBUTE_UNUSED) *** 11577,11582 **** --- 11783,11792 ---- mips_opts.ase_mdmx = 1; else if (strcmp (name, "nomdmx") == 0) mips_opts.ase_mdmx = 0; + else if (strcmp (name, "dsp") == 0) + mips_opts.ase_dsp = 1; + else if (strcmp (name, "nodsp") == 0) + mips_opts.ase_dsp = 0; else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0) { int reset = 0; *************** mips_elf_final_processing (void) *** 13311,13316 **** --- 13521,13528 ---- elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC; /* 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. */ if (file_ase_mips16) elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16; #if 0 /* XXX FIXME */ *************** MIPS options:\n\ *** 14014,14019 **** --- 14226,14234 ---- -mips16 generate mips16 instructions\n\ -no-mips16 do not generate mips16 instructions\n")); fprintf (stream, _("\ + -mdsp generate DSP instructions\n\ + -mno-dsp do not generate DSP 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.107 diff -c -3 -p -r1.107 mips.exp *** gas/testsuite/gas/mips/mips.exp 13 Apr 2005 18:17:10 -0000 1.107 --- gas/testsuite/gas/mips/mips.exp 12 Aug 2005 23:56:58 -0000 *************** if { [istarget mips*-*-*] } then { *** 762,767 **** --- 762,769 ---- run_list_test "noat-6" "" run_list_test "noat-7" "" + run_dump_test_arches "mips32-dsp" [mips_arch_list_matching mips32 !sb1] + if { $elf && !$no_mips16 } { run_dump_test "mips16-dwarf2" if $has_newabi {