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

See the CrossGCC FAQ for lots more information.


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

Re: _GLOBAL_$F$


 When being out of town during the last week (north of the arctic circle seeing
nice aurora borealis...) this a little late but perhaps not too much...

Nik Ilijic wrote:
> 
> I'm working with gcc ver 2.95.3 on a linux box, compiling to an embedded
> 68360 target (m68k-coff target).  So far I have managed to compile & link my
> project, but have come across a problem with the size of the binary.

 AFAIK, the m68k-coff target doesn't use things related to DWARF2, which is
quite ELF-related, referring to the reply from Dave Korn...
 
> the entire code (.text) and .data sections are about twice the size as I get
> with the SDS toolset.  After examining the map file produced by the linker,
> the biggest blowout seems to be in the data section and it is caused by
> these _GLOBAL_$F$ references (see section of map file below).

 The thread "Can't build gcc-3.0.1 for m68k-coff" on this list discussed about
the problems with the '__EH_FRAME_BEGIN__' appearing as undefined with gcc-3.0.1
but whether the same kind of problem (DWARF2-unwind stuff tried with COFF) already
existed in gcc-2.95.3 is unclear. 

> What are these _GLOBAL_$F$'s and how do I get rid of them to reduce my
> code/data size so that it fits into the rom & ram.

 I will try to see how the C++ parts in my gcc-2.95.3 behave, whether I get those
_GLOBAL_$F$'s too. Not toyed with the C++ and m68k much...

 Meanwhile there are that very famous and much talked-about problem with the
'volatile' causing code-bloat with m68k, and another problem related to the
missing '__attribute__((interrupt))' with the m68k-targets. The following code
sample (stupid and not much related to m68k) should tell about these:

-------------------------- clip -------------------------------------
#include <stdio.h>

#ifndef ISR_FUNC
#define ISR_FUNC	__attribute__((interrupt))
#endif

#define PBDR		(*(volatile char *) (0xff60))
#define ITU_TSR0	(*(volatile char *) (0xff61))
#define ITU_TSR1	(*(volatile char *) (0xff62))
#define ITU_TSR2	(*(volatile char *) (0xff63))

/*
#define PBDR		(*(char *) (0xff60))
#define ITU_TSR0	(*(char *) (0xff61))
#define ITU_TSR1	(*(char *) (0xff62))
#define ITU_TSR2	(*(char *) (0xff63))
*/

int count;

void set_itu_tsr12(void)
{
	ITU_TSR1 |= 0x01;
	ITU_TSR2 |= 0x02;
}

void clr_itu_tsr12(void)
{
	ITU_TSR1 &= 0xFE;
	ITU_TSR2 &= 0xFD;
}

void onoff_itu_tsr12(void)
{
	ITU_TSR1 |= 0x01;
	ITU_TSR2 |= 0x02;
	ITU_TSR1 &= 0xFE;
	ITU_TSR2 &= 0xFD;
}

void ISR_FUNC handle_intr(void)
{
	count++;
	if (count == 400)
	  {
	    PBDR ^= 0x01;
	    count = 0;
	  }

	ITU_TSR0 |= 0x04;
/*
	ITU_TSR0 &= 0xFE;
	set_itu_tsr12();
	clr_itu_tsr12();
*/
}

int main(void)
{
	do {
	  puts("Thinking hard...\n");
	} while (1);

	return 0;
}
-------------------------- clip -------------------------------------

 This could produce something like:

-------------------------- clip -------------------------------------
	.file	"isr_demo1.c"
gcc2_compiled.:
.text
.globl set_itu_tsr12
	.type	 set_itu_tsr12,@function
set_itu_tsr12:
	bset #0,65378
	bset #1,65379
	rts
	nop
.Lfe1:
	.size	 set_itu_tsr12,.Lfe1-set_itu_tsr12
.globl clr_itu_tsr12
	.type	 clr_itu_tsr12,@function
clr_itu_tsr12:
	bclr #0,65378
	bclr #1,65379
	rts
	nop
.Lfe2:
	.size	 clr_itu_tsr12,.Lfe2-clr_itu_tsr12
.globl onoff_itu_tsr12
	.type	 onoff_itu_tsr12,@function
onoff_itu_tsr12:
	move.l #65378,%a1
	bset #0,(%a1)
	move.l #65379,%a0
	bset #1,(%a0)
	bclr #0,(%a1)
	bclr #1,(%a0)
	rts
	nop
.Lfe3:
	.size	 onoff_itu_tsr12,.Lfe3-onoff_itu_tsr12
.globl handle_intr
	.type	 handle_intr,@function
handle_intr:
	move.l %d1,-(%sp)
	move.l %d0,-(%sp)
	move.l count,%d0
	move.l %d0,%d1
	addq.l #1,%d1
	move.l %d1,count
	cmp.l #399,%d0
	jbne .L6
	eor.b #1,65376
	clr.l count
.L6:
	bset #2,65377
	move.l (%sp)+,%d0
	move.l (%sp)+,%d1
	rte
.Lfe4:
	.size	 handle_intr,.Lfe4-handle_intr
.globl __main
.section	.rodata
.LC0:
	.string	"Thinking hard...\n"
.text
.globl main
	.type	 main,@function
main:
	jsr __main
.L11:
	pea .LC0
	jsr puts
	addq.l #4,%sp
	jbra .L11
	nop
.Lfe5:
	.size	 main,.Lfe5-main
	.comm	count,4,2
	.ident	"GCC: (GNU) 2.95.3-1 20010315 (release)"
-------------------------- clip -------------------------------------

for cpu32, as my compiler does, but the plain vanilla gcc-2.95.3 for
m68k-coff/-elf doesn't understand the '__attribute__' and doesn't
generate the 'bset', 'bclr' etc. bit-operations with the 'volatile'...
If you try this test, you will see...

 Ok, the patches for adding the '__attribute__' have appeared on this
list now and then but here they are again (attached). And I would suggest
trying the following hack for the 'gcc-2.95.3/gcc/recog.c' to solve the
'volatile' one :

-------------------------- clip -------------------------------------
*** recog.c.orig	Sat Oct 28 22:21:47 2001
--- recog.c	Sat Oct 28 22:21:46 2001
***************
*** 969,976 ****
--- 969,980 ----
    if (code == MEM)
      {
        register rtx y = XEXP (op, 0);
+ /*
+       This hack should remove the 'volatile bug' !
+ 
        if (! volatile_ok && MEM_VOLATILE_P (op))
  	return 0;
+ */
        if (GET_CODE (y) == ADDRESSOF)
  	return 1;
        /* Use the mem's mode, since it will be reloaded thus.  */
-------------------------- clip -------------------------------------

 I would be very curious to hear what this hack will break if anything...

 Somehow I think it cannot be this easy, otherwise someone else would have
invented this years ago... The funny thing is that it seems to work and I
haven't found the things this would break...

Cheers, Kai
*** gcc/config/m68k/m68k.c.orig	Mon Aug  7 19:21:51 2000
--- gcc/config/m68k/m68k.c	Fri Aug  4 21:06:04 2000
***************
*** 1,5 ****
  /* Subroutines for insn-output.c for Motorola 68000 family.
!    Copyright (C) 1987, 93-98, 1999 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
  
--- 1,10 ----
  /* Subroutines for insn-output.c for Motorola 68000 family.
!    Copyright (C) 1987, 93-99, 2000 Free Software Foundation, Inc.
!    
!    Modified by (interrupt attribute patch):
!    Michael Schwingen <rincewind@discworld.dascon.de> 
!    Kai Ruottu <karuottu@freenet.hut.fi>
!    Ken Desmet <ken@sdt.be>
  
  This file is part of GNU CC.
  
***************
*** 38,43 ****
--- 43,61 ----
  /* Needed for use_return_insn.  */
  #include "flags.h"
  
+ /* Flag to tell if the current function is an interrupt handler. */
+ int interrupt_handler;
+ 
+ #define MUST_SAVE_REGISTER(regno)					\
+  (! TREE_THIS_VOLATILE (current_function_decl)				\
+    && (regno != STACK_POINTER_REGNUM)					\
+    /* Save any call saved register that was used.  */			\
+    && (regs_ever_live[regno] && !call_used_regs[regno])			\
+    /* Save any register used in an interrupt handler.	 */		\
+    || (regs_ever_live[regno] && interrupt_handler)			\
+    /* Save call clobbered registers in non-leaf interrupt handlers. */	\
+    || (call_used_regs[regno] && interrupt_handler && !current_function_is_leaf))
+ 
  #ifdef SUPPORT_SUN_FPA
  
  /* Index into this array by (register number >> 3) to find the
***************
*** 152,157 ****
--- 170,188 ----
    int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
    
  
+   interrupt_handler = m68k_interrupt_function_p (current_function_decl);
+   /* Save the floating point unit context in case of an interrupt (exception) */
+   if (TARGET_68881 && TARGET_EFPUCS && !current_function_is_leaf && interrupt_handler)
+     {
+ #ifdef MOTOROLA
+      asm_fprintf (stream, "\tfsave -(%Rsp)\n");
+      asm_fprintf (stream, "\tfmoveml %Rfpcr/%Rfpsr/%Rfpiar,-(%Rsp)\n");
+ #else
+      asm_fprintf (stream, "\tfsave -Rsp@-\n");
+      asm_fprintf (stream, "\tfmoveml %Rfpcr/%Rfpsr/%Rfpiar,%Rsp@-\n");
+ #endif
+     }
+   
    if (frame_pointer_needed)
      {
        if (fsize == 0 && TARGET_68040)
***************
*** 287,293 ****
      }
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24; regno < 56; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        {
  #ifdef MOTOROLA
  	asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
--- 318,324 ----
      }
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24; regno < 56; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        {
  #ifdef MOTOROLA
  	asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
***************
*** 310,319 ****
  	  }
        }
  #endif
!   if (TARGET_68881)
!     {
        for (regno = 16; regno < 24; regno++)
! 	if (regs_ever_live[regno] && ! call_used_regs[regno])
  	  {
  	    mask |= 1 << (regno - 16);
  	    num_saved_regs++;
--- 341,351 ----
  	  }
        }
  #endif
!   if ((TARGET_68881 && !interrupt_handler) ||
!       (TARGET_68881 && TARGET_EFPUCS && interrupt_handler ))
!     {	
        for (regno = 16; regno < 24; regno++)
! 	if (MUST_SAVE_REGISTER(regno))
  	  {
  	    mask |= 1 << (regno - 16);
  	    num_saved_regs++;
***************
*** 346,352 ****
        num_saved_regs = 0;
      }
    for (regno = 0; regno < 16; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        {
          mask |= 1 << (15 - regno);
          num_saved_regs++;
--- 378,384 ----
        num_saved_regs = 0;
      }
    for (regno = 0; regno < 16; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        {
          mask |= 1 << (15 - regno);
          num_saved_regs++;
***************
*** 484,489 ****
--- 516,522 ----
  {
    int regno;
  
+   interrupt_handler = m68k_interrupt_function_p (current_function_decl);
    if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
      return 0;
    
***************
*** 491,497 ****
       separate layout routine to perform the common work.  */
    
    for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        return 0;
    
    return 1;
--- 524,530 ----
       separate layout routine to perform the common work.  */
    
    for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        return 0;
    
    return 1;
***************
*** 519,525 ****
    int big = 0;
    rtx insn = get_last_insn ();
    int restore_from_sp = 0;
!   
    /* If the last insn was a BARRIER, we don't have to write any code.  */
    if (GET_CODE (insn) == NOTE)
      insn = prev_nonnote_insn (insn);
--- 552,559 ----
    int big = 0;
    rtx insn = get_last_insn ();
    int restore_from_sp = 0;
! 
!   int interrupt_handler = m68k_interrupt_function_p (current_function_decl);
    /* If the last insn was a BARRIER, we don't have to write any code.  */
    if (GET_CODE (insn) == NOTE)
      insn = prev_nonnote_insn (insn);
***************
*** 544,558 ****
    nregs = 0;  fmask = 0; fpoffset = 0;
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24 ; regno < 56 ; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        nregs++;
    fpoffset = nregs * 8;
  #endif
    nregs = 0;
!   if (TARGET_68881)
      {
        for (regno = 16; regno < 24; regno++)
! 	if (regs_ever_live[regno] && ! call_used_regs[regno])
  	  {
  	    nregs++;
  	    fmask |= 1 << (23 - regno);
--- 578,594 ----
    nregs = 0;  fmask = 0; fpoffset = 0;
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24 ; regno < 56 ; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        nregs++;
    fpoffset = nregs * 8;
  #endif
    nregs = 0;
!   
!   if ((TARGET_68881 && !interrupt_handler) ||
!       (TARGET_68881 && TARGET_EFPUCS && interrupt_handler ))
      {
        for (regno = 16; regno < 24; regno++)
! 	if (MUST_SAVE_REGISTER(regno))
  	  {
  	    nregs++;
  	    fmask |= 1 << (23 - regno);
***************
*** 563,569 ****
    if (frame_pointer_needed)
      regs_ever_live[FRAME_POINTER_REGNUM] = 0;
    for (regno = 0; regno < 16; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        {
          nregs++;
  	mask |= 1 << regno;
--- 599,605 ----
    if (frame_pointer_needed)
      regs_ever_live[FRAME_POINTER_REGNUM] = 0;
    for (regno = 0; regno < 16; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        {
          nregs++;
  	mask |= 1 << regno;
***************
*** 718,724 ****
      }
    if (fpoffset != 0)
      for (regno = 55; regno >= 24; regno--)
!       if (regs_ever_live[regno] && ! call_used_regs[regno])
          {
  	  if (big)
  	    {
--- 754,760 ----
      }
    if (fpoffset != 0)
      for (regno = 55; regno >= 24; regno--)
!       if (MUST_SAVE_REGISTER(regno))
          {
  	  if (big)
  	    {
***************
*** 828,837 ****
  #endif
  	}
      }
!   if (current_function_pops_args)
!     asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
    else
!     fprintf (stream, "\trts\n");
  }
  
  /* Similar to general_operand, but exclude stack_pointer_rtx.  */
--- 864,890 ----
  #endif
  	}
      }
!   if (interrupt_handler)
!     {
!       if (TARGET_68881 && TARGET_EFPUCS && !current_function_is_leaf)
!         {
! #ifdef MOTOROLA
!           asm_fprintf (stream, "\tfmoveml (%Rsp)+,%Rfpcr/%Rfpsr/%Rfpiar\n");
!           asm_fprintf (stream, "\tfrestore (%Rsp)+\n");
! #else
!           asm_fprintf (stream, "\tfmoveml %Rsp@+,%Rfpcr/%Rfpsr/%Rfpiar\n");
!           asm_fprintf (stream, "\tfrestore %Rsp@+\n");
! #endif
! 	}
!       fprintf (stream, "\trte\n");
!     }
    else
!     {
!       if (current_function_pops_args)
!         asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
!       else
!         fprintf (stream, "\trts\n");
!     }
  }
  
  /* Similar to general_operand, but exclude stack_pointer_rtx.  */
***************
*** 3397,3399 ****
--- 3450,3496 ----
      }
    return "eor%.l %2,%0";
  }
+ 
+ 
+ /* Return nonzero if ATTR is a valid attribute for DECL.
+    ATTRIBUTES are any existing attributes and ARGS are the arguments
+    supplied with ATTR.
+ 
+    Supported attributes:
+ 
+    interrupt -- specifies this function is an interrupt handler.
+ */
+ 
+ int
+ m68k_valid_machine_decl_attribute (decl, attributes, attr, args)
+      tree decl;
+      tree attributes;
+      tree attr;
+      tree args;
+ {
+   if (args != NULL_TREE)
+     return 0;
+ 
+   if (is_attribute_p ("interrupt", attr))
+     return TREE_CODE (decl) == FUNCTION_DECL;
+ 
+   return 0;
+ }
+ 
+ /* Return nonzero if FUNC is an interrupt function as specified by the
+    "interrupt" attribute.  */
+ 
+ int
+ m68k_interrupt_function_p(func)
+      tree func;
+ {
+   tree a;
+ 
+   if (TREE_CODE (func) != FUNCTION_DECL)
+     return 0;
+ 
+   a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
+   return (a != NULL_TREE);
+ }
+ 
+ 
*** gcc/config/m68k/m68k.h.orig	Mon Aug  7 19:21:57 2000
--- gcc/config/m68k/m68k.h	Fri Aug  4 19:56:56 2000
***************
*** 119,124 ****
--- 119,131 ----
  #define MASK_ALIGN_INT	4096
  #define TARGET_ALIGN_INT (target_flags & MASK_ALIGN_INT)
  
+ /* When a floating point unit is used during an exception
+    (with the __attribute__ ((interrupt)) ), its context must be saved.
+    This has only effect when a 68881, 68882, 68040 or 68060 is used. */
+ 
+ #define MASK_EFPUCS 8192
+ #define TARGET_EFPUCS (target_flags & MASK_EFPUCS)
+ 
  /* Compile for a CPU32 */
  	/* A 68020 without bitfields is a good heuristic for a CPU32 */
  #define TARGET_CPU32	(TARGET_68020 && !TARGET_BITFIELD)
***************
*** 140,145 ****
--- 147,154 ----
  		|MASK_68020|MASK_BITFIELD|MASK_68881)},			\
      { "bitfield", MASK_BITFIELD},					\
      { "nobitfield", - MASK_BITFIELD},					\
+     { "noefpucs", -MASK_EFPUCS},					\
+     { "efpucs", MASK_EFPUCS},						\
      { "rtd", MASK_RTD},							\
      { "nortd", - MASK_RTD},						\
      { "short", MASK_SHORT},						\
***************
*** 152,157 ****
--- 161,168 ----
      { "nosky", - MASK_SKY},						\
      { "68881", - (MASK_FPA|MASK_SKY)},					\
      { "68881", MASK_68881},						\
+     { "68882", - (MASK_FPA|MASK_SKY)},					\
+     { "68882", MASK_68881},						\
      { "soft-float", - (MASK_FPA|MASK_SKY|MASK_68040_ONLY|MASK_68881)},	\
      { "68020-40", -(MASK_5200|MASK_68060|MASK_68040_ONLY)},		\
      { "68020-40", (MASK_BITFIELD|MASK_68881|MASK_68020|MASK_68040)},	\
***************
*** 2130,2135 ****
--- 2141,2158 ----
  extern void notice_update_cc ();
  extern void finalize_pic ();
  extern void override_options ();
+ 
+ /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
+    is a valid machine specific attribute for DECL.
+    The attributes in ATTRIBUTES have previously been assigned to DECL.  */
+ 
+ extern int m68k_valid_machine_decl_attribute ();
+ 
+ #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
+ m68k_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+ 
+ extern int interrupt_handler;
+ extern int m68k_interrupt_function_p();
  
  
  /*
*** gcc/config/m68k/m68k.md.orig	Mon Aug  7 19:22:03 2000
--- gcc/config/m68k/m68k.md	Fri Aug  4 19:24:58 2000
***************
*** 6964,6969 ****
--- 6964,6971 ----
    "USE_RETURN_INSN"
    "*
  {
+   if (interrupt_handler)
+    return \"rte\";
    if (current_function_pops_args == 0)
      return \"rts\";
    operands[0] = GEN_INT (current_function_pops_args);




------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com

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