public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] Fix verilog output when the width is > 1.
@ 2022-12-01 13:10 Nick Clifton
  0 siblings, 0 replies; only message in thread
From: Nick Clifton @ 2022-12-01 13:10 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6ef35c04dffe685ece08212201c4c032baf8aa86

commit 6ef35c04dffe685ece08212201c4c032baf8aa86
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Dec 1 13:09:26 2022 +0000

    Fix verilog output when the width is > 1.
    
            PR 25202
    bfd     * bfd.c (VerilogDataEndianness): New variable.
            (verilog_write_record): Use VerilogDataEndianness, if set, to
            choose the endianness of the output.
            (verilog_write_section): Adjust the address by the data width.
    
    binutils* objcopy.c (copy_object): Set VerilogDataEndianness to the
            endianness of the input file.
            (copy_main): Verifiy the value set by the --verilog-data-width
            option.
            * testsuite/binutils-all/objcopy.exp: Add tests of the new behaviour.
            * testsuite/binutils-all/verilog-I4.hex: New file.

Diff:
---
 bfd/ChangeLog                                  |  8 ++++++
 bfd/verilog.c                                  | 23 +++++++++++++---
 binutils/ChangeLog                             | 10 +++++++
 binutils/objcopy.c                             | 25 +++++++++++++++--
 binutils/testsuite/binutils-all/objcopy.exp    | 38 ++++++++++++++++++++++++--
 binutils/testsuite/binutils-all/verilog-I4.hex |  6 ++++
 6 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 24aa783e1a7..eee5d42d6bb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2022-12-01  Nick Clifton  <nickc@redhat.com>
+
+	PR 25202
+	* bfd.c (VerilogDataEndianness): New variable.
+	(verilog_write_record): Use VerilogDataEndianness, if set, to
+	choose the endianness of the output.
+	(verilog_write_section): Adjust the address by the data width.
+
 2022-11-21  Nick Clifton  <nickc@redhat.com>
 
 	PR 29764
diff --git a/bfd/verilog.c b/bfd/verilog.c
index baf0e044c42..52c42c5fdd9 100644
--- a/bfd/verilog.c
+++ b/bfd/verilog.c
@@ -62,6 +62,10 @@
    Data width in bytes.  */
 unsigned int VerilogDataWidth = 1;
 
+/* Modified by obcopy.c
+   Data endianness.  */
+enum bfd_endian VerilogDataEndianness = BFD_ENDIAN_UNKNOWN;
+
 /* Macros for converting between hex and binary.  */
 
 static const char digs[] = "0123456789ABCDEF";
@@ -105,7 +109,7 @@ verilog_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach
   return true;
 }
 
-/* We have to save up all the outpu for a splurge before output.  */
+/* We have to save up all the output for a splurge before output.  */
 
 static bool
 verilog_set_section_contents (bfd *abfd,
@@ -238,7 +242,8 @@ verilog_write_record (bfd *abfd,
 	    *dst++ = ' ';
 	}
     }
-  else if (bfd_little_endian (abfd))
+  else if ((VerilogDataEndianness == BFD_ENDIAN_UNKNOWN && bfd_little_endian (abfd)) /* FIXME: Can this happen ?  */
+	   || (VerilogDataEndianness == BFD_ENDIAN_LITTLE))
     {
       /* If the input byte stream contains:
 	   05 04 03 02 01 00
@@ -263,8 +268,10 @@ verilog_write_record (bfd *abfd,
 	  TOHEX (dst, *end);
 	  dst += 2;
 	}
+
+      /* FIXME: Should padding bytes be inserted here ?  */
     }
-  else
+  else /* Big endian output.  */
     {
       for (src = data; src < end;)
 	{
@@ -274,6 +281,7 @@ verilog_write_record (bfd *abfd,
 	  if ((src - data) % VerilogDataWidth == 0)
 	    *dst++ = ' ';
 	}
+      /* FIXME: Should padding bytes be inserted here ?  */
     }
 
   *dst++ = '\r';
@@ -291,7 +299,14 @@ verilog_write_section (bfd *abfd,
   unsigned int octets_written = 0;
   bfd_byte *location = list->data;
 
-  verilog_write_address (abfd, list->where);
+  /* Insist that the starting address is a multiple of the data width.  */
+  if (list->where % VerilogDataWidth)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return false;
+    }
+
+  verilog_write_address (abfd, list->where / VerilogDataWidth);
   while (octets_written < list->size)
     {
       unsigned int octets_this_chunk = list->size - octets_written;
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index dfa5f1f22c8..6ec81ebd099 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,13 @@
+2022-12-01  Nick Clifton  <nickc@redhat.com>
+
+	PR 25202
+	* objcopy.c (copy_object): Set VerilogDataEndianness to the
+	endianness of the input file.
+	(copy_main): Verifiy the value set by the --verilog-data-width
+	option.
+	* testsuite/binutils-all/objcopy.exp: Add tests of the new behaviour.
+	* testsuite/binutils-all/verilog-I4.hex: New file.
+
 2022-11-21  Nick Clifton  <nickc@redhat.com>
 
 	PR 29764
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 3d886240ce1..6814e20a2fc 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -546,6 +546,11 @@ extern bool _bfd_srec_forceS3;
    the --verilog-data-width parameter.  */
 extern unsigned int VerilogDataWidth;
 
+/* Endianness of data for verilog output.
+   This variable is declared in bfd/verilog.c and is set in the
+   copy_object() function.  */
+extern enum bfd_endian VerilogDataEndianness;
+
 /* Forward declarations.  */
 static void setup_section (bfd *, asection *, void *);
 static void setup_bfd_headers (bfd *, bfd *);
@@ -2655,6 +2660,12 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
       return false;
     }
 
+  /* Set the Verilog output endianness based upon the input file's
+     endianness.  We may not be producing verilog format output,
+     but testing this just adds extra code this is not really
+     necessary.  */
+  VerilogDataEndianness = ibfd->xvec->byteorder;
+
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
     {
       if ((do_debug_sections & compress) != 0
@@ -5847,8 +5858,18 @@ copy_main (int argc, char *argv[])
 
 	case OPTION_VERILOG_DATA_WIDTH:
 	  VerilogDataWidth = parse_vma (optarg, "--verilog-data-width");
-	  if (VerilogDataWidth < 1)
-	    fatal (_("verilog data width must be at least 1 byte"));
+	  switch (VerilogDataWidth)
+	    {
+	    case 1:
+	    case 2:
+	    case 4:
+	    case 8:
+	    case 16: /* We do not support widths > 16 because the verilog
+			data is handled internally in 16 byte wide packets.  */
+	      break;
+	    default:
+	      fatal (_("error: verilog data width must be 1, 2, 4, 8 or 16"));
+	    }
 	  break;
 
 	case 0:
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index aebfdb2090b..de6f3aaaef2 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -155,13 +155,13 @@ proc objcopy_test_verilog {testname} {
     }
 
     set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width 0 $binfile $verilog-0.hex"]
-    if ![regexp "verilog data width must be at least 1 byte" $got] then {
+    if ![regexp "error: verilog data width must be 1, 2, 4, 8 or 16" $got] then {
 	fail "objcopy ($testname 0) {$got}"
     } else {
 	pass "objcopy ($testname 0)"
     }
 
-    foreach width {1 2 4 8} {
+    foreach width {1 2} {
 	set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $binfile $verilog-$width.hex"]
 	if ![string equal "" $got] then {
 	    fail "objcopy ($testname $width)"
@@ -173,6 +173,40 @@ proc objcopy_test_verilog {testname} {
 	    fail "objcopy ($testname $width)"
 	}
     }
+
+    # 16-bit little-endian targets fail the following tests because the
+    # verilog backend does not convert from 16-bits to 32-bits before it
+    # converts from internal format to little endian format.
+    if { [istarget tic54*-*-*] || [istarget pdp11-*-*] } {
+	untested "verilog width-4 and width-8 tests"
+	return
+    }
+    
+    foreach width {4 8} {
+	set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $binfile $verilog-$width.hex"]
+	if ![string equal "" $got] then {
+	    fail "objcopy ($testname $width)"
+	}
+        send_log "regexp_diff $verilog-$width.hex $srcdir/$subdir/verilog-$width.hex\n"
+	if {! [regexp_diff "$verilog-$width.hex" "$srcdir/$subdir/verilog-$width.hex"]} {
+	    pass "objcopy ($testname $width)"
+	} else {
+	    fail "objcopy ($testname $width)"
+	}
+    }
+
+    # Test generating endian correct output.    
+    set testname "objcopy (verilog output endian-ness == input endian-ness)"
+    set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width 4 $binfile $verilog-I4.hex"]
+    if ![string equal "" $got] then {
+	fail $testname
+    }
+    send_log "regexp_diff $verilog-I4.hex $srcdir/$subdir/verilog-I4.hex\n"
+    if {! [regexp_diff "$verilog-I4.hex" "$srcdir/$subdir/verilog-I4.hex"]} {
+	pass $testname 
+    } else {
+	fail $testname 
+    }
 }
 
 objcopy_test_verilog "verilog data width"
diff --git a/binutils/testsuite/binutils-all/verilog-I4.hex b/binutils/testsuite/binutils-all/verilog-I4.hex
new file mode 100644
index 00000000000..4fa1a5c9691
--- /dev/null
+++ b/binutils/testsuite/binutils-all/verilog-I4.hex
@@ -0,0 +1,6 @@
+@00000000
+(01020304|04030201) 00000000.*
+@000000..
+(02000000|00000002).*
+#pass
+

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-01 13:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-01 13:10 [binutils-gdb] Fix verilog output when the width is > 1 Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).