For SH port, make relocation overflow an error instead of a warning.
authorJim Wilson <wilson@tuliptree.org>
Tue, 2 Jan 1996 20:45:49 +0000 (20:45 +0000)
committerJim Wilson <wilson@tuliptree.org>
Tue, 2 Jan 1996 20:45:49 +0000 (20:45 +0000)
gas/ChangeLog
gas/config/tc-sh.c

index 274a544d796284e487cc710ae9cc2563831a2472..ee321c41c4a8aaf836e7612511df8395252fc48b 100644 (file)
@@ -1,3 +1,8 @@
+Tue Jan  2 12:43:23 1996  Jim Wilson  <wilson@chestnut.cygnus.com>
+
+       * config/tc-sh.c (md_apply_fix): Call as_bad_where instead of
+       as_warn_where for relocation overflow.
+
 Sat Dec 30 23:42:51 1995  Jeffrey A Law  (law@cygnus.com)
 
        * ecoff.c (ecoff_stab): Simplify.  Correctly handle sym + offset
index caaf49bedc7b15dce5921bb40311862d09f97fef..27664237f833748c98f12b05aecd84a3eb5ea89c 100644 (file)
@@ -54,6 +54,7 @@ little (ignore)
      int ignore;
 {
   shl = 1;
+  target_big_endian = 0;
 }
 
 const pseudo_typeS md_pseudo_table[] =
@@ -167,6 +168,9 @@ md_begin ()
   sh_opcode_info *opcode;
   char *prev_name = "";
 
+  if (! shl)
+    target_big_endian = 1;
+
   opcode_hash_control = hash_new ();
 
   /* Insert unique names into hash table */
@@ -188,6 +192,8 @@ md_begin ()
 
 static int reg_m;
 static int reg_n;
+static int reg_b;
+
 static expressionS immediate;  /* absolute expression */
 
 typedef struct
@@ -205,6 +211,16 @@ parse_reg (src, mode, reg)
      int *mode;
      int *reg;
 {
+  if (src[0] == 'r') 
+    {
+      if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0)
+       {
+         *mode = A_REG_B;
+         *reg  = (src[1] - '0');
+         return 7;
+       }
+    }
+
   if (src[0] == 'r')
     {
       if (src[1] == '1')
@@ -224,6 +240,18 @@ parse_reg (src, mode, reg)
        }
     }
 
+  if (src[0] == 's' && src[1] == 's' && src[2] == 'r')
+    {
+      *mode = A_SSR;
+      return 3;
+    }
+
+  if (src[0] == 's' && src[1] == 'p' && src[2] == 'c')
+    {
+      *mode = A_SPC;
+      return 3;
+    }
+
   if (src[0] == 's' && src[1] == 'r')
     {
       *mode = A_SR;
@@ -534,16 +562,36 @@ get_operands (info, args, operand)
              ptr++;
            }
          get_operand (&ptr, operand + 1);
+/* start-sanitize-sh3e */
+         if (info->arg[2])
+           {
+             if (*ptr == ',')
+               {
+                 ptr++;
+               }
+             get_operand (&ptr, operand + 2);
+           }
+         else
+           {
+             operand[2].type = 0;
+           }
+/* end-sanitize-sh3e */
        }
       else
        {
          operand[1].type = 0;
+/* start-sanitize-sh3e */
+         operand[2].type = 0;
+/* end-sanitize-sh3e */
        }
     }
   else
     {
       operand[0].type = 0;
       operand[1].type = 0;
+/* start-sanitize-sh3e */
+      operand[2].type = 0;
+/* end-sanitize-sh3e */
     }
   return ptr;
 }
@@ -561,7 +609,6 @@ get_specific (opcode, operands)
 {
   sh_opcode_info *this_try = opcode;
   char *name = opcode->name;
-  int arg_to_test = 0;
   int n = 0;
   while (opcode->name)
     {
@@ -579,8 +626,8 @@ get_specific (opcode, operands)
 
       for (n = 0; this_try->arg[n]; n++)
        {
-         sh_operand_info *user = operands + arg_to_test;
-         sh_arg_type arg = this_try->arg[arg_to_test];
+         sh_operand_info *user = operands + n;
+         sh_arg_type arg = this_try->arg[n];
          switch (arg)
            {
            case A_IMM:
@@ -603,6 +650,12 @@ get_specific (opcode, operands)
              if (user->type != A_R0_GBR || user->reg != 0)
                goto fail;
              break;
+/* start-sanitize-sh3e */
+           case F_FR0:
+             if (user->type != F_REG_N || user->reg != 0)
+               goto fail;
+             break;
+/* end-sanitize-sh3e */
 
            case A_REG_N:
            case A_INC_N:
@@ -623,10 +676,18 @@ get_specific (opcode, operands)
            case A_GBR:
            case A_SR:
            case A_VBR:
+           case A_SSR:
+           case A_SPC:
              if (user->type != arg)
                goto fail;
              break;
 
+            case A_REG_B:
+             if (user->type != arg)
+               goto fail;
+             reg_b = user->reg;
+             break;
+
            case A_REG_M:
            case A_INC_M:
            case A_DEC_M:
@@ -654,8 +715,6 @@ get_specific (opcode, operands)
              printf ("unhandled %d\n", arg);
              goto fail;
            }
-         /* If we did 0, test 1 next, else 0 */
-         arg_to_test = 1 - arg_to_test;
        }
       return this_try;
     fail:;
@@ -698,7 +757,7 @@ static void
 build_relax (opcode)
      sh_opcode_info *opcode;
 {
-  int high_byte = shl ? 1 : 0 ;
+  int high_byte = target_big_endian ? 0 : 1;
   char *p;
 
   if (opcode->arg[0] == A_BDISP8)
@@ -737,7 +796,7 @@ build_Mytes (opcode, operand)
   int index;
   char nbuf[4];
   char *output = frag_more (2);
-  int low_byte = shl ? 0 : 1;
+  int low_byte = target_big_endian ? 1 : 0;
   nbuf[0] = 0;
   nbuf[1] = 0;
   nbuf[2] = 0;
@@ -760,6 +819,9 @@ build_Mytes (opcode, operand)
            case REG_M:
              nbuf[index] = reg_m;
              break;
+            case REG_B:
+             nbuf[index] = reg_b | 0x08;
+             break;
            case DISP_4:
              insert (output + low_byte, R_SH_IMM4, 0);
              break;
@@ -792,7 +854,7 @@ build_Mytes (opcode, operand)
            }
        }
     }
-  if (shl) {
+  if (! target_big_endian) {
     output[1] = (nbuf[0] << 4) | (nbuf[1]);
     output[0] = (nbuf[2] << 4) | (nbuf[3]);
   }
@@ -813,7 +875,7 @@ md_assemble (str)
 {
   unsigned char *op_start;
   unsigned char *op_end;
-  sh_operand_info operand[2];
+  sh_operand_info operand[3];
   sh_opcode_info *opcode;
   char name[20];
   int nlen = 0;
@@ -937,7 +999,7 @@ md_atof (type, litP, sizeP)
 
   *sizeP = prec * 2;
 
-  if (shl)
+  if (! target_big_endian)
     {
       for (i = prec - 1; i >= 0; i--)
        {
@@ -1009,6 +1071,7 @@ md_parse_option (c, arg)
       break;
     case OPTION_LITTLE:
       shl = 1;
+      target_big_endian = 0;
       break;
 
     default:
@@ -1260,8 +1323,8 @@ md_convert_frag (headers, seg, fragP)
       {
        unsigned char *buffer =
          (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
-       int highbyte = shl ? 1 : 0;
-       int lowbyte = shl ? 0 : 1;
+       int highbyte = target_big_endian ? 0 : 1;
+       int lowbyte = target_big_endian ? 1 : 0;
 
        /* Toggle the true/false bit of the bcond.  */
        buffer[highbyte] ^= 0x2;
@@ -1420,8 +1483,8 @@ md_apply_fix (fixP, val)
      long val;
 {
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
-  int lowbyte = shl ? 0 : 1;
-  int highbyte = shl ? 1 : 0;
+  int lowbyte = target_big_endian ? 1 : 0;
+  int highbyte = target_big_endian ? 0 : 1;
 
   if (fixP->fx_r_type == 0)
     {
@@ -1477,34 +1540,34 @@ md_apply_fix (fixP, val)
         variable val.  */
       val = (val + 2) / 4;
       if (val & ~0xff)
-       as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+       as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
       buf[lowbyte] = val;
       break;
 
     case R_SH_PCRELIMM8BY2:
       val /= 2;
       if (val & ~0xff)
-       as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+       as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
       buf[lowbyte] = val;
       break;
 
     case R_SH_PCDISP8BY2:
       val /= 2;
       if (val < -0x80 || val > 0x7f)
-       as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+       as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
       buf[lowbyte] = val;
       break;
 
     case R_SH_PCDISP:
       val /= 2;
       if (val < -0x800 || val >= 0x7ff)
-       as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+       as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
       buf[lowbyte] = val & 0xff;
       buf[highbyte] |= (val >> 8) & 0xf;
       break;
 
     case R_SH_IMM32:
-      if (shl
+      if (! target_big_endian
        {
          *buf++ = val >> 0;
          *buf++ = val >> 8;
@@ -1521,7 +1584,7 @@ md_apply_fix (fixP, val)
       break;
 
     case R_SH_IMM16:
-      if (shl) 
+      if (! target_big_endian)
        {
          *buf++ = val >> 0;
          *buf++ = val >> 8;
@@ -1619,7 +1682,7 @@ md_number_to_chars (ptr, use, nbytes)
      valueT use;
      int nbytes;
 {
-  if (shl)
+  if (! target_big_endian)
     number_to_chars_littleendian (ptr, use, nbytes);
   else
     number_to_chars_bigendian (ptr, use, nbytes);