--- ./gcc/config/avr/avr-protos.h.orig 2010-03-05 15:20:53.000000000 +0100 +++ ./gcc/config/avr/avr-protos.h 2010-03-05 15:24:52.000000000 +0100 @@ -114,6 +114,7 @@ extern int _reg_unused_after (rtx insn, rtx reg); extern int avr_jump_mode (rtx x, rtx insn); extern int byte_immediate_operand (rtx op, enum machine_mode mode); +extern int text_segment_operand (rtx op, enum machine_mode mode); extern int test_hard_reg_class (enum reg_class class, rtx x); extern int jump_over_one_insn_p (rtx insn, rtx dest); --- ./gcc/config/avr/avr.c.orig 2010-03-05 15:22:53.000000000 +0100 +++ ./gcc/config/avr/avr.c 2010-03-05 15:24:52.000000000 +0100 @@ -1136,8 +1136,7 @@ default: if (CONSTANT_ADDRESS_P (addr) - && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr)) - || GET_CODE (addr) == LABEL_REF)) + && text_segment_operand (addr, VOIDmode)) { fprintf (file, "gs("); output_addr_const (file,addr); @@ -1453,6 +1452,26 @@ && INTVAL (op) <= 0xff && INTVAL (op) >= 0); } +/* Return true if OP is a program memory reference.*/ +int +text_segment_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) +{ + switch (GET_CODE (op)) + { + case LABEL_REF : + return true; + case SYMBOL_REF : + return SYMBOL_REF_FUNCTION_P (op); + case PLUS : + /* Assume canonical format of symbol + constant. + Fall through. */ + case CONST : + return text_segment_operand (XEXP (op, 0), VOIDmode); + default : + return false; + } +} + /* Output all insn addresses and their sizes into the assembly language output file. This is helpful for debugging whether the length attributes in the md file are correct. @@ -4490,8 +4509,7 @@ avr_assemble_integer (rtx x, unsigned int size, int aligned_p) { if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p - && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x)) - || GET_CODE (x) == LABEL_REF)) + && text_segment_operand (x, VOIDmode) ) { fputs ("\t.word\tgs(", asm_out_file); output_addr_const (asm_out_file, x);