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] |
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] |