summaryrefslogtreecommitdiff
path: root/devel/avr-gcc/files/patch-bug35013
blob: db8e09e616cf0578fc36d056b342391cf83b981d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
--- ./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);