* hppa-dis.c (print_insn_hppa): Escape '%' in output strings.
[deliverable/binutils-gdb.git] / opcodes / hppa-dis.c
index 4a7fd06efb7f2349d610755aba6df6a90fd0c3d3..cde70fa3e39189891b62e9ad6be2c47179d4a733 100644 (file)
@@ -46,6 +46,7 @@ typedef unsigned int CORE_ADDR;
 /* Get at various relevent fields of an instruction word. */
 
 #define MASK_5 0x1f
+#define MASK_10 0x3ff
 #define MASK_11 0x7ff
 #define MASK_14 0x3fff
 #define MASK_21 0x1fffff
@@ -82,7 +83,7 @@ static const char add_cond_names[][5] = {
   ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
 };
 static const char add_cond_64_names[][6] = {
-  ",*", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
+  "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
   ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
 };
 static const char wide_add_cond_names[][5] = {
@@ -93,21 +94,21 @@ static const char *const logical_cond_names[] = {
   "", ",=", ",<", ",<=", 0, 0, 0, ",od",
   ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
 static const char *const logical_cond_64_names[] = {
-  ",*", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
+  "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
   ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
 static const char *const unit_cond_names[] = {
   "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
   ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
 };
 static const char *const unit_cond_64_names[] = {
-  ",*", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
+  "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
   ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
 };
 static const char shift_cond_names[][4] = {
   "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
 };
 static const char shift_cond_64_names[][5] = {
-  ",*", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
+  "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
 };
 static const char bb_cond_64_names[][5] = {
   ",*<", ",*>="
@@ -127,8 +128,11 @@ static const char float_comp_names[][8] =
 };
 static const char *const signed_unsigned_names[][3] = {",u", ",s"};
 static const char *const mix_half_names[][3] = {",l", ",r"};
-static const char *const saturation_names[][3] = {",us", ",ss", 0, ""};
-
+static const char *const saturation_names[][4] = {",us", ",ss", 0, ""};
+static const char *const read_write_names[][3] = {",r", ",w"};
+static const char *const add_compl_names[] = {
+  0, "", ",l", ",tsv"
+};
 
 /* For a bunch of different instructions form an index into a 
    completer name table. */
@@ -235,6 +239,14 @@ extract_5R_store (word)
   return (word >> 16 & MASK_5);
 }
 
+/* extract the 10 bit immediate field from a {sr}sm instruction */
+static unsigned
+extract_10U_store (word)
+     unsigned word;
+{
+  return (word >> 16 & MASK_10);
+}
+
 /* extract the immediate field from a bb instruction */
 static unsigned
 extract_5Q_store (word)
@@ -344,12 +356,6 @@ print_insn_hppa (memaddr, info)
                case 'x':
                  fput_reg (GET_FIELD (insn, 11, 15), info);
                  break;
-               case 'X':
-                  if (GET_FIELD (insn, 25, 25))
-                     fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
-                 else
-                     fput_fp_reg (GET_FIELD (insn, 11, 15), info);
-                 break;
                case 'a':
                case 'b':
                  fput_reg (GET_FIELD (insn, 6, 10), info);
@@ -357,61 +363,100 @@ print_insn_hppa (memaddr, info)
                case '^':
                  fput_creg (GET_FIELD (insn, 6, 10), info);
                  break;
-               case 'E':
-                 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
-                 break;
                case 't':
                  fput_reg (GET_FIELD (insn, 27, 31), info);
                  break;
-               case 'v':
-                  if (GET_FIELD (insn, 25, 25))
-                     fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
-                 else
+
+               /* Handle floating point registers.  */
+               case 'f':
+                 switch (*++s)
+                   {
+                   case 't':
                      fput_fp_reg (GET_FIELD (insn, 27, 31), info);
-                 break;
-               case 'y':
-                 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
-                 break;
-               case '4':
-                 {
-                   int reg = GET_FIELD (insn, 6, 10);
+                     break;
+                   case 'T':
+                     if (GET_FIELD (insn, 25, 25))
+                       fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
+                     else
+                       fput_fp_reg (GET_FIELD (insn, 27, 31), info);
+                     break;
+                   case 'a':
+                     if (GET_FIELD (insn, 25, 25))
+                       fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
+                     else
+                       fput_fp_reg (GET_FIELD (insn, 6, 10), info);
+                     break;
+                   case 'A':
+                     if (GET_FIELD (insn, 24, 24))
+                       fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
+                     else
+                       fput_fp_reg (GET_FIELD (insn, 6, 10), info);
+                     
+                     break;
+                   case 'b':
+                     if (GET_FIELD (insn, 25, 25))
+                       fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
+                     else
+                       fput_fp_reg (GET_FIELD (insn, 11, 15), info);
+                     break;
+                   case 'B':
+                     if (GET_FIELD (insn, 19, 19))
+                       fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
+                     else
+                       fput_fp_reg (GET_FIELD (insn, 11, 15), info);
+                     break;
+                   case 'C':
+                     {
+                       int reg = GET_FIELD (insn, 21, 22);
+                       reg |= GET_FIELD (insn, 16, 18) << 2;
+                       if (GET_FIELD (insn, 23, 23) != 0)
+                         fput_fp_reg_r (reg, info);
+                       else
+                         fput_fp_reg (reg, info);
+                       break;
+                     }
+                   case 'i':
+                     {
+                       int reg = GET_FIELD (insn, 6, 10);
 
-                   reg |= (GET_FIELD (insn, 26, 26) << 4);
-                   fput_fp_reg (reg, info);
-                   break;
-                 }
-               case '6':
-                 {
-                   int reg = GET_FIELD (insn, 11, 15);
+                       reg |= (GET_FIELD (insn, 26, 26) << 4);
+                       fput_fp_reg (reg, info);
+                       break;
+                     }
+                   case 'j':
+                     {
+                       int reg = GET_FIELD (insn, 11, 15);
 
-                   reg |= (GET_FIELD (insn, 26, 26) << 4);
-                   fput_fp_reg (reg, info);
-                   break;
-                 }
-               case '7':
-                 {
-                   int reg = GET_FIELD (insn, 27, 31);
+                       reg |= (GET_FIELD (insn, 26, 26) << 4);
+                       fput_fp_reg (reg, info);
+                       break;
+                     }
+                   case 'k':
+                     {
+                       int reg = GET_FIELD (insn, 27, 31);
 
-                   reg |= (GET_FIELD (insn, 26, 26) << 4);
-                   fput_fp_reg (reg, info);
-                   break;
-                 }
-               case '8':
-                 {
-                   int reg = GET_FIELD (insn, 16, 20);
+                       reg |= (GET_FIELD (insn, 26, 26) << 4);
+                       fput_fp_reg (reg, info);
+                       break;
+                     }
+                   case 'l':
+                     {
+                       int reg = GET_FIELD (insn, 21, 25);
 
-                   reg |= (GET_FIELD (insn, 26, 26) << 4);
-                   fput_fp_reg (reg, info);
-                   break;
-                 }
-               case '9':
-                 {
-                   int reg = GET_FIELD (insn, 21, 25);
+                       reg |= (GET_FIELD (insn, 26, 26) << 4);
+                       fput_fp_reg (reg, info);
+                       break;
+                     }
+                   case 'm':
+                     {
+                       int reg = GET_FIELD (insn, 16, 20);
+
+                       reg |= (GET_FIELD (insn, 26, 26) << 4);
+                       fput_fp_reg (reg, info);
+                       break;
+                     }
+                   }
 
-                   reg |= (GET_FIELD (insn, 26, 26) << 4);
-                   fput_fp_reg (reg, info);
-                   break;
-                 }
                case '5':
                  fput_const (extract_5_load (insn), info);
                  break;
@@ -440,12 +485,72 @@ print_insn_hppa (memaddr, info)
                      (*info->fprintf_func) (info->stream, "%s ",
                                             short_bytes_compl_names[GET_COMPL (insn)]);
                      break;
+                   case 'L':
+                     (*info->fprintf_func) (info->stream, ",l");
+                     break;
+                   case 'w':
+                     (*info->fprintf_func) (info->stream, "%s ",
+                                            read_write_names[GET_FIELD (insn, 25, 25)]);
+                     break;
+                   case 'W':
+                     (*info->fprintf_func) (info->stream, ",w");
+                     break;
+                   case 'r':
+                     if (GET_FIELD (insn, 23, 26) == 5)
+                       (*info->fprintf_func) (info->stream, ",r");
+                     break;
                    case 'Z':
                      if (GET_FIELD (insn, 26, 26))
                        (*info->fprintf_func) (info->stream, ",m ");
                      else
                        (*info->fprintf_func) (info->stream, " ");
                      break;
+                   case 'i':
+                     if (GET_FIELD (insn, 25, 25))
+                       (*info->fprintf_func) (info->stream, ",i");
+                     break;
+                   case 'z':
+                     if (!GET_FIELD (insn, 21, 21))
+                       (*info->fprintf_func) (info->stream, ",z");
+                     break;
+                   case 'a':
+                     (*info->fprintf_func)
+                       (info->stream, "%s", add_compl_names[GET_FIELD
+                                                           (insn, 20, 21)]);
+                     break;
+                   case 'Y':
+                     (*info->fprintf_func)
+                       (info->stream, ",dc%s", add_compl_names[GET_FIELD
+                                                              (insn, 20, 21)]);
+                     break;
+                   case 'y':
+                     (*info->fprintf_func)
+                       (info->stream, ",c%s", add_compl_names[GET_FIELD
+                                                             (insn, 20, 21)]);
+                     break;
+                   case 'v':
+                     if (GET_FIELD (insn, 20, 20))
+                       (*info->fprintf_func) (info->stream, ",tsv");
+                     break;
+                   case 't':
+                     (*info->fprintf_func) (info->stream, ",tc");
+                     if (GET_FIELD (insn, 20, 20))
+                       (*info->fprintf_func) (info->stream, ",tsv");
+                     break;
+                   case 'B':
+                     (*info->fprintf_func) (info->stream, ",db");
+                     if (GET_FIELD (insn, 20, 20))
+                       (*info->fprintf_func) (info->stream, ",tsv");
+                     break;
+                   case 'b':
+                     (*info->fprintf_func) (info->stream, ",b");
+                     if (GET_FIELD (insn, 20, 20))
+                       (*info->fprintf_func) (info->stream, ",tsv");
+                     break;
+                   case 'T':
+                     if (GET_FIELD (insn, 25, 25))
+                       (*info->fprintf_func) (info->stream, ",tc");
+                     break;
                    case 'S':
                      /* EXTRD/W has a following condition.  */
                      if (*(s + 1) == '?')
@@ -493,8 +598,7 @@ print_insn_hppa (memaddr, info)
                           rather than by the 'f' bit (sigh): comb, comib,
                           addb, addib */
                      case 't':
-                       fputs_filtered (compare_cond_names[GET_FIELD (insn, 16,
-                                                                     18)],
+                       fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
                                        info);
                        break;
                      case 'T':
@@ -514,8 +618,7 @@ print_insn_hppa (memaddr, info)
                                        info);
                        break;
                      case 'n':
-                       fputs_filtered (compare_cond_names[GET_FIELD (insn, 16,
-                                                                     18)
+                       fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
                                        + GET_FIELD (insn, 4, 4) * 8], info);
                        break;
                      case '@':
@@ -540,24 +643,22 @@ print_insn_hppa (memaddr, info)
                        break;
                      case 'd':
                        (*info->fprintf_func) (info->stream, "%s",
-                                              add_cond_names[GET_FIELD (insn,
-                                                                        16,
-                                                                        18)]);
+                                              add_cond_names[GET_FIELD (insn, 16, 18)]);
                        break;
+
                      case 'D':
                        (*info->fprintf_func) (info->stream, "%s",
-                                              add_cond_names[GET_FIELD (insn,
-                                                                        16, 18)
-                                                             + 8]);
+                                              add_cond_names[GET_FIELD (insn, 16, 18)
+                                                            + 8]);
                        break;
                      case 'w':
-                       (*info->fprintf_func)
+                       (*info->fprintf_func) 
                          (info->stream, "%s",
                           wide_add_cond_names[GET_FIELD (insn, 16, 18)]);
                        break;
 
                      case 'W':
-                       (*info->fprintf_func)
+                       (*info->fprintf_func) 
                          (info->stream, "%s",
                           wide_add_cond_names[GET_FIELD (insn, 16, 18) + 8]);
                        break;
@@ -617,6 +718,9 @@ print_insn_hppa (memaddr, info)
                case 'R':
                  fput_const (extract_5R_store (insn), info);
                  break;
+               case 'U':
+                 fput_const (extract_10U_store (insn), info);
+                 break;
                case 'Q':
                  fput_const (extract_5Q_store (insn), info);
                  break;
@@ -659,12 +763,22 @@ print_insn_hppa (memaddr, info)
                     of address.  */
                  fput_const (extract_17 (insn), info);
                  break;
+
+               case 'Z':
+                 /* addil %r1 implicit output.  */
+                 (*info->fprintf_func) (info->stream, "%%r1");
+                 break;
+                 
                case '.':
                  (*info->fprintf_func) (info->stream, "%d",
                                    GET_FIELD (insn, 24, 25));
                  break;
+               case '*':
+                 (*info->fprintf_func) (info->stream, "%d",
+                                   GET_FIELD (insn, 22, 25));
+                 break;
                case '!':
-                 (*info->fprintf_func) (info->stream, "%sar");
+                 (*info->fprintf_func) (info->stream, "%%sar");
                  break;
                case 'p':
                  (*info->fprintf_func) (info->stream, "%d",
@@ -682,10 +796,34 @@ print_insn_hppa (memaddr, info)
                  (*info->fprintf_func) (info->stream, "%d",
                                    GET_FIELD (insn, 22, 26));
                  break;
+               case 'q':
+                 {
+                   int num;
+                   num = GET_FIELD (insn, 20, 20) << 5;
+                   num |= GET_FIELD (insn, 22, 26);
+                   (*info->fprintf_func) (info->stream, "%d", num);
+                   break;
+                 }
                case 'T':
                  (*info->fprintf_func) (info->stream, "%d",
                                    32 - GET_FIELD (insn, 27, 31));
                  break;
+               case '%':
+                 {
+                   int num;
+                   num = (GET_FIELD (insn, 23, 23) + 1) * 32;
+                   num -= GET_FIELD (insn, 27, 31);
+                   (*info->fprintf_func) (info->stream, "%d", num);
+                   break;
+                 }
+               case '|':
+                 {
+                   int num;
+                   num = (GET_FIELD (insn, 19, 19) + 1) * 32;
+                   num -= GET_FIELD (insn, 27, 31);
+                   (*info->fprintf_func) (info->stream, "%d", num);
+                   break;
+                 }
                case '$':
                  fput_const (GET_FIELD (insn, 20, 28), info);
                  break;
@@ -695,7 +833,7 @@ print_insn_hppa (memaddr, info)
                case 'D':
                  fput_const (GET_FIELD (insn, 6, 31), info);
                  break;
-               case 'f':
+               case 'v':
                  (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
                  break;
                case 'O':
@@ -705,17 +843,6 @@ print_insn_hppa (memaddr, info)
                case 'o':
                  fput_const (GET_FIELD (insn, 6, 20), info);
                  break;
-               case '3':
-                 {
-                   int reg = GET_FIELD (insn, 21, 22);
-                   reg |= GET_FIELD (insn, 16, 18) << 2;
-                   if (GET_FIELD (insn, 23, 23) != 0)
-                     fput_fp_reg_r (reg, info);
-                   else
-                     fput_fp_reg (reg, info);
-                   break;
-                 }
-
                case '2':
                  fput_const ((GET_FIELD (insn, 6, 22) << 5 |
                               GET_FIELD (insn, 27, 31)), info);
@@ -766,19 +893,6 @@ print_insn_hppa (memaddr, info)
                                           float_format_names[GET_FIELD
                                                              (insn, 20, 20)]);
                  break;
-               case 'J':
-                  if (GET_FIELD (insn, 24, 24))
-                     fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
-                 else
-                     fput_fp_reg (GET_FIELD (insn, 6, 10), info);
-                     
-                 break;
-               case 'K':
-                  if (GET_FIELD (insn, 19, 19))
-                     fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
-                 else
-                     fput_fp_reg (GET_FIELD (insn, 11, 15), info);
-                 break;
                default:
                  (*info->fprintf_func) (info->stream, "%c", *s);
                  break;
This page took 0.029273 seconds and 4 git commands to generate.