* frags.h (struct frag): Add has_code and insn_addr fields.
authorAlan Modra <amodra@gmail.com>
Fri, 2 Jul 2004 06:40:19 +0000 (06:40 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 2 Jul 2004 06:40:19 +0000 (06:40 +0000)
* write.c (cvt_frag_to_fill): Invoke md_frag_check.
* config/tc-ppc.c (md_assemble): Check and set insn_addr.
* config/tc-ppc.h (md_frag_check): Define.

gas/ChangeLog
gas/config/tc-ppc.c
gas/config/tc-ppc.h
gas/frags.h
gas/write.c

index 1c0e301..ab0551e 100644 (file)
@@ -1,3 +1,10 @@
+2004-07-02  Alan Modra  <amodra@bigpond.net.au>
+
+       * frags.h (struct frag): Add has_code and insn_addr fields.
+       * write.c (cvt_frag_to_fill): Invoke md_frag_check.
+       * config/tc-ppc.c (md_assemble): Check and set insn_addr.
+       * config/tc-ppc.h (md_frag_check): Define.
+
 2004-06-28  Maciej W. Rozycki  <macro@linux-mips.org>
 
        * doc/Makefile.am (info): Rename goal to...
index fe66d2b..d4893e7 100644 (file)
@@ -2091,6 +2091,7 @@ md_assemble (str)
   struct ppc_fixup fixups[MAX_INSN_FIXUPS];
   int fc;
   char *f;
+  int addr_mod;
   int i;
 #ifdef OBJ_ELF
   bfd_reloc_code_real_type reloc;
@@ -2618,6 +2619,11 @@ md_assemble (str)
 
   /* Write out the instruction.  */
   f = frag_more (4);
+  addr_mod = frag_now_fix () & 3;
+  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
+    as_bad (_("instruction address is not a multiple of 4"));
+  frag_now->insn_addr = addr_mod;
+  frag_now->has_code = 1;
   md_number_to_chars (f, insn, 4);
 
 #ifdef OBJ_ELF
index 0844f84..e08b12d 100644 (file)
@@ -1,6 +1,6 @@
 /* tc-ppc.h -- Header file for tc-ppc.c.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of GAS, the GNU Assembler.
@@ -110,6 +110,11 @@ extern char *ppc_target_format PARAMS ((void));
        }                                                               \
     }
 
+#define md_frag_check(FRAGP) \
+  if ((FRAGP)->has_code                                                        \
+      && (((FRAGP)->fr_address + (FRAGP)->insn_addr) & 3) != 0)                \
+    as_bad_where ((FRAGP)->fr_file, (FRAGP)->fr_line,                  \
+                 _("instruction address is not a multiple of 4"));
 \f
 #ifdef TE_PE
 
index 52a6cfe..a3bd522 100644 (file)
@@ -1,6 +1,6 @@
 /* frags.h - Header file for the frag concept.
-   Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+   2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -74,6 +74,11 @@ struct frag {
      fr_address has been adjusted.  */
   unsigned int relax_marker:1;
 
+  /* Used to ensure that all insns are emitted on proper address
+     boundaries.  */
+  unsigned int has_code:1;
+  unsigned int insn_addr:6;
+
   /* What state is my tail in? */
   relax_stateT fr_type;
   relax_substateT fr_subtype;
index 5acd607..509596f 100644 (file)
@@ -1,6 +1,6 @@
 /* write.c - emit .o file
    Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003
+   1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -616,6 +616,9 @@ cvt_frag_to_fill (object_headers *headersP, segT sec, fragS *fragP)
       BAD_CASE (fragP->fr_type);
       break;
     }
+#ifdef md_frag_check
+  md_frag_check (fragP);
+#endif
 }
 
 #endif /* defined (BFD_ASSEMBLER) || !defined (BFD)  */