Wed Jul 31 11:45:15 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
authorMartin Hunt <hunt@redhat.com>
Wed, 31 Jul 1996 18:50:12 +0000 (18:50 +0000)
committerMartin Hunt <hunt@redhat.com>
Wed, 31 Jul 1996 18:50:12 +0000 (18:50 +0000)
* tc-d10v.c: Fixed bugs in short relocs and range checking.

gas/config/tc-d10v.c

index 674bbd4..c8ee06c 100644 (file)
@@ -152,7 +152,7 @@ check_range (num, bits, flags)
      int bits;
      int flags;
 {
-  long min, max;
+  long min, max, bit1;
   int retval=0;
 
   if (flags & OPERAND_SHIFT)
@@ -167,7 +167,14 @@ check_range (num, bits, flags)
 
   if (flags & OPERAND_SIGNED)
     {
-      max = (1 << (bits - 1)) - 1; 
+      bit1 = (1 << (bits - 1)); 
+      max = bit1 -1;
+      if (num & max)
+       {
+         /* sign-extend */
+         num = ((num & (bit1 | max))^(~max))+bit1;
+       }
+
       min = - (1 << (bits - 1));  
       if (((long)num > max) || ((long)num < min))
        retval = 1;
@@ -553,7 +560,9 @@ write_1_short (opcode, insn, fx)
   number_to_chars_bigendian (f, insn, 4);
   for (i=0; i < fx->fc; i++) 
     {
-      if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc])) 
+      bfd_reloc_code_real_type reloc;
+      reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]);
+      if (reloc)
        { 
          /*
          printf("fix_new_exp: where:%x size:4\n    ",f - frag_now->fr_literal);
@@ -561,6 +570,10 @@ write_1_short (opcode, insn, fx)
          printf("\n");
          */
 
+         /* if it's an R reloc, we may have to switch it to L */
+         if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (opcode->unit != IU) )
+           fx->fix[i].reloc |= 1024;
+
          fix_new_exp (frag_now,
                       f - frag_now->fr_literal, 
                       4,
@@ -624,6 +637,7 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
            as_fatal ("Two IU instructions may not be executed in parallel");
          as_warn ("Swapping instruction order");
          insn = FM00 | (insn2 << 15) | insn1;
+         fx = fx->next;
        }
       else if (opcode2->unit == MU)
        {
@@ -631,6 +645,7 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
            as_fatal ("Two MU instructions may not be executed in parallel");
          as_warn ("Swapping instruction order");
          insn = FM00 | (insn2 << 15) | insn1;
+         fx = fx->next;
        }
       else
        insn = FM00 | (insn1 << 15) | insn2;