yann@402: --------- snip ------- yann@402: Downloaded from ftp://ftp.linux.org.uk/pub/armlinux/toolchain/src-2.95.3/gcc-2.95.3.diff.bz2 yann@402: Not sure what it fixes, but this appears to be The Patch used with gcc-2.95.3 on arm. yann@402: --------- snip ------- yann@402: yann@402: diff -urN gcc-2.95.3-orig/gcc/config/arm/arm.c gcc-2.95.3/gcc/config/arm/arm.c yann@402: --- gcc-2.95.3-orig/gcc/config/arm/arm.c Thu Jan 25 15:03:24 2001 yann@402: +++ gcc-2.95.3/gcc/config/arm/arm.c Fri Jul 20 19:39:11 2001 yann@402: @@ -1529,27 +1529,34 @@ yann@402: return gen_rtx_PLUS (Pmode, base, offset); yann@402: } yann@402: else if (GET_CODE (orig) == LABEL_REF) yann@402: - current_function_uses_pic_offset_table = 1; yann@402: - yann@402: - return orig; yann@402: -} yann@402: + { yann@402: + current_function_uses_pic_offset_table = 1; yann@402: yann@402: -static rtx pic_rtx; yann@402: + if (NEED_PLT_GOT) yann@402: + { yann@402: + rtx pic_ref, address = gen_reg_rtx (Pmode); yann@402: + yann@402: + emit_insn (gen_pic_load_addr (address, orig)); yann@402: + pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, yann@402: + address); yann@402: + emit_move_insn (address, pic_ref); yann@402: + return address; yann@402: + } yann@402: + } yann@402: yann@402: -int yann@402: -is_pic(x) yann@402: - rtx x; yann@402: -{ yann@402: - if (x == pic_rtx) yann@402: - return 1; yann@402: - return 0; yann@402: + return orig; yann@402: } yann@402: yann@402: +/* Generate code to load the PIC register. PROLOGUE is true if yann@402: + called from arm_expand_prologue (in which case we want the yann@402: + generated insns at the start of the function); false if called yann@402: + by an exception receiver that needs the PIC register reloaded yann@402: + (in which case the insns are just dumped at the current location). */ yann@402: void yann@402: -arm_finalize_pic () yann@402: +arm_finalize_pic (int prologue) yann@402: { yann@402: #ifndef AOF_ASSEMBLER yann@402: - rtx l1, pic_tmp, pic_tmp2, seq; yann@402: + rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx; yann@402: rtx global_offset_table; yann@402: yann@402: if (current_function_uses_pic_offset_table == 0) yann@402: @@ -1578,7 +1585,10 @@ yann@402: yann@402: seq = gen_sequence (); yann@402: end_sequence (); yann@402: - emit_insn_after (seq, get_insns ()); yann@402: + if (prologue) yann@402: + emit_insn_after (seq, get_insns ()); yann@402: + else yann@402: + emit_insn (seq); yann@402: yann@402: /* Need to emit this whether or not we obey regdecls, yann@402: since setjmp/longjmp can cause life info to screw up. */ yann@402: @@ -5327,7 +5337,13 @@ yann@402: if (frame_pointer_needed) yann@402: live_regs += 4; yann@402: yann@402: - if (live_regs) yann@402: + if (live_regs == 1 && regs_ever_live[LR_REGNUM] yann@402: + && ! lr_save_eliminated && ! really_return) yann@402: + { yann@402: + output_asm_insn (reverse ? "ldr%?%D0\t%|lr, [%|sp}, #4" yann@402: + : "ldr%?%d0\t%|lr, [%|sp], #4", &operand); yann@402: + } yann@402: + else if (live_regs) yann@402: { yann@402: if (lr_save_eliminated || ! regs_ever_live[14]) yann@402: live_regs++; yann@402: @@ -5446,7 +5462,7 @@ yann@402: rtx x; yann@402: yann@402: length = strlen (name); yann@402: - alignlength = (length + 1) + 3 & ~3; yann@402: + alignlength = ((length + 1) + 3) & ~3; yann@402: yann@402: ASM_OUTPUT_ASCII (stream, name, length + 1); yann@402: ASM_OUTPUT_ALIGN (stream, 2); yann@402: @@ -5838,6 +5854,9 @@ yann@402: int store_arg_regs = 0; yann@402: int volatile_func = (optimize > 0 yann@402: && TREE_THIS_VOLATILE (current_function_decl)); yann@402: + rtx ip_rtx; yann@402: + int fp_offset = 0; yann@402: + rtx insn; yann@402: yann@402: /* Naked functions don't have prologues. */ yann@402: if (arm_naked_function_p (current_function_decl)) yann@402: @@ -5859,11 +5878,59 @@ yann@402: live_regs_mask |= 0x4000; yann@402: } yann@402: yann@402: + ip_rtx = gen_rtx_REG (SImode, IP_REGNUM); yann@402: + yann@402: if (frame_pointer_needed) yann@402: { yann@402: + if (current_function_needs_context) yann@402: + { yann@402: + /* The Static chain register is the same as the IP register yann@402: + used as a scratch register during stack frame creation. yann@402: + To get around this need to find somewhere to store IP yann@402: + whilst the frame is being created. We try the following yann@402: + places in order: yann@402: + yann@402: + 1. An unused argument register. yann@402: + 2. A slot on the stack above the frame. (This only yann@402: + works if the function is not a varargs function). yann@402: + yann@402: + If neither of these places is available, we abort (for now). */ yann@402: + if (regs_ever_live[3] == 0) yann@402: + { yann@402: + insn = gen_rtx_REG (SImode, 3); yann@402: + insn = gen_rtx_SET (SImode, insn, ip_rtx); yann@402: + insn = emit_insn (insn); yann@402: + RTX_FRAME_RELATED_P (insn) = 1; yann@402: + } yann@402: + else if (current_function_pretend_args_size == 0) yann@402: + { yann@402: + insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx); yann@402: + insn = gen_rtx_MEM (SImode, insn); yann@402: + insn = gen_rtx_SET (VOIDmode, insn, ip_rtx); yann@402: + insn = emit_insn (insn); yann@402: + RTX_FRAME_RELATED_P (insn) = 1; yann@402: + fp_offset = 4; yann@402: + } yann@402: + else yann@402: + /* FIXME - the way to handle this situation is to allow yann@402: + the pretend args to be dumped onto the stack, then yann@402: + reuse r3 to save IP. This would involve moving the yann@402: + copying os SP into IP until after the pretend args yann@402: + have been dumped, but this is not too hard. */ yann@402: + error ("Unable to find a temporary location for static chanin register"); yann@402: + } yann@402: + yann@402: live_regs_mask |= 0xD800; yann@402: - emit_insn (gen_movsi (gen_rtx_REG (SImode, 12), yann@402: - stack_pointer_rtx)); yann@402: + if (fp_offset) yann@402: + { yann@402: + insn = gen_rtx_PLUS (SImode, stack_pointer_rtx, GEN_INT (fp_offset)); yann@402: + insn = gen_rtx_SET (SImode, ip_rtx, insn); yann@402: + } yann@402: + else yann@402: + insn = gen_movsi (ip_rtx, stack_pointer_rtx); yann@402: + yann@402: + insn = emit_insn (insn); yann@402: + RTX_FRAME_RELATED_P (insn) = 1; yann@402: } yann@402: yann@402: if (current_function_pretend_args_size) yann@402: @@ -5927,9 +5994,31 @@ yann@402: } yann@402: yann@402: if (frame_pointer_needed) yann@402: - emit_insn (gen_addsi3 (hard_frame_pointer_rtx, gen_rtx_REG (SImode, 12), yann@402: - (GEN_INT yann@402: - (-(4 + current_function_pretend_args_size))))); yann@402: + { yann@402: + insn = GEN_INT (-(4 + current_function_pretend_args_size + fp_offset)); yann@402: + insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ip_rtx, insn)); yann@402: + RTX_FRAME_RELATED_P (insn) = 1; yann@402: + yann@402: + if (current_function_needs_context) yann@402: + { yann@402: + /* Recover the static chain register. */ yann@402: + if (regs_ever_live [3] == 0) yann@402: + { yann@402: + insn = gen_rtx_REG (SImode, 3); yann@402: + insn = gen_rtx_SET (SImode, ip_rtx, insn); yann@402: + insn = emit_insn (insn); yann@402: + RTX_FRAME_RELATED_P (insn) = 1; yann@402: + } yann@402: + else /* if (current_function_pretend_args_size == 0) */ yann@402: + { yann@402: + insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx, GEN_INT (4)); yann@402: + insn = gen_rtx_MEM (SImode, insn); yann@402: + insn = gen_rtx_SET (SImode, ip_rtx, insn); yann@402: + insn = emit_insn (insn); yann@402: + RTX_FRAME_RELATED_P (insn) = 1; yann@402: + } yann@402: + } yann@402: + } yann@402: yann@402: if (amount != const0_rtx) yann@402: { yann@402: diff -urN gcc-2.95.3-orig/gcc/config/arm/arm.h gcc-2.95.3/gcc/config/arm/arm.h yann@402: --- gcc-2.95.3-orig/gcc/config/arm/arm.h Thu Jan 25 15:03:26 2001 yann@402: +++ gcc-2.95.3/gcc/config/arm/arm.h Fri Jul 20 19:39:11 2001 yann@402: @@ -601,14 +601,20 @@ yann@402: (TREE_CODE (EXP) == STRING_CST \ yann@402: && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) yann@402: yann@402: +#ifndef STRUCTURE_SIZE_BOUNDARY yann@402: /* Every structures size must be a multiple of 32 bits. */ yann@402: /* This is for compatibility with ARMCC. ARM SDT Reference Manual yann@402: (ARM DUI 0020D) page 2-20 says "Structures are aligned on word yann@402: boundaries". */ yann@402: -#ifndef STRUCTURE_SIZE_BOUNDARY yann@402: -#define STRUCTURE_SIZE_BOUNDARY 32 yann@402: +/* Setting this to 32 produces more efficient code, but the value set in previous yann@402: + versions of this toolchain was 8, which produces more compact structures. The yann@402: + command line option -mstructure_size_boundary= can be used to change this yann@402: + value. */ yann@402: +#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary yann@402: #endif yann@402: yann@402: +extern int arm_structure_size_boundary; yann@402: + yann@402: /* Used when parsing command line option -mstructure_size_boundary. */ yann@402: extern const char * structure_size_string; yann@402: yann@402: @@ -768,6 +774,9 @@ yann@402: /* Specify the registers used for certain standard purposes. yann@402: The values of these macros are register numbers. */ yann@402: yann@402: +/* Register which holds return address from a subroutine call. */ yann@402: +#define LR_REGNUM 14 yann@402: + yann@402: /* Define this if the program counter is overloaded on a register. */ yann@402: #define PC_REGNUM 15 yann@402: yann@402: @@ -777,6 +786,9 @@ yann@402: /* Base register for access to local variables of the function. */ yann@402: #define FRAME_POINTER_REGNUM 25 yann@402: yann@402: +/* Scratch register - used in all kinds of places, eg trampolines. */ yann@402: +#define IP_REGNUM 12 yann@402: + yann@402: /* Define this to be where the real frame pointer is if it is not possible to yann@402: work out the offset between the frame pointer and the automatic variables yann@402: until after register allocation has taken place. FRAME_POINTER_REGNUM yann@402: @@ -798,7 +810,7 @@ yann@402: /* The native (Norcroft) Pascal compiler for the ARM passes the static chain yann@402: as an invisible last argument (possible since varargs don't exist in yann@402: Pascal), so the following is not true. */ yann@402: -#define STATIC_CHAIN_REGNUM 8 yann@402: +#define STATIC_CHAIN_REGNUM 12 yann@402: yann@402: /* Register in which address to store a structure value yann@402: is passed to a function. */ yann@402: @@ -1248,7 +1260,12 @@ yann@402: { \ yann@402: int volatile_func = arm_volatile_func (); \ yann@402: if ((FROM) == ARG_POINTER_REGNUM && (TO) == HARD_FRAME_POINTER_REGNUM)\ yann@402: - (OFFSET) = 0; \ yann@402: + { \ yann@402: + if (! current_function_needs_context || ! frame_pointer_needed) \ yann@402: + (OFFSET) = 0; \ yann@402: + else \ yann@402: + (OFFSET) = 4; \ yann@402: + } \ yann@402: else if ((FROM) == FRAME_POINTER_REGNUM \ yann@402: && (TO) == STACK_POINTER_REGNUM) \ yann@402: (OFFSET) = (current_function_outgoing_args_size \ yann@402: @@ -1379,8 +1396,10 @@ yann@402: yann@402: On the ARM, allow any integer (invalid ones are removed later by insn yann@402: patterns), nice doubles and symbol_refs which refer to the function's yann@402: - constant pool XXX. */ yann@402: -#define LEGITIMATE_CONSTANT_P(X) (! label_mentioned_p (X)) yann@402: + constant pool XXX. yann@402: + yann@402: + When generating PIC code, allow anything. */ yann@402: +#define LEGITIMATE_CONSTANT_P(X) (flag_pic || ! label_mentioned_p (X)) yann@402: yann@402: /* Symbols in the text segment can be accessed without indirecting via the yann@402: constant pool; it may take an extra binary operation, but this is still yann@402: @@ -1496,9 +1515,8 @@ yann@402: && INTVAL (op) <= 31) \ yann@402: goto LABEL; \ yann@402: } \ yann@402: - /* NASTY: Since this limits the addressing of unsigned byte loads */ \ yann@402: range = ((MODE) == HImode || (MODE) == QImode) \ yann@402: - ? (arm_arch4 ? 256 : 4095) : 4096; \ yann@402: + ? (((MODE) == HImode && arm_arch4) ? 256 : 4095) : 4096; \ yann@402: if (code == CONST_INT && INTVAL (INDEX) < range \ yann@402: && INTVAL (INDEX) > -range) \ yann@402: goto LABEL; \ yann@402: @@ -1812,14 +1830,15 @@ yann@402: data addresses in memory. */ yann@402: #define PIC_OFFSET_TABLE_REGNUM arm_pic_register yann@402: yann@402: -#define FINALIZE_PIC arm_finalize_pic () yann@402: +#define FINALIZE_PIC arm_finalize_pic (1) yann@402: yann@402: -/* We can't directly access anything that contains a symbol, yann@402: +/* We can't directly access anything that contains a symbol or label, yann@402: nor can we indirect via the constant pool. */ yann@402: #define LEGITIMATE_PIC_OPERAND_P(X) \ yann@402: - (! symbol_mentioned_p (X) \ yann@402: + (! symbol_mentioned_p (X) && ! label_mentioned_p (X) \ yann@402: && (! CONSTANT_POOL_ADDRESS_P (X) \ yann@402: - || ! symbol_mentioned_p (get_pool_constant (X)))) yann@402: + || (! symbol_mentioned_p (get_pool_constant (X))) \ yann@402: + && (! label_mentioned_p (get_pool_constant (X))))) yann@402: yann@402: /* We need to know when we are making a constant pool; this determines yann@402: whether data needs to be in the GOT or can be referenced via a GOT yann@402: @@ -2046,17 +2065,9 @@ yann@402: else output_addr_const(STREAM, X); \ yann@402: } yann@402: yann@402: -/* Handles PIC addr specially */ yann@402: #define OUTPUT_INT_ADDR_CONST(STREAM,X) \ yann@402: { \ yann@402: - if (flag_pic && GET_CODE(X) == CONST && is_pic(X)) \ yann@402: - { \ yann@402: - output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 0), 0)); \ yann@402: - fputs(" - (", STREAM); \ yann@402: - output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 1), 0)); \ yann@402: - fputs(")", STREAM); \ yann@402: - } \ yann@402: - else output_addr_const(STREAM, X); \ yann@402: + output_addr_const(STREAM, X); \ yann@402: \ yann@402: /* Mark symbols as position independent. We only do this in the \ yann@402: .text segment, not in the .data segment. */ \ yann@402: @@ -2170,8 +2181,7 @@ yann@402: int arm_return_in_memory PROTO ((Tree)); yann@402: int legitimate_pic_operand_p PROTO ((Rtx)); yann@402: Rtx legitimize_pic_address PROTO ((Rtx, Mmode, Rtx)); yann@402: -int is_pic PROTO ((Rtx)); yann@402: -void arm_finalize_pic PROTO ((void)); yann@402: +void arm_finalize_pic PROTO ((int)); yann@402: int arm_rtx_costs RTX_CODE_PROTO ((Rtx, Rcode)); yann@402: int arm_adjust_cost PROTO ((Rtx, Rtx, Rtx, int)); yann@402: int const_double_rtx_ok_for_fpu PROTO ((Rtx)); yann@402: diff -urN gcc-2.95.3-orig/gcc/config/arm/arm.md gcc-2.95.3/gcc/config/arm/arm.md yann@402: --- gcc-2.95.3-orig/gcc/config/arm/arm.md Thu Jan 25 15:03:27 2001 yann@402: +++ gcc-2.95.3/gcc/config/arm/arm.md Fri Jul 20 19:39:11 2001 yann@402: @@ -2629,7 +2629,8 @@ yann@402: : preserve_subexpressions_p ())); yann@402: DONE; yann@402: } yann@402: - if (CONSTANT_P (operands[1]) && flag_pic) yann@402: + if ((CONSTANT_P (operands[1]) || symbol_mentioned_p (operands[1]) yann@402: + || label_mentioned_p (operands[1])) && flag_pic) yann@402: operands[1] = legitimize_pic_address (operands[1], SImode, yann@402: ((reload_in_progress yann@402: || reload_completed) yann@402: @@ -2721,6 +2722,15 @@ yann@402: return \"add%?\\t%0, %|pc, %0\"; yann@402: ") yann@402: yann@402: +(define_expand "builtin_setjmp_receiver" yann@402: + [(label_ref (match_operand 0 "" ""))] yann@402: + "flag_pic" yann@402: + " yann@402: +{ yann@402: + arm_finalize_pic (0); yann@402: + DONE; yann@402: +}") yann@402: + yann@402: ;; If copying one reg to another we can set the condition codes according to yann@402: ;; its value. Such a move is common after a return from subroutine and the yann@402: ;; result is being tested against zero. yann@402: @@ -6184,15 +6194,20 @@ yann@402: abort (); yann@402: return \"\"; yann@402: } yann@402: - strcpy (pattern, \"stmfd\\t%m0!, {%1\"); yann@402: - for (i = 1; i < XVECLEN (operands[2], 0); i++) yann@402: + if (XVECLEN (operands[2], 0) > 1) yann@402: { yann@402: - strcat (pattern, \", %|\"); yann@402: - strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), yann@402: + strcpy (pattern, \"stmfd\\t%m0!, {%1\"); yann@402: + for (i = 1; i < XVECLEN (operands[2], 0); i++) yann@402: + { yann@402: + strcat (pattern, \", %|\"); yann@402: + strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), yann@402: 0))]); yann@402: + } yann@402: + strcat (pattern, \"}\"); yann@402: + output_asm_insn (pattern, operands); yann@402: } yann@402: - strcat (pattern, \"}\"); yann@402: - output_asm_insn (pattern, operands); yann@402: + else yann@402: + output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands); yann@402: return \"\"; yann@402: }" yann@402: [(set_attr "type" "store4")]) yann@402: diff -urN gcc-2.95.3-orig/gcc/config/arm/elf.h gcc-2.95.3/gcc/config/arm/elf.h yann@402: --- gcc-2.95.3-orig/gcc/config/arm/elf.h Mon May 31 10:21:53 1999 yann@402: +++ gcc-2.95.3/gcc/config/arm/elf.h Fri Jul 20 19:39:11 2001 yann@402: @@ -167,15 +167,6 @@ yann@402: #define MULTILIB_DEFAULTS { "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork" } yann@402: #endif yann@402: yann@402: -/* Setting this to 32 produces more efficient code, but the value set in previous yann@402: - versions of this toolchain was 8, which produces more compact structures. The yann@402: - command line option -mstructure_size_boundary= can be used to change this yann@402: - value. */ yann@402: -#undef STRUCTURE_SIZE_BOUNDARY yann@402: -#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary yann@402: - yann@402: -extern int arm_structure_size_boundary; yann@402: - yann@402: /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS yann@402: is a valid machine specific attribute for DECL. yann@402: The attributes in ATTRIBUTES have previously been assigned to DECL. */ yann@402: diff -urN gcc-2.95.3-orig/gcc/config/arm/linux-gas.h gcc-2.95.3/gcc/config/arm/linux-gas.h yann@402: --- gcc-2.95.3-orig/gcc/config/arm/linux-gas.h Mon Feb 22 17:47:57 1999 yann@402: +++ gcc-2.95.3/gcc/config/arm/linux-gas.h Fri Jul 20 19:39:11 2001 yann@402: @@ -1,6 +1,6 @@ yann@402: /* Definitions of target machine for GNU compiler. yann@402: ARM Linux-based GNU systems version. yann@402: - Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. yann@402: + Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. yann@402: Contributed by Russell King . yann@402: yann@402: This file is part of GNU CC. yann@402: @@ -79,5 +79,7 @@ yann@402: register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \ yann@402: register unsigned long _end __asm ("a2") = (unsigned long) (END); \ yann@402: register unsigned long _flg __asm ("a3") = 0; \ yann@402: - __asm __volatile ("swi 0x9f0002"); \ yann@402: + __asm __volatile ("swi 0x9f0002 @ sys_cacheflush" \ yann@402: + : "=r" (_beg) \ yann@402: + : "0" (_beg), "r" (_end), "r" (_flg)); \ yann@402: } yann@402: diff -urN gcc-2.95.3-orig/gcc/config/arm/t-linux gcc-2.95.3/gcc/config/arm/t-linux yann@402: --- gcc-2.95.3-orig/gcc/config/arm/t-linux Fri Mar 26 16:30:20 1999 yann@402: +++ gcc-2.95.3/gcc/config/arm/t-linux Fri Jul 20 20:46:19 2001 yann@402: @@ -1,6 +1,6 @@ yann@402: # Just for these, we omit the frame pointer since it makes such a big yann@402: # difference. It is then pointless adding debugging. yann@402: -TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC yann@402: +TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC yann@402: LIBGCC2_DEBUG_CFLAGS = -g0 yann@402: yann@402: # Don't build enquire yann@402: diff -urN gcc-2.95.3-orig/gcc/final.c gcc-2.95.3/gcc/final.c yann@402: --- gcc-2.95.3-orig/gcc/final.c Mon Mar 12 13:07:59 2001 yann@402: +++ gcc-2.95.3/gcc/final.c Fri Jul 20 19:39:11 2001 yann@402: @@ -3652,8 +3652,9 @@ yann@402: yann@402: output_addr_const (file, XEXP (x, 0)); yann@402: fprintf (file, "-"); yann@402: - if (GET_CODE (XEXP (x, 1)) == CONST_INT yann@402: - && INTVAL (XEXP (x, 1)) < 0) yann@402: + if ((GET_CODE (XEXP (x, 1)) == CONST_INT yann@402: + && INTVAL (XEXP (x, 1)) < 0) yann@402: + || GET_CODE (XEXP (x, 1)) != CONST_INT) yann@402: { yann@402: fprintf (file, ASM_OPEN_PAREN); yann@402: output_addr_const (file, XEXP (x, 1)); yann@402: diff -urN gcc-2.95.3-orig/gcc/function.c gcc-2.95.3/gcc/function.c yann@402: --- gcc-2.95.3-orig/gcc/function.c Thu Jan 25 15:03:15 2001 yann@402: +++ gcc-2.95.3/gcc/function.c Fri Jul 20 19:39:10 2001 yann@402: @@ -3053,6 +3053,105 @@ yann@402: extracted by usage MEM with narrower mode. */ yann@402: static rtx purge_addressof_replacements; yann@402: yann@402: +/* Return 1 if X and Y are identical-looking rtx's. yann@402: + This is the Lisp function EQUAL for rtx arguments. */ yann@402: + yann@402: +int yann@402: +rtx_equal_for_addressof_p (x, y) yann@402: + rtx x, y; yann@402: +{ yann@402: + register int i; yann@402: + register int j; yann@402: + register enum rtx_code code; yann@402: + register char *fmt; yann@402: + yann@402: + if (x == y) yann@402: + return 1; yann@402: + if (x == 0 || y == 0) yann@402: + return 0; yann@402: + yann@402: + code = GET_CODE (x); yann@402: + /* Rtx's of different codes cannot be equal. */ yann@402: + if (code != GET_CODE (y)) yann@402: + return 0; yann@402: + yann@402: + /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. yann@402: + (REG:SI x) and (REG:HI x) are NOT equivalent. yann@402: + But (MEM:SI x) and (MEM:HI x) are equivalent for our purposes. */ yann@402: + yann@402: + if (code != MEM && (GET_MODE (x) != GET_MODE (y))) yann@402: + return 0; yann@402: + yann@402: + /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ yann@402: + yann@402: + if (code == REG) yann@402: + return REGNO (x) == REGNO (y); yann@402: + else if (code == LABEL_REF) yann@402: + return XEXP (x, 0) == XEXP (y, 0); yann@402: + else if (code == SYMBOL_REF) yann@402: + return XSTR (x, 0) == XSTR (y, 0); yann@402: + else if (code == SCRATCH || code == CONST_DOUBLE) yann@402: + return 0; yann@402: + yann@402: + /* Compare the elements. If any pair of corresponding elements yann@402: + fail to match, return 0 for the whole things. */ yann@402: + yann@402: + fmt = GET_RTX_FORMAT (code); yann@402: + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) yann@402: + { yann@402: + switch (fmt[i]) yann@402: + { yann@402: + case 'w': yann@402: + if (XWINT (x, i) != XWINT (y, i)) yann@402: + return 0; yann@402: + break; yann@402: + yann@402: + case 'n': yann@402: + case 'i': yann@402: + if (XINT (x, i) != XINT (y, i)) yann@402: + return 0; yann@402: + break; yann@402: + yann@402: + case 'V': yann@402: + case 'E': yann@402: + /* Two vectors must have the same length. */ yann@402: + if (XVECLEN (x, i) != XVECLEN (y, i)) yann@402: + return 0; yann@402: + yann@402: + /* And the corresponding elements must match. */ yann@402: + for (j = 0; j < XVECLEN (x, i); j++) yann@402: + if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) yann@402: + return 0; yann@402: + break; yann@402: + yann@402: + case 'e': yann@402: + if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0) yann@402: + return 0; yann@402: + break; yann@402: + yann@402: + case 'S': yann@402: + case 's': yann@402: + if (strcmp (XSTR (x, i), XSTR (y, i))) yann@402: + return 0; yann@402: + break; yann@402: + yann@402: + case 'u': yann@402: + /* These are just backpointers, so they don't matter. */ yann@402: + break; yann@402: + yann@402: + case '0': yann@402: + break; yann@402: + yann@402: + /* It is believed that rtx's at this level will never yann@402: + contain anything but integers and other rtx's, yann@402: + except for within LABEL_REFs and SYMBOL_REFs. */ yann@402: + default: yann@402: + abort (); yann@402: + } yann@402: + } yann@402: + return 1; yann@402: +} yann@402: + yann@402: /* Helper function for purge_addressof. See if the rtx expression at *LOC yann@402: in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into yann@402: the stack. */ yann@402: @@ -3133,7 +3232,7 @@ yann@402: for (tem = purge_bitfield_addressof_replacements; yann@402: tem != NULL_RTX; yann@402: tem = XEXP (XEXP (tem, 1), 1)) yann@402: - if (rtx_equal_p (x, XEXP (tem, 0))) yann@402: + if (rtx_equal_for_addressof_p (x, XEXP (tem, 0))) yann@402: { yann@402: *loc = XEXP (XEXP (tem, 1), 0); yann@402: return; yann@402: @@ -3143,7 +3242,7 @@ yann@402: for (tem = purge_addressof_replacements; yann@402: tem != NULL_RTX; yann@402: tem = XEXP (XEXP (tem, 1), 1)) yann@402: - if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0))) yann@402: + if (rtx_equal_for_addressof_p (XEXP (x, 0), XEXP (tem, 0))) yann@402: { yann@402: rtx z = XEXP (XEXP (tem, 1), 0); yann@402: yann@402: diff -urN gcc-2.95.3-orig/gcc/jump.c gcc-2.95.3/gcc/jump.c yann@402: --- gcc-2.95.3-orig/gcc/jump.c Thu Oct 21 08:24:03 1999 yann@402: +++ gcc-2.95.3/gcc/jump.c Fri Jul 20 19:39:10 2001 yann@402: @@ -115,7 +115,7 @@ yann@402: static rtx delete_unreferenced_labels PROTO((rtx)); yann@402: static void delete_noop_moves PROTO((rtx)); yann@402: static int calculate_can_reach_end PROTO((rtx, int, int)); yann@402: -static int duplicate_loop_exit_test PROTO((rtx)); yann@402: +static int duplicate_loop_exit_test PROTO((rtx, int)); yann@402: static void find_cross_jump PROTO((rtx, rtx, int, rtx *, rtx *)); yann@402: static void do_cross_jump PROTO((rtx, rtx, rtx)); yann@402: static int jump_back_p PROTO((rtx, rtx)); yann@402: @@ -338,7 +338,7 @@ yann@402: && simplejump_p (temp1)) yann@402: { yann@402: temp = PREV_INSN (insn); yann@402: - if (duplicate_loop_exit_test (insn)) yann@402: + if (duplicate_loop_exit_test (insn, after_regscan)) yann@402: { yann@402: changed = 1; yann@402: next = NEXT_INSN (temp); yann@402: @@ -2548,8 +2548,9 @@ yann@402: values of regno_first_uid and regno_last_uid. */ yann@402: yann@402: static int yann@402: -duplicate_loop_exit_test (loop_start) yann@402: +duplicate_loop_exit_test (loop_start, after_regscan) yann@402: rtx loop_start; yann@402: + int after_regscan; yann@402: { yann@402: rtx insn, set, reg, p, link; yann@402: rtx copy = 0, first_copy = 0; yann@402: @@ -2662,6 +2663,9 @@ yann@402: reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg)); yann@402: } yann@402: } yann@402: + yann@402: + if (after_regscan) yann@402: + reg_scan_update (exitcode, lastexit, max_reg); yann@402: yann@402: /* Now copy each insn. */ yann@402: for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn)) yann@402: diff -urN gcc-2.95.3-orig/gcc/varasm.c gcc-2.95.3/gcc/varasm.c yann@402: --- gcc-2.95.3-orig/gcc/varasm.c Mon Feb 19 15:02:02 2001 yann@402: +++ gcc-2.95.3/gcc/varasm.c Fri Jul 20 19:39:11 2001 yann@402: @@ -3286,7 +3286,10 @@ yann@402: value->un.addr.offset = - INTVAL (XEXP (x, 1)); yann@402: } yann@402: else yann@402: - abort (); yann@402: + { yann@402: + value->un.addr.base = x; yann@402: + value->un.addr.offset = 0; yann@402: + } yann@402: break; yann@402: yann@402: default: