This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch for avr port of binutils [adiw, sbiw, ldd with more functionality]


Sorry if you got this mail again, but I send that mail 20:44 local time to <binutils@sources.redhat.com> but got this message not back again???

So I tried it again.

If you got also the first message I think something is going wrong with my email system :-(


>Ian Lance Taylor schrieb:


Klaus Rudolph <lts-rudolph@gmx.de> writes:





What procedure in general is needed to provide some more work :-)



Submit the patches for approval, breaking them up into relevant chunks
so that they can be understood and approved by the maintainers.



Here is the patch for approval.



Additional functionality:


in older Versions from gas only constants are wroking in connection
with ldd, sbiw, adiw

now you also could write:

table1:
...
table2:
....

ldd r16, Y+(table2-table1)
adiw r16, (table2-table1)
sbiw r16, (table2-table1)

The patch is going only to avr related files.

Bye
   Klaus




diff -ur binutils-041119/bfd/bfd-in2.h binutils-041119_modified/bfd/bfd-in2.h
--- binutils-041119/bfd/bfd-in2.h	2004-11-08 14:17:32.000000000 +0100
+++ binutils-041119_modified/bfd/bfd-in2.h	2004-11-25 08:04:36.000000000 +0100
@@ -3158,6 +3158,18 @@
 into 22 bits.  */
   BFD_RELOC_AVR_CALL,
 
+/* This is a 16 bit reloc for the AVR that stores all needed bits
+  for absolute addressing with ldi with overflow check to linktime*/
+  BFD_RELOC_AVR_LDI,
+
+/* This is a 6 bit reloc for the AVR that stores offset for ldd/std
+  instructions*/
+  BFD_RELOC_AVR_6,
+
+/* This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw
+  instructions*/
+  BFD_RELOC_AVR_6_ADIW,
+
 /* Direct 12 bit.  */
   BFD_RELOC_390_12,
 
diff -ur binutils-041119/bfd/elf32-avr.c binutils-041119_modified/bfd/elf32-avr.c
--- binutils-041119/bfd/elf32-avr.c	2004-10-21 17:28:20.000000000 +0200
+++ binutils-041119_modified/bfd/elf32-avr.c	2004-11-25 08:08:55.000000000 +0100
@@ -329,7 +329,52 @@
 	 FALSE,			/* partial_inplace */
 	 0xffffffff,		/* src_mask */
 	 0xffffffff,		/* dst_mask */
-	 FALSE)			/* pcrel_offset */
+	 FALSE),			/* pcrel_offset */
+  /* A 16 bit absolute relocation of 16 bit address.
+     For LDI command.  */
+  HOWTO (R_AVR_LDI,		/* type */
+	 0,			/* rightshift */
+	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 16,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_AVR_LDI",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffff,		/* src_mask */
+	 0xffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+  /* A 6 bit absolute relocation of 6 bit offset.
+     For ldd/sdd command.  */
+  HOWTO (R_AVR_6,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 6,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_AVR_6",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffff,		/* src_mask */
+	 0xffff,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+  /* A 6 bit absolute relocation of 6 bit offset.
+     For sbiw/adiw command.  */
+  HOWTO (R_AVR_6_ADIW,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 6,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 "R_AVR_6_ADIW",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffff,		/* src_mask */
+	 0xffff,		/* dst_mask */
+	 FALSE)		/* pcrel_offset */
 };
 
 /* Map BFD reloc types to AVR ELF reloc types.  */
@@ -360,7 +405,10 @@
   { BFD_RELOC_AVR_LO8_LDI_PM_NEG,   R_AVR_LO8_LDI_PM_NEG },
   { BFD_RELOC_AVR_HI8_LDI_PM_NEG,   R_AVR_HI8_LDI_PM_NEG },
   { BFD_RELOC_AVR_HH8_LDI_PM_NEG,   R_AVR_HH8_LDI_PM_NEG },
-  { BFD_RELOC_AVR_CALL,             R_AVR_CALL }
+  { BFD_RELOC_AVR_CALL,             R_AVR_CALL },
+  { BFD_RELOC_AVR_LDI,              R_AVR_LDI  },
+  { BFD_RELOC_AVR_6,                R_AVR_6    },
+  { BFD_RELOC_AVR_6_ADIW,           R_AVR_6_ADIW }
 };
 
 static reloc_howto_type *
@@ -561,6 +609,39 @@
       bfd_put_16 (input_bfd, x, contents);
       break;
 
+    case R_AVR_LDI:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation + rel->r_addend;
+      if ((srel&0xffff)>255) { //remove offset for data/eeprom section
+          return bfd_reloc_overflow;
+      }
+      x = bfd_get_16 (input_bfd, contents);
+      x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+      bfd_put_16 (input_bfd, x, contents);
+      break;
+
+    case R_AVR_6:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation + rel->r_addend;
+      if (((srel&0xffff)>63 ) || (srel <0 )) { //remove offset for data/eeprom section
+          return bfd_reloc_overflow;
+      }
+      x = bfd_get_16 (input_bfd, contents);
+      x = (x & 0xd3f8) | (( srel  & 7) | (( srel  & (3 << 3)) << 7) | (( srel  & (1 << 5)) << 8) );
+      bfd_put_16 (input_bfd, x, contents);
+      break;
+
+    case R_AVR_6_ADIW:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation + rel->r_addend;
+      if (((srel&0xffff)>63 ) || (srel <0 )) { //remove offset for data/eeprom section
+          return bfd_reloc_overflow;
+      }
+      x = bfd_get_16 (input_bfd, contents);
+      x = (x & 0xff30) | (srel & 0xf) | ((srel & 0x30)<<2); 
+      bfd_put_16 (input_bfd, x, contents);
+      break;
+
     case R_AVR_HI8_LDI:
       contents += rel->r_offset;
       srel = (bfd_signed_vma) relocation + rel->r_addend;
diff -ur binutils-041119/gas/config/tc-avr.c binutils-041119_modified/gas/config/tc-avr.c
--- binutils-041119/gas/config/tc-avr.c	2004-09-11 15:15:04.000000000 +0200
+++ binutils-041119_modified/gas/config/tc-avr.c	2004-11-25 08:09:58.000000000 +0100
@@ -150,6 +150,7 @@
 static unsigned int avr_get_constant PARAMS ((char *, int));
 static char *parse_exp PARAMS ((char *, expressionS *));
 static bfd_reloc_code_real_type avr_ldi_expression PARAMS ((expressionS *));
+static void avr_offset_expression PARAMS ((expressionS *));
 
 #define EXP_MOD_NAME(i) exp_mod[i].name
 #define EXP_MOD_RELOC(i) exp_mod[i].reloc
@@ -442,6 +443,8 @@
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
 }
 
+
+
 /* Resolve STR as a constant expression and return the result.
    If result greater than MAX then error.  */
 
@@ -464,6 +467,10 @@
   return ex.X_add_number;
 }
 
+/* Resolve STR as a constant expression and return the result.
+   If result greater than MAX then error.  */
+
+
 /* Parse instruction operands.
    Return binary opcode.  */
 
@@ -592,7 +599,7 @@
 	}
       else
 	{
-	  op_mask = avr_get_constant (str, 31);
+	  op_mask = avr_get_constant (str, 31 );
 	  str = input_line_pointer;
 	}
 
@@ -689,12 +696,13 @@
 	  as_bad (_("pointer register (Y or Z) required"));
 	str = skip_space (str);
 	if (*str++ == '+')
-	  {
-	    unsigned int x;
-	    x = avr_get_constant (str, 63);
-	    str = input_line_pointer;
-	    op_mask |= (x & 7) | ((x & (3 << 3)) << 7) | ((x & (1 << 5)) << 8);
-	  }
+	    {
+	        input_line_pointer = str;
+	        avr_offset_expression (&op_expr);
+	        str = input_line_pointer;
+	        fix_new_exp (frag_now, where, 3,
+		    &op_expr, FALSE, BFD_RELOC_AVR_6);
+	    }
       }
       break;
 
@@ -746,11 +754,11 @@
 
     case 'K':
       {
-	unsigned int x;
-
-	x = avr_get_constant (str, 63);
-	str = input_line_pointer;
-	op_mask |= (x & 0xf) | ((x & 0x30) << 2);
+	  input_line_pointer = str;
+	  avr_offset_expression (&op_expr);
+	  str = input_line_pointer;
+	  fix_new_exp (frag_now, where, 3,
+	  &op_expr, FALSE, BFD_RELOC_AVR_6_ADIW);
       }
       break;
 
@@ -935,6 +943,27 @@
 	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
 	  break;
 
+	case BFD_RELOC_AVR_LDI:
+	  if (value > 255)
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("operand out of range: %ld"), value);
+	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
+	  break;
+
+    case BFD_RELOC_AVR_6:
+	  if ((value > 63) || (value<0) )
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("operand out of range: %ld"), value);
+      bfd_putl16 ((bfd_vma) insn | (( value  & 7) | (( value  & (3 << 3)) << 7) | (( value  & (1 << 5)) << 8) ), where);
+      break;
+
+    case BFD_RELOC_AVR_6_ADIW:
+	  if ((value > 63) || (value<0) )
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("operand out of range: %ld"), value);
+      bfd_putl16 ((bfd_vma) insn| (value & 0xf) | ((value & 0x30)<<2), where);
+      break;
+
 	case -BFD_RELOC_AVR_LO8_LDI:
 	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);
 	  break;
@@ -1129,6 +1158,33 @@
   return input_line_pointer;
 }
 
+/* Parse for ldd/std offset */
+
+static void
+avr_offset_expression (exp)
+     expressionS *exp;
+{
+  char *str = input_line_pointer;
+  char *tmp;
+  char op[8];
+  tmp = str;
+  str = extract_word (str, op, sizeof (op));
+
+  input_line_pointer = tmp;
+  expression (exp);
+
+  /* Warn about expressions that fail to use lo8 ().  */
+  if (exp->X_op == O_constant)
+    {
+        
+      int x = exp->X_add_number;
+      
+      if (x < -255 || x > 255)
+	as_warn (_("constant out of 8-bit range: %d"), x);
+    }
+
+}
+
 /* Parse special expressions (needed for LDI command):
    xx8 (address)
    xx8 (-address)
@@ -1145,7 +1201,6 @@
   char op[8];
   int mod;
   tmp = str;
-
   str = extract_word (str, op, sizeof (op));
 
   if (op[0])
@@ -1218,14 +1273,14 @@
   /* Warn about expressions that fail to use lo8 ().  */
   if (exp->X_op == O_constant)
     {
+        
       int x = exp->X_add_number;
+      
       if (x < -255 || x > 255)
 	as_warn (_("constant out of 8-bit range: %d"), x);
     }
-  else
-    as_warn (_("expression possibly out of 8-bit range"));
 
-  return BFD_RELOC_AVR_LO8_LDI;
+  return BFD_RELOC_AVR_LDI;
 }
 
 /* Flag to pass `pm' mode between `avr_parse_cons_expression' and
diff -ur binutils-041119/gas/doc/as.1 binutils-041119_modified/gas/doc/as.1
--- binutils-041119/gas/doc/as.1	2004-11-19 06:41:48.000000000 +0100
+++ binutils-041119_modified/gas/doc/as.1	2004-11-25 08:04:36.000000000 +0100
@@ -128,7 +128,7 @@
 .\" ========================================================================
 .\"
 .IX Title "AS 1"
-.TH AS 1 "2004-11-19" "binutils-041119" "GNU Development Tools"
+.TH AS 1 "2004-11-23" "binutils-041119" "GNU Development Tools"
 .SH "NAME"
 AS \- the portable GNU assembler.
 .SH "SYNOPSIS"
diff -ur binutils-041119/include/elf/avr.h binutils-041119_modified/include/elf/avr.h
--- binutils-041119/include/elf/avr.h	2001-03-14 03:27:44.000000000 +0100
+++ binutils-041119_modified/include/elf/avr.h	2004-11-25 08:04:36.000000000 +0100
@@ -53,6 +53,9 @@
      RELOC_NUMBER (R_AVR_HI8_LDI_PM_NEG,       16)
      RELOC_NUMBER (R_AVR_HH8_LDI_PM_NEG,       17)
      RELOC_NUMBER (R_AVR_CALL,		       18)
+     RELOC_NUMBER (R_AVR_LDI,              19)
+     RELOC_NUMBER (R_AVR_6,                20)
+     RELOC_NUMBER (R_AVR_6_ADIW,           21)
 END_RELOC_NUMBERS (R_AVR_max)
 
 #endif /* _ELF_AVR_H */
diff -ur binutils-041119/ld/ld.1 binutils-041119_modified/ld/ld.1
--- binutils-041119/ld/ld.1	2004-11-19 06:41:51.000000000 +0100
+++ binutils-041119_modified/ld/ld.1	2004-11-25 08:04:36.000000000 +0100
@@ -128,7 +128,7 @@
 .\" ========================================================================
 .\"
 .IX Title "LD 1"
-.TH LD 1 "2004-11-19" "binutils-041119" "GNU Development Tools"
+.TH LD 1 "2004-11-23" "binutils-041119" "GNU Development Tools"
 .SH "NAME"
 ld \- Using LD, the GNU linker
 .SH "SYNOPSIS"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]