include/opcode/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 18 Dec 2010 11:14:14 +0000 (11:14 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sat, 18 Dec 2010 11:14:14 +0000 (11:14 +0000)
2010-12-14  Mingjie Xing  <mingjie.xing@gmail.com>

* mips.h (OP_*_OFFSET_A, OP_*_OFFSET_B, OP_*_OFFSET_C)
(OP_*_RZ, OP_*_FZ, INSN2_M_FP_D, INSN2_WRITE_GPR_Z, INSN2_WRITE_FPR_Z)
(INSN2_READ_GPR_Z, INSN2_READ_FPR_Z, INSN2_READ_GPR_D): Define.

opcodes/
2010-12-14  Mingjie Xing  <mingjie.xing@gmail.com>

* mips-opc.c (WR_z, WR_Z, RD_z, RD_Z, RD_d): Define.
(mips_builtin_opcodes): Add loongson3a specific instructions.
* mips-dis.c (print_insn_args): Handle the new arguments +a|b|c|z|Z.

gas/
2010-12-14  Mingjie Xing  <mingjie.xing@gmail.com>

* config/tc-mips.c (insn_uses_reg): Handle the new flags
INSN2_READ_FPR_Z, INSN2_READ_GPR_D and INSN2_READ_GPR_Z.
(append_insn): Handle delay-slot filling for the new flags.
(validate_mips_insn): Handle the new arguments +a|b|c|z|Z.
(mips_ip): Handle the new arguments +a|b|c|z|Z.

gas/testsuite/
2010-12-14  Mingjie Xing  <mingjie.xing@gmail.com>

* gas/mips/loongson-3a-2.s, gas/mips/loongson-3a-2.d,
gas/mips/loongson-3a-3.s, gas/mips/loongson-3a-3.d: New tests.
* gas/mips/mips.exp: Run them.

13 files changed:
gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/loongson-3a-2.d [new file with mode: 0644]
gas/testsuite/gas/mips/loongson-3a-2.s [new file with mode: 0644]
gas/testsuite/gas/mips/loongson-3a-3.d [new file with mode: 0644]
gas/testsuite/gas/mips/loongson-3a-3.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
include/opcode/ChangeLog
include/opcode/mips.h
opcodes/ChangeLog
opcodes/mips-dis.c
opcodes/mips-opc.c

index ca9b61d..50216fd 100644 (file)
@@ -1,3 +1,11 @@
+2010-12-18  Mingjie Xing  <mingjie.xing@gmail.com>
+
+       * config/tc-mips.c (insn_uses_reg): Handle the new flags
+       INSN2_READ_FPR_Z, INSN2_READ_GPR_D and INSN2_READ_GPR_Z.
+       (append_insn): Handle delay-slot filling for the new flags.
+       (validate_mips_insn): Handle the new arguments +a|b|c|z|Z.
+       (mips_ip): Handle the new arguments +a|b|c|z|Z.
+
 2010-12-18  DJ Delorie  <dj@redhat.com>
 
        * config/rx-parse.y (SUB): Correct subtraction of immediate
index 65d1989..20bf431 100644 (file)
@@ -2275,6 +2275,10 @@ insn_uses_reg (const struct mips_cl_insn *ip, unsigned int reg,
          && ((EXTRACT_OPERAND (FT, *ip) & ~(unsigned) 1)
              == (reg &~ (unsigned) 1)))
        return 1;
+      if ((ip->insn_mo->pinfo2 & INSN2_READ_FPR_Z)
+         && ((EXTRACT_OPERAND (FZ, *ip) & ~(unsigned) 1)
+             == (reg &~ (unsigned) 1)))
+       return 1;
     }
   else if (! mips_opts.mips16)
     {
@@ -2284,6 +2288,12 @@ insn_uses_reg (const struct mips_cl_insn *ip, unsigned int reg,
       if ((ip->insn_mo->pinfo & INSN_READ_GPR_T)
          && EXTRACT_OPERAND (RT, *ip) == reg)
        return 1;
+      if ((ip->insn_mo->pinfo2 & INSN2_READ_GPR_D)
+         && EXTRACT_OPERAND (RD, *ip) == reg)
+       return 1;
+      if ((ip->insn_mo->pinfo2 & INSN2_READ_GPR_Z)
+         && EXTRACT_OPERAND (RZ, *ip) == reg)
+       return 1;
     }
   else
     {
@@ -2809,6 +2819,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
             bfd_reloc_code_real_type *reloc_type)
 {
   unsigned long prev_pinfo, pinfo;
+  unsigned long prev_pinfo2, pinfo2;
   relax_stateT prev_insn_frag_type = 0;
   bfd_boolean relaxed_branch = FALSE;
   segment_info_type *si = seg_info (now_seg);
@@ -2822,7 +2833,9 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   file_ase_mips16 |= mips_opts.mips16;
 
   prev_pinfo = history[0].insn_mo->pinfo;
+  prev_pinfo2 = history[0].insn_mo->pinfo2;
   pinfo = ip->insn_mo->pinfo;
+  pinfo2 = ip->insn_mo->pinfo2;
 
   if (mips_relax.sequence != 2 && !mips_opts.noreorder)
     {
@@ -3162,7 +3175,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   /* Update the register mask information.  */
   if (! mips_opts.mips16)
     {
-      if (pinfo & INSN_WRITE_GPR_D)
+      if ((pinfo & INSN_WRITE_GPR_D) || (pinfo2 & INSN2_READ_GPR_D))
        mips_gprmask |= 1 << EXTRACT_OPERAND (RD, *ip);
       if ((pinfo & (INSN_WRITE_GPR_T | INSN_READ_GPR_T)) != 0)
        mips_gprmask |= 1 << EXTRACT_OPERAND (RT, *ip);
@@ -3170,6 +3183,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
        mips_gprmask |= 1 << EXTRACT_OPERAND (RS, *ip);
       if (pinfo & INSN_WRITE_GPR_31)
        mips_gprmask |= 1 << RA;
+      if (pinfo2 & (INSN2_WRITE_GPR_Z | INSN2_READ_GPR_Z))
+       mips_gprmask |= 1 << EXTRACT_OPERAND (RZ, *ip);
       if (pinfo & INSN_WRITE_FPR_D)
        mips_cprmask[1] |= 1 << EXTRACT_OPERAND (FD, *ip);
       if ((pinfo & (INSN_WRITE_FPR_S | INSN_READ_FPR_S)) != 0)
@@ -3178,6 +3193,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
        mips_cprmask[1] |= 1 << EXTRACT_OPERAND (FT, *ip);
       if ((pinfo & INSN_READ_FPR_R) != 0)
        mips_cprmask[1] |= 1 << EXTRACT_OPERAND (FR, *ip);
+      if (pinfo2 & (INSN2_WRITE_FPR_Z | INSN2_READ_FPR_Z))
+       mips_cprmask[1] |= 1 << EXTRACT_OPERAND (FZ, *ip);
       if (pinfo & INSN_COP)
        {
          /* We don't keep enough information to sort these cases out.
@@ -3272,6 +3289,10 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
                  && (prev_pinfo & INSN_WRITE_GPR_D)
                  && insn_uses_reg (ip, EXTRACT_OPERAND (RD, history[0]),
                                    MIPS_GR_REG))
+             || (! mips_opts.mips16
+                 && (prev_pinfo2 & INSN2_WRITE_GPR_Z)
+                 && insn_uses_reg (ip, EXTRACT_OPERAND (RZ, history[0]),
+                                   MIPS_GR_REG))
              || (mips_opts.mips16
                  && (((prev_pinfo & MIPS16_INSN_WRITE_X)
                       && (insn_uses_reg
@@ -8479,6 +8500,11 @@ validate_mips_insn (const struct mips_opcode *opc)
          case 'Q': USE_BITS (OP_MASK_SEQI,     OP_SH_SEQI);    break;
          case 's': USE_BITS (OP_MASK_CINSLM1,  OP_SH_CINSLM1); break;
          case 'S': USE_BITS (OP_MASK_CINSLM1,  OP_SH_CINSLM1); break;
+         case 'z': USE_BITS (OP_MASK_RZ,       OP_SH_RZ);      break;
+         case 'Z': USE_BITS (OP_MASK_FZ,       OP_SH_FZ);      break;
+         case 'a': USE_BITS (OP_MASK_OFFSET_A, OP_SH_OFFSET_A); break;
+         case 'b': USE_BITS (OP_MASK_OFFSET_B, OP_SH_OFFSET_B); break;
+         case 'c': USE_BITS (OP_MASK_OFFSET_C, OP_SH_OFFSET_C); break;
 
          default:
            as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
@@ -9290,6 +9316,77 @@ mips_ip (char *str, struct mips_cl_insn *ip)
                  s = expr_end;
                  continue;
 
+               case 'a': /* 8-bit signed offset in bit 6 */
+                 my_getExpression (&imm_expr, s);
+                 check_absolute_expr (ip, &imm_expr);
+                 min_range = -((OP_MASK_OFFSET_A + 1) >> 1);
+                 max_range = ((OP_MASK_OFFSET_A + 1) >> 1) - 1;
+                 if (imm_expr.X_add_number < min_range
+                     || imm_expr.X_add_number > max_range)
+                   {
+                     as_bad (_("immediate not in range %ld..%ld (%ld)"),
+                             (long) min_range, (long) max_range,
+                             (long) imm_expr.X_add_number);
+                   }
+                 INSERT_OPERAND (OFFSET_A, *ip, imm_expr.X_add_number);
+                 imm_expr.X_op = O_absent;
+                 s = expr_end;
+                 continue;
+
+               case 'b': /* 8-bit signed offset in bit 3 */
+                 my_getExpression (&imm_expr, s);
+                 check_absolute_expr (ip, &imm_expr);
+                 min_range = -((OP_MASK_OFFSET_B + 1) >> 1);
+                 max_range = ((OP_MASK_OFFSET_B + 1) >> 1) - 1;
+                 if (imm_expr.X_add_number < min_range
+                     || imm_expr.X_add_number > max_range)
+                   {
+                     as_bad (_("immediate not in range %ld..%ld (%ld)"),
+                             (long) min_range, (long) max_range,
+                             (long) imm_expr.X_add_number);
+                   }
+                 INSERT_OPERAND (OFFSET_B, *ip, imm_expr.X_add_number);
+                 imm_expr.X_op = O_absent;
+                 s = expr_end;
+                 continue;
+
+               case 'c': /* 9-bit signed offset in bit 6 */
+                 my_getExpression (&imm_expr, s);
+                 check_absolute_expr (ip, &imm_expr);
+                 min_range = -((OP_MASK_OFFSET_C + 1) >> 1);
+                 max_range = ((OP_MASK_OFFSET_C + 1) >> 1) - 1;
+                 if (imm_expr.X_add_number < min_range
+                     || imm_expr.X_add_number > max_range)
+                   {
+                     as_bad (_("immediate not in range %ld..%ld (%ld)"),
+                             (long) min_range, (long) max_range,
+                             (long) imm_expr.X_add_number);
+                   }
+                 INSERT_OPERAND (OFFSET_C, *ip, imm_expr.X_add_number);
+                 imm_expr.X_op = O_absent;
+                 s = expr_end;
+                 continue;
+
+               case 'z':
+                 if (!reg_lookup (&s, RTYPE_NUM | RTYPE_GP, &regno))
+                   break;
+                 if (regno == AT && mips_opts.at)
+                   {
+                     if (mips_opts.at == ATREG)
+                       as_warn (_("used $at without \".set noat\""));
+                     else
+                       as_warn (_("used $%u with \".set at=$%u\""),
+                                regno, mips_opts.at);
+                   }
+                 INSERT_OPERAND (RZ, *ip, regno);
+                 continue;
+
+               case 'Z':
+                 if (!reg_lookup (&s, RTYPE_FPU, &regno))
+                   break;
+                 INSERT_OPERAND (FZ, *ip, regno);
+                 continue;
+
                default:
                  as_bad (_("Internal error: bad mips opcode "
                            "(unknown extension operand type `+%c'): %s %s"),
index 8592bf0..0cf93d6 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-18  Mingjie Xing  <mingjie.xing@gmail.com>
+
+       * gas/mips/loongson-3a-2.s, gas/mips/loongson-3a-2.d,
+       gas/mips/loongson-3a-3.s, gas/mips/loongson-3a-3.d: New tests.
+       * gas/mips/mips.exp: Run them.
+
 2010-12-12  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gas/elf/elf.exp: Run section9.
diff --git a/gas/testsuite/gas/mips/loongson-3a-2.d b/gas/testsuite/gas/mips/loongson-3a-2.d
new file mode 100644 (file)
index 0000000..4029a60
--- /dev/null
@@ -0,0 +1,65 @@
+#as: -march=loongson3a -mabi=o64
+#objdump: -M reg-names=numeric -dr
+#name: Loongson-3A tests
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+[0-9a-f]+ <.text>:
+.*:    70601075        campi   \$2,\$3
+.*:    70a02035        campv   \$4,\$5
+.*:    70e830b5        camwi   \$6,\$7,\$8
+.*:    714048f5        ramri   \$9,\$10
+.*:    716c0026        gsle    \$11,\$12
+.*:    71ae0027        gsgt    \$13,\$14
+.*:    c8622010        gslble  \$2,\$3,\$4
+.*:    c8c53811        gslbgt  \$5,\$6,\$7
+.*:    c9285012        gslhle  \$8,\$9,\$10
+.*:    c98b6813        gslhgt  \$11,\$12,\$13
+.*:    c9ee8014        gslwle  \$14,\$15,\$16
+.*:    ca519815        gslwgt  \$17,\$18,\$19
+.*:    cab4b016        gsldle  \$20,\$21,\$22
+.*:    cb17c817        gsldgt  \$23,\$24,\$25
+.*:    e8622010        gssble  \$2,\$3,\$4
+.*:    e8c53811        gssbgt  \$5,\$6,\$7
+.*:    e9285012        gsshle  \$8,\$9,\$10
+.*:    e98b6813        gsshgt  \$11,\$12,\$13
+.*:    e9ee8014        gsswle  \$14,\$15,\$16
+.*:    ea519815        gsswgt  \$17,\$18,\$19
+.*:    eab4b016        gssdle  \$20,\$21,\$22
+.*:    eb17c817        gssdgt  \$23,\$24,\$25
+.*:    c8401818        gslwlec1        \$f0,\$2,\$3
+.*:    c8812819        gslwgtc1        \$f1,\$4,\$5
+.*:    c8c2381a        gsldlec1        \$f2,\$6,\$7
+.*:    c903481b        gsldgtc1        \$f3,\$8,\$9
+.*:    e944581c        gsswlec1        \$f4,\$10,\$11
+.*:    e985681d        gsswgtc1        \$f5,\$12,\$13
+.*:    e9c6781e        gssdlec1        \$f6,\$14,\$15
+.*:    ea07881f        gssdgtc1        \$f7,\$16,\$17
+.*:    ca480004        gslwlc1 \$f8,0\(\$18\)
+.*:    ca690045        gslwrc1 \$f9,1\(\$19\)
+.*:    ca8a0086        gsldlc1 \$f10,2\(\$20\)
+.*:    caab00c7        gsldrc1 \$f11,3\(\$21\)
+.*:    eacc0104        gsswlc1 \$f12,4\(\$22\)
+.*:    eaed0145        gsswrc1 \$f13,5\(\$23\)
+.*:    eb0e0186        gssdlc1 \$f14,6\(\$24\)
+.*:    eb2f01c7        gssdrc1 \$f15,7\(\$25\)
+.*:    d8622000        gslbx   \$2,0\(\$3,\$4\)
+.*:    d8c53ff9        gslhx   \$5,-1\(\$6,\$7\)
+.*:    d92857f2        gslwx   \$8,-2\(\$9,\$10\)
+.*:    d98b6feb        gsldx   \$11,-3\(\$12,\$13\)
+.*:    f9ee87e0        gssbx   \$14,-4\(\$15,\$16\)
+.*:    fa519fd9        gsshx   \$17,-5\(\$18,\$19\)
+.*:    fab4b7d2        gsswx   \$20,-6\(\$21,\$22\)
+.*:    fb17cfcb        gssdx   \$23,-7\(\$24,\$25\)
+.*:    d8501bfe        gslwxc1 \$f16,127\(\$2,\$3\)
+.*:    d8912c07        gsldxc1 \$f17,-128\(\$4,\$5\)
+.*:    f8d23bfe        gsswxc1 \$f18,127\(\$6,\$7\)
+.*:    f9134c07        gssdxc1 \$f19,-128\(\$8,\$9\)
+.*:    c98b3fea        gslq    \$10,\$11,255\(\$12\)
+.*:    e9ee402d        gssq    \$13,\$14,-256\(\$15\)
+.*:    ca15bff4        gslqc1  \$f20,\$f21,255\(\$16\)
+.*:    ea37c036        gssqc1  \$f22,\$f23,-256\(\$17\)
+#pass
+
diff --git a/gas/testsuite/gas/mips/loongson-3a-2.s b/gas/testsuite/gas/mips/loongson-3a-2.s
new file mode 100644 (file)
index 0000000..16a38c9
--- /dev/null
@@ -0,0 +1,65 @@
+       .text\r
+       .set noreorder\r
+\r
+       campi           $2,$3\r
+       campv           $4,$5\r
+       camwi           $6,$7,$8\r
+       ramri           $9,$10\r
+\r
+       gsle            $11,$12\r
+       gsgt            $13,$14\r
+\r
+       gslble          $2,$3,$4\r
+       gslbgt          $5,$6,$7\r
+       gslhle          $8,$9,$10\r
+       gslhgt          $11,$12,$13\r
+       gslwle          $14,$15,$16\r
+       gslwgt          $17,$18,$19\r
+       gsldle          $20,$21,$22\r
+       gsldgt          $23,$24,$25\r
+       gssble          $2,$3,$4\r
+       gssbgt          $5,$6,$7\r
+       gsshle          $8,$9,$10\r
+       gsshgt          $11,$12,$13\r
+       gsswle          $14,$15,$16\r
+       gsswgt          $17,$18,$19\r
+       gssdle          $20,$21,$22\r
+       gssdgt          $23,$24,$25\r
+\r
+       gslwlec1        $f0,$2,$3        \r
+       gslwgtc1        $f1,$4,$5  \r
+       gsldlec1        $f2,$6,$7  \r
+       gsldgtc1        $f3,$8,$9  \r
+       gsswlec1        $f4,$10,$11  \r
+       gsswgtc1        $f5,$12,$13\r
+       gssdlec1        $f6,$14,$15\r
+       gssdgtc1        $f7,$16,$17\r
+\r
+       gslwlc1         $f8,0($18)\r
+       gslwrc1         $f9,1($19) \r
+       gsldlc1         $f10,2($20) \r
+       gsldrc1         $f11,3($21)\r
+       gsswlc1         $f12,4($22)\r
+       gsswrc1         $f13,5($23)\r
+       gssdlc1         $f14,6($24)\r
+       gssdrc1         $f15,7($25)\r
+\r
+       gslbx           $2,0($3,$4)\r
+       gslhx           $5,-1($6,$7)\r
+       gslwx           $8,-2($9,$10)\r
+       gsldx           $11,-3($12,$13)\r
+       gssbx           $14,-4($15,$16)\r
+       gsshx           $17,-5($18,$19)\r
+       gsswx           $20,-6($21,$22)\r
+       gssdx           $23,-7($24,$25)\r
+\r
+       gslwxc1         $f16,127($2,$3)\r
+       gsldxc1         $f17,-128($4,$5)\r
+       gsswxc1         $f18,127($6,$7)\r
+       gssdxc1         $f19,-128($8,$9)\r
+\r
+       gslq            $10,$11,255($12) \r
+       gssq            $13,$14,-256($15)\r
+       gslqc1          $f20,$f21,255($16)\r
+       gssqc1          $f22,$f23,-256($17)\r
+\r
diff --git a/gas/testsuite/gas/mips/loongson-3a-3.d b/gas/testsuite/gas/mips/loongson-3a-3.d
new file mode 100644 (file)
index 0000000..e242c5d
--- /dev/null
@@ -0,0 +1,13 @@
+#as: -march=loongson3a -mabi=o64
+#objdump: -M reg-names=numeric -dr
+#name: Loongson delay slot tests
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+[0-9a-f]+ <.text>:
+.*:    c8c50024        gslq    \$4,\$5,0\(\$6\)
+.*:    10800002        beqz    \$4,0x10
+.*:    00000000        nop
+#pass
diff --git a/gas/testsuite/gas/mips/loongson-3a-3.s b/gas/testsuite/gas/mips/loongson-3a-3.s
new file mode 100644 (file)
index 0000000..24f427b
--- /dev/null
@@ -0,0 +1,4 @@
+       gslq $4,$5,0($6)
+       beq  $4,$0,1f
+       nop
+1:
index baea397..056dd75 100644 (file)
@@ -916,6 +916,8 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "loongson-2f-3"
 
     run_dump_test "loongson-3a"
+    run_dump_test "loongson-3a-2"
+    run_dump_test "loongson-3a-3"
 
     run_dump_test_arches "octeon"      [mips_arch_list_matching octeon]
     run_list_test_arches "octeon-ill" "" \
index 85ae8ab..f68805f 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-18  Mingjie Xing  <mingjie.xing@gmail.com>
+
+       * mips.h (OP_*_OFFSET_A, OP_*_OFFSET_B, OP_*_OFFSET_C)
+       (OP_*_RZ, OP_*_FZ, INSN2_M_FP_D, INSN2_WRITE_GPR_Z, INSN2_WRITE_FPR_Z)
+       (INSN2_READ_GPR_Z, INSN2_READ_FPR_Z, INSN2_READ_GPR_D): Define.
+
 2010-11-23  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * mips.h: Fix previous commit.
index f707d46..f6656a6 100644 (file)
 #define OP_SH_SEQI             6
 #define OP_MASK_SEQI           0x3ff
 
+/* Loongson */
+#define OP_SH_OFFSET_A         6
+#define OP_MASK_OFFSET_A       0xff
+#define OP_SH_OFFSET_B         3
+#define OP_MASK_OFFSET_B       0xff
+#define OP_SH_OFFSET_C         6
+#define OP_MASK_OFFSET_C       0x1ff
+#define OP_SH_RZ               0
+#define OP_MASK_RZ             0x1f
+#define OP_SH_FZ               0
+#define OP_MASK_FZ             0x1f
+
 /* This structure holds information for a particular instruction.  */
 
 struct mips_opcode
@@ -503,6 +515,17 @@ struct mips_opcode
    only be set for macros.  For instructions, FP_D in pinfo carries the
    same information.  */
 #define INSN2_M_FP_D               0x00000010
+/* Modifies the general purpose register in OP_*_RZ.  */
+#define INSN2_WRITE_GPR_Z          0x00000020
+/* Modifies the floating point register in OP_*_FZ.  */
+#define INSN2_WRITE_FPR_Z          0x00000040
+/* Reads the general purpose register in OP_*_RZ.  */
+#define INSN2_READ_GPR_Z           0x00000080
+/* Reads the floating point register in OP_*_FZ.  */
+#define INSN2_READ_FPR_Z           0x00000100
+/* Reads the general purpose register in OP_*_RD.  */
+#define INSN2_READ_GPR_D           0x00000200
+
 
 /* Masks used to mark instructions to indicate which MIPS ISA level
    they were introduced in.  INSN_ISA_MASK masks an enumeration that
index bef474e..b18b6b9 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-18  Mingjie Xing  <mingjie.xing@gmail.com>
+
+       * mips-opc.c (WR_z, WR_Z, RD_z, RD_Z, RD_d): Define.
+       (mips_builtin_opcodes): Add loongson3a specific instructions.
+       * mips-dis.c (print_insn_args): Handle the new arguments +a|b|c|z|Z.
+
 2010-12-11 Mingming Sun <mingm.sun@gmail.com>
 
        * mips-opc.c: (mips_builtin_opcodes): Add loongson3a mul/div and
index a528e96..ca65d71 100644 (file)
@@ -973,6 +973,37 @@ print_insn_args (const char *d,
              (*info->fprintf_func) (info->stream, "%d", op);
              break;
 
+           case 'a':           /* 8-bit signed offset in bit 6 */
+             delta = (l >> OP_SH_OFFSET_A) & OP_MASK_OFFSET_A;
+             if (delta & 0x80)
+               delta |= ~OP_MASK_OFFSET_A;
+             (*info->fprintf_func) (info->stream, "%d", delta);
+             break;
+
+           case 'b':           /* 8-bit signed offset in bit 3 */
+             delta = (l >> OP_SH_OFFSET_B) & OP_MASK_OFFSET_B;
+             if (delta & 0x80)
+               delta |= ~OP_MASK_OFFSET_B;
+             (*info->fprintf_func) (info->stream, "%d", delta);
+             break;
+
+           case 'c':           /* 9-bit signed offset in bit 6 */
+             delta = (l >> OP_SH_OFFSET_C) & OP_MASK_OFFSET_C;
+             if (delta & 0x100)
+               delta |= ~OP_MASK_OFFSET_C;
+             (*info->fprintf_func) (info->stream, "%d", delta);
+             break;
+
+           case 'z':
+             (*info->fprintf_func) (info->stream, "%s",
+                                    mips_gpr_names[(l >> OP_SH_RZ) & OP_MASK_RZ]);
+             break;
+
+           case 'Z':
+             (*info->fprintf_func) (info->stream, "%s",
+                                    mips_fpr_names[(l >> OP_SH_FZ) & OP_MASK_FZ]);
+             break;
+
            default:
              /* xgettext:c-format */
              (*info->fprintf_func) (info->stream,
index e22c20c..fc25e07 100644 (file)
 /* MIPS MT ASE support.  */
 #define MT32   INSN_MT
 
+/* Loongson support.  */
+#define WR_z   INSN2_WRITE_GPR_Z
+#define WR_Z   INSN2_WRITE_FPR_Z
+#define RD_z   INSN2_READ_GPR_Z
+#define RD_Z   INSN2_READ_FPR_Z
+#define RD_d   INSN2_READ_GPR_D
+
 /* 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
@@ -199,6 +206,64 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"b",       "p",       0x04010000, 0xffff0000, UBD,                    INSN2_ALIAS,    I1      },/* bgez 0 */
 {"bal",     "p",       0x04110000, 0xffff0000, UBD|WR_31,              INSN2_ALIAS,    I1      },/* bgezal 0*/
 
+/* Loongson specific instructions.  Loongson 3A redefines the Coprocessor 2
+   instructions.  Put them here so that disassembler will find them first.
+   The assemblers uses a hash table based on the instruction name anyhow.  */
+{"campi",      "d,s",          0x70000075,     0xfc1f07ff,     WR_d|RD_s,      0,      IL3A    },
+{"campv",      "d,s",          0x70000035,     0xfc1f07ff,     WR_d|RD_s,      0,      IL3A    },
+{"camwi",      "d,s,t",        0x700000b5,     0xfc0007ff,     RD_s|RD_t,      RD_d,   IL3A    },
+{"ramri",      "d,s",          0x700000f5,     0xfc1f07ff,     WR_d|RD_s,      0,      IL3A    },
+{"gsle",       "s,t",          0x70000026,     0xfc00ffff,     RD_s|RD_t,      0,      IL3A    },
+{"gsgt",       "s,t",          0x70000027,     0xfc00ffff,     RD_s|RD_t,      0,      IL3A    },
+{"gslble",     "t,b,d",        0xc8000010,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gslbgt",     "t,b,d",        0xc8000011,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gslhle",     "t,b,d",        0xc8000012,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gslhgt",     "t,b,d",        0xc8000013,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gslwle",     "t,b,d",        0xc8000014,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gslwgt",     "t,b,d",        0xc8000015,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gsldle",     "t,b,d",        0xc8000016,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gsldgt",     "t,b,d",        0xc8000017,     0xfc0007ff,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gssble",     "t,b,d",        0xe8000010,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gssbgt",     "t,b,d",        0xe8000011,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gsshle",     "t,b,d",        0xe8000012,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gsshgt",     "t,b,d",        0xe8000013,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gsswle",     "t,b,d",        0xe8000014,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gsswgt",     "t,b,d",        0xe8000015,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gssdle",     "t,b,d",        0xe8000016,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gssdgt",     "t,b,d",        0xe8000017,     0xfc0007ff,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gslwlec1",   "T,b,d",        0xc8000018,     0xfc0007ff,     WR_T|RD_b|LDD,  RD_d,   IL3A    },
+{"gslwgtc1",   "T,b,d",        0xc8000019,     0xfc0007ff,     WR_T|RD_b|LDD,  RD_d,   IL3A    },
+{"gsldlec1",   "T,b,d",        0xc800001a,     0xfc0007ff,     WR_T|RD_b|LDD,  RD_d,   IL3A    },
+{"gsldgtc1",   "T,b,d",        0xc800001b,     0xfc0007ff,     WR_T|RD_b|LDD,  RD_d,   IL3A    },
+{"gsswlec1",   "T,b,d",        0xe800001c,     0xfc0007ff,     RD_T|RD_b|SM,   RD_d,   IL3A    },
+{"gsswgtc1",   "T,b,d",        0xe800001d,     0xfc0007ff,     RD_T|RD_b|SM,   RD_d,   IL3A    },
+{"gssdlec1",   "T,b,d",        0xe800001e,     0xfc0007ff,     RD_T|RD_b|SM,   RD_d,   IL3A    },
+{"gssdgtc1",   "T,b,d",        0xe800001f,     0xfc0007ff,     RD_T|RD_b|SM,   RD_d,   IL3A    },
+{"gslwlc1",    "T,+a(b)",      0xc8000004,     0xfc00c03f,     WR_T|RD_b|LDD,  0,      IL3A    },
+{"gslwrc1",    "T,+a(b)",      0xc8000005,     0xfc00c03f,     WR_T|RD_b|LDD,  0,      IL3A    },
+{"gsldlc1",    "T,+a(b)",      0xc8000006,     0xfc00c03f,     WR_T|RD_b|LDD,  0,      IL3A    },
+{"gsldrc1",    "T,+a(b)",      0xc8000007,     0xfc00c03f,     WR_T|RD_b|LDD,  0,      IL3A    },
+{"gsswlc1",    "T,+a(b)",      0xe8000004,     0xfc00c03f,     RD_T|RD_b|SM,   0,      IL3A    },
+{"gsswrc1",    "T,+a(b)",      0xe8000005,     0xfc00c03f,     RD_T|RD_b|SM,   0,      IL3A    },
+{"gssdlc1",    "T,+a(b)",      0xe8000006,     0xfc00c03f,     RD_T|RD_b|SM,   0,      IL3A    },
+{"gssdrc1",    "T,+a(b)",      0xe8000007,     0xfc00c03f,     RD_T|RD_b|SM,   0,      IL3A    },
+{"gslbx",      "t,+b(b,d)",    0xd8000000,     0xfc000007,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gslhx",      "t,+b(b,d)",    0xd8000001,     0xfc000007,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gslwx",      "t,+b(b,d)",    0xd8000002,     0xfc000007,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gsldx",      "t,+b(b,d)",    0xd8000003,     0xfc000007,     WR_t|RD_b|LDD,  RD_d,   IL3A    },
+{"gssbx",      "t,+b(b,d)",    0xf8000000,     0xfc000007,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gsshx",      "t,+b(b,d)",    0xf8000001,     0xfc000007,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gsswx",      "t,+b(b,d)",    0xf8000002,     0xfc000007,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gssdx",      "t,+b(b,d)",    0xf8000003,     0xfc000007,     RD_t|RD_b|SM,   RD_d,   IL3A    },
+{"gslwxc1",    "T,+b(b,d)",    0xd8000006,     0xfc000007,     WR_T|RD_b|LDD,  RD_d,   IL3A    },
+{"gsldxc1",    "T,+b(b,d)",    0xd8000007,     0xfc000007,     WR_T|RD_b|LDD,  RD_d,   IL3A    },
+{"gsswxc1",    "T,+b(b,d)",    0xf8000006,     0xfc000007,     RD_T|RD_b|SM,   RD_d,   IL3A    },
+{"gssdxc1",    "T,+b(b,d)",    0xf8000007,     0xfc000007,     RD_T|RD_b|SM,   RD_d,   IL3A    },
+{"gslq",       "+z,t,+c(b)",   0xc8000020,     0xfc008020,     WR_t|RD_b|LDD,  WR_z,   IL3A    },
+{"gssq",       "+z,t,+c(b)",   0xe8000020,     0xfc008020,     RD_t|RD_b|SM,   RD_z,   IL3A    },
+{"gslqc1",     "+Z,T,+c(b)",   0xc8008020,     0xfc008020,     WR_T|RD_b|LDD,  WR_Z,   IL3A    },
+{"gssqc1",     "+Z,T,+c(b)",   0xe8008020,     0xfc008020,     RD_T|RD_b|SM,   RD_Z,   IL3A    },
+
 {"abs",     "d,v",     0,    (int) M_ABS,      INSN_MACRO,             0,              I1      },
 {"abs.s",   "D,V",     0x46000005, 0xffff003f, WR_D|RD_S|FP_S,         0,              I1      },
 {"abs.d",   "D,V",     0x46200005, 0xffff003f, WR_D|RD_S|FP_D,         0,              I1      },