Incompatability between APCS and ATPCS

Nick Clifton nickc@cygnus.com
Fri Mar 3 14:27:00 GMT 2000


Hi Richard,

[Background: The new ARM ABI, called ATPCS, is incompatible with the
old ABI in the area of functions that return small structures.  GCC
needs to support both ABIs and GDB needs to know which ABI is in use,
but there are no more flag bits available (for COFF at least) in the
file headers].

: For gcc we need to think a bit more carefully, and probably need to rework 
: all the machine specific flags (Groan, yet again).  Part of the problem is 
: that we are running out of bits in TARGET_FLAGS and that not all of the 
: options we support are truly orthogonal.  Maybe a better approach would be 
: something more akin to the way the ARM compiler does this.  Eg:
: 
: 	-mapcs=[/26|/32][/stack-check|/no-stack-check][/frame|/no-frame][fpreg|/no
: fpreg]
: 
: and 
: 
: -matpcs=(...)
: 
: But this needs more thought before we dive in.

Hmm, well I had already started on the implementation of a new command
line switch (-matpcs).  We do still have enough flags bits left over
to accomodate this new option, although I agree that at some point, it
would be nice to rework the switches properly.

I also received a suggestion from the gdb group here that we could
create a dummy debug section for ATPCS compliant binaries and GDB
could detect this and 'do the right thing' (tm) somehow.

So below is a patch that implements these features.  It also
implements another new command line switch -mbuggy-return-in-memory to
enable compatability with prior implementations which did not quite
this right.

This patch also covers the change to arm_return_in_memory() that Scott
originally submitted a few days ago which started me on all of this in
the first place. 

One thing that this patch does not do is implement the GDB side of
things, maybe somebody else would like to do that ?

What do you think - should we go with this patch ?

Cheers
	Nick


ChangeLog for gcc:
2000-03-03  Nick Clifton  <nickc@cygnus.com>

	* arm.h (SUBTARGET_EXTRA_ASM_SPEC): Define as empty if not
	defined.
	(ASM_SPEC): Define.
	(ARM_FLAG_ATPCS): Define.
	(ARM_FLAG_BUGGY_RETURN_IN_MEMORY): Define.
	(TARGET_ATPCS): Define.
	(TARGET_BUGGY_RETURN_IN_MEMORY): Define.
	(TARGET_SWITCHES): Add -matpcs, -mno-atpcs,
	-mbuggy-return-in-memory and -mno-buggy-return-in-memory
	options. 

	* arm.c (arm_override_options): If both -matpcs and
	-mbuggy-return-in-memory are specified, prefer the former.
	(arm_return_in_memory): If suppport ATPCS allow any structure
	<= 32 bits in size to be returned in a register.  Otherwise,
	if providing compatability with previous versions of gcc,
	disallow small structures containign floats or non
	integer-like aggregates.

	* thumb.h (SUBTARGET_EXTRA_ASM_SPEC): Define as empty if not
	already defined.
	(ASM_SPEC): Extend definition.
	(THUMB_FLAG_ATPCS): Define.
	(TARGET_ATPCS): Define.
	(TARGET_SWITCHES): Add -matpcs and -mno-atpcs options.

	* thumb.c (thumb_return_in_memory): If supporting ATPCS allow
	any structire <= 32 bits in size to be returned in a register.

	* semi.h (ASM_SPEC): Undefine.
	* elf.h (ASM_SPEC): Undefine.

	* linux-elf.h (SUBTARGET_EXTRA_ASM_SPEC): Fix definitions.
	(ASM_SPEC): Undefine.

	* unknown-elf-oabi.h (ASM_SPEC): Undefine.

	* invoke.texi (ARM Options): Document new command line
	switches -matpcs, -mno-atpcs, -mbuggy-return-in-memory and
	-mno-buggy-return-in-memory.
	(Thumb Options): Document new command line switches -matpcs,
	-mno-atpcs, -mbuggy-return-in-memory and
	-mno-buggy-return-in-memory. 


ChangeLog for gas:
2000-03-03  Nick Clifton  <nickc@cygnus.com>

	* tc-arm.c (atpcs): New static boolean.
	(md_begin): If 'atpcs' is true, create an empty debugging
	section called '.arm.atpcs'.
	(md_parse_option): Support -matpcs command line switch.
	(md_show_usage): Document -matpcs command line switch.

	* c-arm.texi (Options): Document new command line switch
	-matpcs. 

Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.h,v
retrieving revision 1.62
diff -p -r1.62 arm.h
*** arm.h	2000/02/29 01:42:52	1.62
--- arm.h	2000/03/03 21:30:20
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 250,255 ****
--- 250,271 ----
  #define SUBTARGET_CPP_SPEC      ""
  #endif
  
+ #ifndef SUBTARGET_EXTRA_ASM_SPEC
+ #define SUBTARGET_EXTRA_ASM_SPEC
+ #endif
+ 
+ #ifndef ASM_SPEC
+ #define ASM_SPEC "\
+ %{mbig-endian:-EB} \
+ %{mcpu=*:-m%*} \
+ %{march=*:-m%*} \
+ %{mapcs-*:-mapcs-%*} \
+ %{matpcs:-matpcs} \
+ %{mapcs-float:-mfloat} \
+ %{msoft-float:-mno-fpu} \
+ %{mthumb-interwork:-mthumb-interwork} \
+ " SUBTARGET_EXTRA_ASM_SPEC
+ #endif
  
  /* Run-time Target Specification.  */
  #ifndef TARGET_VERSION
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 321,326 ****
--- 337,351 ----
  /* Nonzero if all call instructions should be indirect.  */
  #define ARM_FLAG_LONG_CALLS	(1 << 15)
  
+ /* Set if ATPCS compliance is required.  Note there *are* some
+    incompatabilities between APCS and ATPCS.  */
+ #define ARM_FLAG_ATPCS		(1 << 16)
+ 
+ /* Set if compatability with older versions of GCC is required,
+    where struct { float a; } would be returned from a function
+    by a hidden extra argument rather than in r0.  */
+ #define ARM_FLAG_BUGGY_RETURN_IN_MEMORY	(1 << 17)
+ 
  #define TARGET_APCS			(target_flags & ARM_FLAG_APCS_FRAME)
  #define TARGET_POKE_FUNCTION_NAME	(target_flags & ARM_FLAG_POKE)
  #define TARGET_FPE			(target_flags & ARM_FLAG_FPE)
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 338,343 ****
--- 363,370 ----
  #define TARGET_ABORT_NORETURN		(target_flags & ARM_FLAG_ABORT_NORETURN)
  #define TARGET_SINGLE_PIC_BASE		(target_flags & ARM_FLAG_SINGLE_PIC_BASE)
  #define TARGET_LONG_CALLS		(target_flags & ARM_FLAG_LONG_CALLS)
+ #define TARGET_ATPCS			(target_flags & ARM_FLAG_ATPCS)
+ #define TARGET_BUGGY_RETURN_IN_MEMORY	(target_flags & ARM_FLAG_BUGGY_RETURN_IN_MEMORY)
  
  /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
     Bit 31 is reserved.  See riscix.h.  */
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 399,404 ****
--- 426,437 ----
    {"long-calls",		ARM_FLAG_LONG_CALLS,		\
       "Generate call insns as indirect calls, if necessary"},	\
    {"no-long-calls",	       -ARM_FLAG_LONG_CALLS, ""},	\
+   {"atpcs",			ARM_FLAG_ATPCS, 		\
+     "generate ATPCS compliant code, rather than APCS compliant code" }, \
+   {"no-atpcs", 		       -ARM_FLAG_ATPCS,  "" },		\
+   {"buggy-return-in-memory",	ARM_FLAG_BUGGY_RETURN_IN_MEMORY,\
+     "return struct { float a; } in memory" },			\
+   {"no-buggy-return-in-memory",-ARM_FLAG_BUGGY_RETURN_IN_MEMORY, "" }, \
    SUBTARGET_SWITCHES						\
    {"",				TARGET_DEFAULT, "" }		\
  }

Index: gcc/config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.c,v
retrieving revision 1.84
diff -p -r1.84 arm.c
*** arm.c	2000/02/29 01:42:52	1.84
--- arm.c	2000/03/03 21:30:20
*************** arm_override_options ()
*** 497,502 ****
--- 497,508 ----
    if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
      warning ("-g with -fomit-frame-pointer may not give sensible debugging");
    
+   if (TARGET_BUGGY_RETURN_IN_MEMORY && TARGET_ATPCS)
+     {
+       warning ("-mbuggy-return-in-memory is overriden by -matpcs.");
+       target_flags &= ARM_FLAG_BUGGY_RETURN_IN_MEMORY;
+     }
+   
    /* If stack checking is disabled, we can use r10 as the PIC register,
       which keeps r9 available.  */
    if (flag_pic && ! TARGET_APCS_STACK)
*************** arm_return_in_memory (type)
*** 1393,1408 ****
       tree type;
  {
    if (! AGGREGATE_TYPE_P (type))
!     {
!       /* All simple types are returned in registers. */
!       return 0;
!     }
!   else if (int_size_in_bytes (type) > 4)
!     {
!       /* All structures/unions bigger than one word are returned in memory. */
!       return 1;
!     }
!   else if (TREE_CODE (type) == RECORD_TYPE)
      {
        tree field;
  
--- 1399,1417 ----
       tree type;
  {
    if (! AGGREGATE_TYPE_P (type))
!     /* All simple types are returned in registers. */
!     return 0;
! 
!   if (int_size_in_bytes (type) > 4)
!     /* All structures/unions bigger than one word are returned in memory. */
!     return 1;
! 
!   if (TARGET_ATPCS)
!     /* The ATPCS says that any structure or union of no larger than
!        one word is returned in a register.  */
!     return 0;
!   
!   if (TREE_CODE (type) == RECORD_TYPE)
      {
        tree field;
  
*************** arm_return_in_memory (type)
*** 1424,1436 ****
  
        /* Check that the first field is valid for returning in a register...  */
  
!       /* ... Floats are not allowed */
!       if (FLOAT_TYPE_P (TREE_TYPE (field)))
  	return 1;
  
!       /* ... Aggregates that are not themselves valid for returning in
! 	 a register are not allowed.  */
!       if (RETURN_IN_MEMORY (TREE_TYPE (field)))
  	return 1;
  
        /* Now check the remaining fields, if any.  Only bitfields are allowed,
--- 1433,1453 ----
  
        /* Check that the first field is valid for returning in a register...  */
  
!       /* The APCS only says that the structrue must be integer-like.  It
! 	 does not say that it may not contain integer values.  Thus
! 	 struct { float a; } should be returned in a register.  Earlier
! 	 implementations got this wrong.  */
!       if (TARGET_BUGGY_RETURN_IN_MEMORY
! 	  && FLOAT_TYPE_P (TREE_TYPE (field)))
  	return 1;
  
!       /* Similarly the APCS only insists that all the sub-fields of a
! 	 structure be addressible.  It does not insist that if these
! 	 sub-fields themselves are structures that they also conform
! 	 to the integer-like specification.  This is another thing
! 	 that the old compiler did incorrectly.  */
!       if (TARGET_BUGGY_RETURN_IN_MEMORY
! 	  && RETURN_IN_MEMORY (TREE_TYPE (field)))
  	return 1;
  
        /* Now check the remaining fields, if any.  Only bitfields are allowed,
*************** arm_return_in_memory (type)
*** 1448,1454 ****
  
        return 0;
      }
!   else if (TREE_CODE (type) == UNION_TYPE)
      {
        tree field;
  
--- 1465,1472 ----
  
        return 0;
      }
!   
!   if (TREE_CODE (type) == UNION_TYPE)
      {
        tree field;
  
*************** arm_return_in_memory (type)
*** 1471,1478 ****
        return 0;
      }
    
!   /* XXX Not sure what should be done for other aggregates, so put them in
!      memory. */
    return 1;
  }
  
--- 1489,1496 ----
        return 0;
      }
    
!   /* XXX Not sure what should be done for
!      other aggregates so put them in memory.  */
    return 1;
  }
  
Index: gcc/config/arm/semi.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/semi.h,v
retrieving revision 1.3
diff -p -r1.3 semi.h
*** semi.h	1999/11/02 17:06:24	1.3
--- semi.h	2000/03/03 22:09:25
*************** Boston, MA 02111-1307, USA.  */
*** 26,33 ****
  #define CPP_PREDEFINES \
      "-Darm -D__semi__ -Acpu(arm) -Amachine(arm)"
  
- #define ASM_SPEC "%{mbig-endian:-EB}"
- 
  #define LINK_SPEC "%{mbig-endian:-EB} -X"
  
  #ifndef TARGET_VERSION
--- 26,31 ----

Index: gcc/config/arm/unknown-elf-oabi.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/unknown-elf-oabi.h,v
retrieving revision 1.2
diff -p -r1.2 unknown-elf-oabi.h
*** unknown-elf-oabi.h	1999/09/04 15:08:56	1.2
--- unknown-elf-oabi.h	2000/03/03 22:09:25
*************** Boston, MA 02111-1307, USA.  */
*** 26,35 ****
  
  #define CPP_PREDEFINES "-Darm_oabi -Darm -Darm_elf -Acpu(arm) -Amachine(arm) -D__ELF__"
  
! #ifndef ASM_SPEC
! #define ASM_SPEC "-moabi %{mbig-endian:-EB} %{mcpu=*:-m%*} %{march=*:-m%*} \
!  %{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork}"
! #endif
  
  /* Now get the routine arm-elf definitions.  */
  #include "arm/unknown-elf.h"
--- 26,32 ----
  
  #define CPP_PREDEFINES "-Darm_oabi -Darm -Darm_elf -Acpu(arm) -Amachine(arm) -D__ELF__"
  
! #define SUBTARGET_EXTRA_ASM_SPECS "-moabi"
  
  /* Now get the routine arm-elf definitions.  */
  #include "arm/unknown-elf.h"
Index: gcc/config/arm/elf.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/elf.h,v
retrieving revision 1.17
diff -p -r1.17 elf.h
*** elf.h	2000/02/29 01:42:52	1.17
--- elf.h	2000/03/03 21:30:20
*************** Boston, MA 02111-1307, USA.  */
*** 151,161 ****
     Otherwise, the readonly data section is used.  */
  #define JUMP_TABLES_IN_TEXT_SECTION 1
  
- #ifndef ASM_SPEC
- #define ASM_SPEC "%{mbig-endian:-EB} %{mcpu=*:-m%*} %{march=*:-m%*} \
-  %{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork} %{mapcs-float:mfloat}"
- #endif
- 
  #ifndef LINK_SPEC
  #define LINK_SPEC "%{mbig-endian:-EB} -X"
  #endif
--- 151,156 ----

Index: gcc/config/arm/linux-elf.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/linux-elf.h,v
retrieving revision 1.13
diff -p -r1.13 linux-elf.h
*** linux-elf.h	1999/12/18 13:34:21	1.13
--- linux-elf.h	2000/03/03 21:30:20
*************** Boston, MA 02111-1307, USA.  */
*** 36,42 ****
  	" %{mapcs-26:-m armelf_linux26} %{!mapcs-26:-m armelf_linux} -p"
  # endif
  # define SUBTARGET_EXTRA_ASM_SPEC	\
! 	" %{mapcs-26:-mapcs-26} %(!mapcs-26:-mapcs-32}"
  # define MULTILIB_DEFAULTS \
  	{ "mlittle-endian", "mhard-float", "mapcs-32", "mno-thumb-interwork" }
  # define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
--- 36,42 ----
  	" %{mapcs-26:-m armelf_linux26} %{!mapcs-26:-m armelf_linux} -p"
  # endif
  # define SUBTARGET_EXTRA_ASM_SPEC	\
! 	" %{!mapcs-*:-mapcs-32}"
  # define MULTILIB_DEFAULTS \
  	{ "mlittle-endian", "mhard-float", "mapcs-32", "mno-thumb-interwork" }
  # define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
*************** Boston, MA 02111-1307, USA.  */
*** 50,56 ****
  	" %{mapcs-32:-m armelf_linux} %{!mapcs-32:-m armelf_linux26} -p"
  # endif
  # define SUBTARGET_EXTRA_ASM_SPEC	\
! 	" %{mapcs-32:-mapcs-32} %(!mapcs-32:-mapcs-26}"
  # define MULTILIB_DEFAULTS \
  	{ "mlittle-endian", "mhard-float", "mapcs-26", "mno-thumb-interwork" }
  #endif
--- 50,56 ----
  	" %{mapcs-32:-m armelf_linux} %{!mapcs-32:-m armelf_linux26} -p"
  # endif
  # define SUBTARGET_EXTRA_ASM_SPEC	\
! 	" %{!mapcs-*:-mapcs-26}"
  # define MULTILIB_DEFAULTS \
  	{ "mlittle-endian", "mhard-float", "mapcs-26", "mno-thumb-interwork" }
  #endif
*************** Boston, MA 02111-1307, USA.  */
*** 102,114 ****
     -X \
     %{mbig-endian:-EB}" \
     SUBTARGET_EXTRA_LINK_SPEC
- 
- #define ASM_SPEC "%{mbig-endian:-EB} \
-    %{mcpu=*:-m%*} %{march=*:-m%*} \
-    %{mthumb-interwork:-mthumb-interwork} \
-    %{msoft-float:-mno-fpu} \
-    %{mapcs-float:-mfloat}" \
-    SUBTARGET_EXTRA_ASM_SPEC
  
  #undef  CPP_PREDEFINES
  #define CPP_PREDEFINES \
--- 102,107 ----

Index: gcc/config/arm/unknown-elf-oabi.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/unknown-elf-oabi.h,v
retrieving revision 1.2
diff -p -r1.2 unknown-elf-oabi.h
*** unknown-elf-oabi.h	1999/09/04 15:08:56	1.2
--- unknown-elf-oabi.h	2000/03/03 22:08:25
*************** Boston, MA 02111-1307, USA.  */
*** 26,35 ****
  
  #define CPP_PREDEFINES "-Darm_oabi -Darm -Darm_elf -Acpu(arm) -Amachine(arm) -D__ELF__"
  
! #ifndef ASM_SPEC
! #define ASM_SPEC "-moabi %{mbig-endian:-EB} %{mcpu=*:-m%*} %{march=*:-m%*} \
!  %{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork}"
! #endif
  
  /* Now get the routine arm-elf definitions.  */
  #include "arm/unknown-elf.h"
--- 26,32 ----
  
  #define CPP_PREDEFINES "-Darm_oabi -Darm -Darm_elf -Acpu(arm) -Amachine(arm) -D__ELF__"
  
! #define SUBTARGET_EXTRA_ASM_SPECS "-moabi"
  
  /* Now get the routine arm-elf definitions.  */
  #include "arm/unknown-elf.h"

Index: gcc/config/arm/thumb.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/thumb.h,v
retrieving revision 1.18
diff -p -r1.18 thumb.h
*** thumb.h	2000/02/18 18:22:10	1.18
--- thumb.h	2000/03/03 21:52:34
*************** Boston, MA 02111-1307, USA.  */
*** 49,55 ****
  "
  #endif
  
! #define ASM_SPEC "-marm7tdmi %{mthumb-interwork:-mthumb-interwork} %{mbig-endian:-EB}"
  #ifndef LINK_SPEC
  #define LINK_SPEC "%{mbig-endian:-EB} -X"
  #endif
--- 49,69 ----
  "
  #endif
  
! #ifndef SUBTARGET_EXTRA_ASM_SPEC
! #define SUBTARGET_EXTRA_ASM_SPEC
! #endif
! 
! #ifndef ASM_SPEC
! #define ASM_SPEC "\
! -marm7tdmi \
! %{mbig-endian:-EB} \
! %{mcpu=*:-m%*} \
! %{march=*:-m%*} \
! %{matpcs:-matpcs} \
! %{mthumb-interwork:-mthumb-interwork} \
! " SUBTARGET_EXTRA_ASM_SPEC
! #endif
! 
  #ifndef LINK_SPEC
  #define LINK_SPEC "%{mbig-endian:-EB} -X"
  #endif
*************** Boston, MA 02111-1307, USA.  */
*** 64,70 ****
  #define THUMB_FLAG_SINGLE_PIC_BASE		0x4000  /* same as in arm.h */
  #define THUMB_FLAG_CALLEE_SUPER_INTERWORKING	0x40000 
  #define THUMB_FLAG_CALLER_SUPER_INTERWORKING	0x80000 
! 
  
  /* Run-time compilation parameters selecting different hardware/software subsets.  */
  extern int target_flags;
--- 78,84 ----
  #define THUMB_FLAG_SINGLE_PIC_BASE		0x4000  /* same as in arm.h */
  #define THUMB_FLAG_CALLEE_SUPER_INTERWORKING	0x40000 
  #define THUMB_FLAG_CALLER_SUPER_INTERWORKING	0x80000 
! #define THUMB_FLAG_ATPCS			(1 << 21)
  
  /* Run-time compilation parameters selecting different hardware/software subsets.  */
  extern int target_flags;
*************** extern int target_flags;
*** 75,80 ****
--- 89,95 ----
  				 ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \
  				 : (target_flags & THUMB_FLAG_BACKTRACE))
  #define TARGET_SINGLE_PIC_BASE	(target_flags & THUMB_FLAG_SINGLE_PIC_BASE)
+ #define TARGET_ATPCS		(target_flags & ARM_FLAG_ATPCS)
  
  #ifndef GOT_PCREL
  #define GOT_PCREL		0
*************** extern int target_flags;
*** 116,121 ****
--- 131,139 ----
    {"single-pic-base",		    THUMB_FLAG_SINGLE_PIC_BASE,	\
       "Do not load the PIC register in function prologues" },	\
    {"no-single-pic-base",	   -THUMB_FLAG_SINGLE_PIC_BASE, ""}, \
+   {"atpcs",			ARM_FLAG_ATPCS, 		\
+     "generate ATPCS compliant code, rather than APCS compliant code" }, \
+   {"no-atpcs", 		       -ARM_FLAG_ATPCS,  "" },		\
    SUBTARGET_SWITCHES						\
    {"",                          TARGET_DEFAULT, ""}         	\
  }

Index: gcc/config/arm/thumb.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/thumb.c,v
retrieving revision 1.17
diff -p -r1.17 thumb.c
*** thumb.c	2000/02/17 17:59:13	1.17
--- thumb.c	2000/03/03 21:52:34
*************** thumb_return_in_memory (type)
*** 2290,2307 ****
       tree type;
  {
    if (! AGGREGATE_TYPE_P (type))
!     {
!       /* All simple types are returned in registers. */
  
!       return 0;
!     }
!   else if (int_size_in_bytes (type) > 4)
!     {
!       /* All structures/unions bigger than one word are returned in memory. */
!       
!       return 1;
!     }
!   else if (TREE_CODE (type) == RECORD_TYPE)
      {
        tree field;
  
--- 2290,2308 ----
       tree type;
  {
    if (! AGGREGATE_TYPE_P (type))
!     /* All simple types are returned in registers. */
!     return 0;
  
!   if (int_size_in_bytes (type) > 4)
!     /* All structures/unions bigger than one word are returned in memory. */
!     return 1;
! 
!   if (TARGET_ATPCS)
!     /* The ATPCS says that any structure or union of no larger than
!        one word is returned in a register.  */
!     return 0;
!   
!   if (TREE_CODE (type) == RECORD_TYPE)
      {
        tree field;
  
*************** thumb_return_in_memory (type)
*** 2312,2327 ****
  	 the structure.  */
  
        /* Find the first field, ignoring non FIELD_DECL things which will
! 	 have been created by C++. */
        for (field = TYPE_FIELDS (type);
  	   field && TREE_CODE (field) != FIELD_DECL;
  	   field = TREE_CHAIN (field))
  	continue;
  
        if (field == NULL)
! 	return 0; /* An empty structure.  Allowed by an extension to ANSI C. */
  
!       /* Now check the remaining fields, if any. */
        for (field = TREE_CHAIN (field); field;  field = TREE_CHAIN (field))
  	{
  	  if (TREE_CODE (field) != FIELD_DECL)
--- 2313,2328 ----
  	 the structure.  */
  
        /* Find the first field, ignoring non FIELD_DECL things which will
! 	 have been created by C++.  */
        for (field = TYPE_FIELDS (type);
  	   field && TREE_CODE (field) != FIELD_DECL;
  	   field = TREE_CHAIN (field))
  	continue;
  
        if (field == NULL)
! 	return 0; /* An empty structure.  Allowed by an extension to ANSI C.  */
  
!       /* Now check the remaining fields, if any.  */
        for (field = TREE_CHAIN (field); field;  field = TREE_CHAIN (field))
  	{
  	  if (TREE_CODE (field) != FIELD_DECL)
*************** thumb_return_in_memory (type)
*** 2333,2339 ****
  
        return 0;
      }
!   else if (TREE_CODE (type) == UNION_TYPE)
      {
        tree field;
  
--- 2334,2341 ----
  
        return 0;
      }
!   
!   if (TREE_CODE (type) == UNION_TYPE)
      {
        tree field;
  
*************** thumb_return_in_memory (type)
*** 2353,2360 ****
        
        return 0;
      }
!   /* XXX Not sure what should be done for other aggregates, so put them in
!      memory. */
    return 1;
  }
  
--- 2355,2363 ----
        
        return 0;
      }
!   
!   /* XXX Not sure what should be done for other aggregates,
!      so put them in memory.  */
    return 1;
  }
  
Index: gcc/invoke.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/invoke.texi,v
retrieving revision 1.177
diff -p -r1.177 invoke.texi
*** invoke.texi	2000/02/29 01:42:52	1.177
--- invoke.texi	2000/03/03 21:52:34
*************** in the following sections.
*** 256,262 ****
  
  @emph{ARM Options}
  -mapcs-frame -mno-apcs-frame
! -mapcs-26 -mapcs-32
  -mapcs-stack-check -mno-apcs-stack-check
  -mapcs-float -mno-apcs-float
  -mapcs-reentrant -mno-apcs-reentrant
--- 256,262 ----
  
  @emph{ARM Options}
  -mapcs-frame -mno-apcs-frame
! -mapcs-26 -mapcs-32 -matpcs
  -mapcs-stack-check -mno-apcs-stack-check
  -mapcs-float -mno-apcs-float
  -mapcs-reentrant -mno-apcs-reentrant
*************** in the following sections.
*** 279,284 ****
--- 279,285 ----
  -mtpcs-leaf-frame -mno-tpcs-leaf-frame
  -mlittle-endian  -mbig-endian
  -mthumb-interwork -mno-thumb-interwork
+ -matpcs
  -mstructure-size-boundary=
  -mnop-fun-dllimport -mno-nop-fun-dllimport
  -mcallee-super-interworking -mno-callee-super-interworking
*************** and conforming to the function calling s
*** 4404,4409 ****
--- 4405,4425 ----
  option.  This option replaces the @samp{-m6} option of previous releases
  of the compiler.
  
+ @item -matpcs
+ @kindex -matpcs
+ @kindex -mno-atpcs
+ Generate code that conforms to the ATPCS (ARM Thumb Procedure Call
+ Standard).  This ABI standard is slightly different from the APCS
+ standard and is incompatible in the way that small structures are
+ returned from a function.  For the APCS a structure like this
+ 
+ @smallexample
+ struct @{@ char a; char b; @}@
+ @end smallexample
+ 
+ would be returned in memory, whereas for the ATPS it is returned in a
+ register. 
+ 
  @item -mapcs-stack-check
  @kindex -mapcs-stack-check
  @kindex -mno-apcs-stack-check
*************** Generate reentrant, position independent
*** 4432,4437 ****
--- 4448,4483 ----
  to specifying the @samp{-fpic} option.  The default is
  @samp{-mno-apcs-reentrant}.
  
+ @item -mbuggy-return-in-memory
+ @kindex -mbuggy-return-in-memory
+ @kindex -mno-buggy-return-in-memory
+ This options enables compatability with older versions of @code{GCC}
+ for the ARM which incorrectly interpreted the APCS.  These older
+ versions would incorrectly return some small structures in memory
+ instead of in a register.  This only affects functions which return a
+ structure containing a single float value like this:
+ 
+ @smallexample
+ struct @{@ float a; @}@
+ @end smallexample
+ 
+ and functions returning a structure which is:
+ 
+ @table @bullet
+ @item Less than or equal to 32 bits in size
+ @item Contains exactly one field which is not a bitfield.
+ @item This field is the first field in the structure.
+ @item This field is itself a structure type.
+ @item The contents of this sub-structure are at least two, non-bitfield types:
+ @end table
+ 
+ @smallexample
+ typedef struct @{@ char a; char b @}@ sub_structure;
+ typedef struct @{@ sub_structure s; @}@ structure;
+ @end smallexample
+ 
+ By default this option is not enabled.
+ 
  @item -mthumb-interwork
  @kindex -mthumb-interwork
  @kindex -mno-thumb-interwork
*************** the default for all standard configurati
*** 4690,4695 ****
--- 4736,4756 ----
  @item -mbig-endian
  @kindex -mbig-endian
  Generate code for a processor running in big-endian mode.
+ 
+ @item -matpcs
+ @kindex -matpcs
+ @kindex -mno-atpcs
+ Generate code that conforms to the ATPCS (ARM Thumb Procedure Call
+ Standard).  This ABI standard is slightly different from the APCS
+ standard and is incompatible in the way that small structures are
+ returned from a function.  For the APCS a structure like this
+ 
+ @smallexample
+ struct @{@ char a; char b; @}@
+ @end smallexample
+ 
+ would be returned in memory, whereas for the ATPS it is returned in a
+ register. 
  
  @item -mstructure-size-boundary=<n>
  @kindex -mstructure-size-boundary



Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src//src/gas/config/tc-arm.c,v
retrieving revision 1.33
diff -p -r1.33 tc-arm.c
*** tc-arm.c	2000/02/24 19:46:27	1.33
--- tc-arm.c	2000/03/03 21:30:45
*************** static int target_oabi = 0;
*** 98,103 ****
--- 98,104 ----
  #if defined OBJ_COFF || defined OBJ_ELF
  /* Flags stored in private area of BFD structure */
  static boolean		uses_apcs_26 = false;
+ static boolean		atpcs = false;
  static boolean		support_interwork = false;
  static boolean		uses_apcs_float = false;
  static boolean		pic_code = false;
*************** md_begin ()
*** 5021,5026 ****
--- 5022,5045 ----
      if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
  
      bfd_set_private_flags (stdoutput, flags);
+     
+     /* We have run out flags in the COFF header to encode the
+        status of ATPCS support, so instead we create a dummy,
+        empty, debug section called .arm.atpcs  */
+     if (atpcs)
+       {
+ 	asection * sec;
+ 	
+ 	sec = bfd_make_section (stdoutput, ".arm.atpcs");
+ 
+ 	if (sec != NULL)
+ 	  {
+ 	    bfd_set_section_flags
+ 	      (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
+ 	    bfd_set_section_size (stdoutput, sec, 0);
+ 	    bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
+ 	  }
+       }
    }
  #endif
    
*************** _("Warning: Use of the 'nv' conditional 
*** 6354,6359 ****
--- 6373,6379 ----
   *    ARM Procedure Calling Standard:
   *	      -mapcs-32		      32 bit APCS
   *	      -mapcs-26		      26 bit APCS
+  *            -matpcs                 ARM/Thumb Procedure Call Standard
   *	      -mapcs-float	      Pass floats in float regs
   *	      -mapcs-reentrant        Position independent code
   *            -mthumb-interwork       Code supports Arm/Thumb interworking
*************** md_parse_option (c, arg)
*** 6502,6507 ****
--- 6522,6533 ----
  	      as_bad (_("Unrecognised APCS switch -m%s"), arg);
  	      return 0;
    	    }
+ 	  
+ 	  if (! strcmp (str, "atpcs"))
+ 	    {
+ 	      atpcs = true;
+ 	      return 1;
+ 	    }
  #endif
  	  /* Strip off optional "arm" */
  	  if (! strncmp (str, "arm", 3))
*************** _("\
*** 6716,6722 ****
  #if defined OBJ_COFF || defined OBJ_ELF
    fprintf (fp,
  _("\
!   -mapcs-32, -mapcs-26      specify which ARM Procedure Calling Standard to use\n"));
    fprintf (fp,
  _("\
    -mapcs-float              floating point args are passed in FP regs\n"));
--- 6742,6748 ----
  #if defined OBJ_COFF || defined OBJ_ELF
    fprintf (fp,
  _("\
!   -mapcs-[26|32], -matpcs   specify which ABI to use\n"));
    fprintf (fp,
  _("\
    -mapcs-float              floating point args are passed in FP regs\n"));

Index: gas/doc/c-arm.texi
===================================================================
RCS file: /cvs/src//src/gas/doc/c-arm.texi,v
retrieving revision 1.5
diff -p -r1.5 c-arm.texi
*** c-arm.texi	2000/01/10 22:22:56	1.5
--- c-arm.texi	2000/03/03 22:18:58
***************
*** 1,4 ****
! @c Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
  @c This is part of the GAS manual.
  @c For copying conditions, see the file as.texinfo.
  
--- 1,4 ----
! @c Copyright (C) 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
  @c This is part of the GAS manual.
  @c For copying conditions, see the file as.texinfo.
  
***************
*** 27,92 ****
  @section Options
  @cindex ARM options (none)
  @cindex options for ARM (none)
  @table @code
  @cindex @code{-marm} command line option, ARM
! @item -marm [@var{2}|@var{250}|@var{3}|@var{6}|@var{60}|@var{600}|@var{610}|@var{620}|@var{7}|@var{7m}|@var{7d}|@var{7dm}|@var{7di}|@var{7dmi}|@var{70}|@var{700}|@var{700i}|@var{710}|@var{710c}|@var{7100}|@var{7500}|@var{7500fe}|@var{7tdmi}|@var{8}|@var{810}|@var{9}|@var{9tdmi}|@var{920}|@var{strongarm}|@var{strongarm110}|@var{strongarm1100}]
  This option specifies the target processor.  The assembler will issue an
  error message if an attempt is made to assemble an instruction which
  will not execute on the target processor.
  @cindex @code{-marmv} command line option, ARM
! @item -marmv [@var{2}|@var{2a}|@var{3}|@var{3m}|@var{4}|@var{4t}|@var{5}|@var{5t}]
  This option specifies the target architecture.  The assembler will issue
  an error message if an attempt is made to assemble an instruction which
  will not execute on the target architecture.
  @cindex @code{-mthumb} command line option, ARM
  @item -mthumb
  This option specifies that only Thumb instructions should be assembled.
  @cindex @code{-mall} command line option, ARM
  @item -mall
  This option specifies that any Arm or Thumb instruction should be assembled.
  @cindex @code{-mfpa} command line option, ARM
! @item -mfpa [@var{10}|@var{11}]
  This option specifies the floating point architecture in use on the
  target processor. 
  @cindex @code{-mfpe-old} command line option, ARM
  @item -mfpe-old
  Do not allow the assemble of floating point multiple instructions.
  @cindex @code{-mno-fpu} command line option, ARM
  @item -mno-fpu
  Do not allow the assembly of any floating point instructions.
  @cindex @code{-mthumb-interwork} command line option, ARM
  @item -mthumb-interwork
  This option specifies that the output generated by the assembler should
  be marked as supporting interworking.
  @cindex @code{-mapcs} command line option, ARM
! @item -mapcs [@var{26}|@var{32}]
  This option specifies that the output generated by the assembler should
  be marked as supporting the indicated version of the Arm Procedure.
  Calling Standard.
  @item -mapcs-float
  This indicates the the floating point variant of the APCS should be
  used.  In this variant floating point arguments are passed in FP
  registers rather than integer registers.
  @item -mapcs-reentrant
  This indicates that the reentrant variant of the APCS should be used.
  This variant supports position independent code.
  @cindex @code{-EB} command line option, ARM
  @item -EB
  This option specifies that the output generated by the assembler should
  be marked as being encoded for a big-endian processor.
  @cindex @code{-EL} command line option, ARM
  @item -EL
  This option specifies that the output generated by the assembler should
  be marked as being encoded for a little-endian processor.
  @cindex @code{-k} command line option, ARM
  @cindex PIC code generation for ARM
  @item -k
  This option enables the generation of PIC (position independent code).
  @item -moabi
  This indicates that the code should be assembled using the old ARM ELF
  conventions, based on a beta release release of the ARM-ELF
  specifications, rather than the default conventions which are based on
  the final release of the ARM-ELF specifications.
  @end table
  
  
--- 27,120 ----
  @section Options
  @cindex ARM options (none)
  @cindex options for ARM (none)
+ 
  @table @code
+ 
  @cindex @code{-marm} command line option, ARM
! @item -marm @var{[2|250|3|6|60|600|610|620|7|7m|7d|7dm|7di|7dmi|70|700|700i|710|710c|7100|7500|7500fe|7tdmi|8|810|9|9tdmi|920|strongarm|strongarm110|strongarm1100]}
  This option specifies the target processor.  The assembler will issue an
  error message if an attempt is made to assemble an instruction which
  will not execute on the target processor.
+ 
  @cindex @code{-marmv} command line option, ARM
! @item -marmv @var{[2|2a|3|3m|4|4t|5|5t]}
  This option specifies the target architecture.  The assembler will issue
  an error message if an attempt is made to assemble an instruction which
  will not execute on the target architecture.
+ 
  @cindex @code{-mthumb} command line option, ARM
  @item -mthumb
  This option specifies that only Thumb instructions should be assembled.
+ 
  @cindex @code{-mall} command line option, ARM
  @item -mall
  This option specifies that any Arm or Thumb instruction should be assembled.
+ 
  @cindex @code{-mfpa} command line option, ARM
! @item -mfpa @var{[10|11]}
  This option specifies the floating point architecture in use on the
  target processor. 
+ 
  @cindex @code{-mfpe-old} command line option, ARM
  @item -mfpe-old
  Do not allow the assemble of floating point multiple instructions.
+ 
  @cindex @code{-mno-fpu} command line option, ARM
  @item -mno-fpu
  Do not allow the assembly of any floating point instructions.
+ 
  @cindex @code{-mthumb-interwork} command line option, ARM
  @item -mthumb-interwork
  This option specifies that the output generated by the assembler should
  be marked as supporting interworking.
+ 
  @cindex @code{-mapcs} command line option, ARM
! @item -mapcs @var{[26|32]}
  This option specifies that the output generated by the assembler should
  be marked as supporting the indicated version of the Arm Procedure.
  Calling Standard.
+ 
+ @cindex @code{-matpcs} command line option, ARM
+ @item -matpcs
+ This option specifies that the output generated by the assembler should 
+ be marked as supporting the Arm/Thumb Procedure Calling Standard.  If
+ enabled this option will cause the assembler to create an empty
+ debugging section in the object file called .arm.atpcs.  Debuggers can
+ use this to determine the ABI being used by.
+ 
+ @cindex @code{-mapcs-float} command line option, ARM
  @item -mapcs-float
  This indicates the the floating point variant of the APCS should be
  used.  In this variant floating point arguments are passed in FP
  registers rather than integer registers.
+ 
+ @cindex @code{-mapcs-reentrant} command line option, ARM
  @item -mapcs-reentrant
  This indicates that the reentrant variant of the APCS should be used.
  This variant supports position independent code.
+ 
  @cindex @code{-EB} command line option, ARM
  @item -EB
  This option specifies that the output generated by the assembler should
  be marked as being encoded for a big-endian processor.
+ 
  @cindex @code{-EL} command line option, ARM
  @item -EL
  This option specifies that the output generated by the assembler should
  be marked as being encoded for a little-endian processor.
+ 
  @cindex @code{-k} command line option, ARM
  @cindex PIC code generation for ARM
  @item -k
  This option enables the generation of PIC (position independent code).
+ 
+ @cindex @code{-moabi} command line option, ARM
  @item -moabi
  This indicates that the code should be assembled using the old ARM ELF
  conventions, based on a beta release release of the ARM-ELF
  specifications, rather than the default conventions which are based on
  the final release of the ARM-ELF specifications.
+ 
  @end table
  
  
*************** example:
*** 153,159 ****
  @end smallexample
  
  @cindex @code{code} directive, ARM
! @item .code [@var{16}|@var{32}]
  This directive selects the instruction set being generated. The value 16
  selects Thumb, with the value 32 selecting ARM.
  
--- 181,187 ----
  @end smallexample
  
  @cindex @code{code} directive, ARM
! @item .code @var{[16|32]}
  This directive selects the instruction set being generated. The value 16
  selects Thumb, with the value 32 selecting ARM.
  


More information about the Gcc-patches mailing list