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 ca9b61dc2bfcf0d3bb75a83ab9b149431137b03d..50216fde1f525ab18bb20a801f49530b2802945e 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 65d198913b18adcf70fe0e205003ada9ebdf4f49..20bf431c027d321cfa15a83f7c61a26b914d9c9c 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 8592bf08e0e3137f845fc6f8033882f45e101785..0cf93d6ed8215232ff64d28987388da6d7efc66d 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 baea397eec20e3f2c0f1629fceedc9db56a05f8d..056dd75c0904611dea71d293f46960fe6c2b91b1 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 85ae8ab46c37f80f3878f68c6a17f805c8fd34e8..f68805fef31e04004a94076446814cab6fd7b83a 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 f707d4604d22612614af32666cd99b603cac07f7..f6656a6c5bdea21ec3249b37064fdc778ec51ee0 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 bef474ed14363459d46857a50e7813461c1279f1..b18b6b930464f05c65500a7fcfbda30807206927 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 a528e9650e7cab04e66116ecb66bccb94b0ebede..ca65d71f59960fbd9ce04cf4374f0610761c719c 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 e22c20c137b6576aa1563b3ffd9fd2e6581aff23..fc25e077c2a3f3b355c2d481fab58e7fd342a1ac 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      },