I think I have found a simple fix.
I changed gcc so that offsets added to assembler symbols are doubled. So
in c when we use &foo+2 this gets send to assembler/linker as gs(foo+4).
This has the effect that offsets or arithmetic are consistently in words
- on a word pointer. (which makes more sense)
Now it does not matter if optimisation creates p=&foo+2 OR p=&foo,
p=p+2 as the result will be the same.
I attach test program I used to check several variant and it worked.
Apart from normal warning messages about linker stubs. There also lst
and lss files you can look at what gets send to assembler and code
produced.
I've attached patch - but have not checked for elegance!
See if this breaks!
Andy
------------------------------------------------------------------------
1 .file "bug27192.c"
2 __SREG__ = 0x3f
3 __SP_H__ = 0x3e
4 __SP_L__ = 0x3d
5 __tmp_reg__ = 0
6 __zero_reg__ = 1
7 .global __do_copy_data
8 .global __do_clear_bss
16 .Ltext0:
17 .global putchar_exit_c
19 putchar_exit_c:
20 .LFB3:
21 .LM1:
22 .LVL0:
23 /* prologue: function */
24 /* frame size = 0 */
25 .LM2:
26 0000 82BF out 82-0x20,r24
27 .LM3:
28 0002 80E0 ldi r24,lo8(0)
29 0004 90E0 ldi r25,hi8(0)
30 .LVL1:
31 /* epilogue start */
32 0006 0895 ret
33 .LFE3:
35 .section .init8,"ax",@progbits
36 .global init_exit_c
38 init_exit_c:
39 .LFB4:
40 .LSM0:
41 /* prologue: naked */
42 /* frame size = 0 */
43 .LSM1:
44 0000 80E0 ldi r24,lo8(gs(putchar_exit_c))
45 0002 90E0 ldi r25,hi8(gs(putchar_exit_c))
46 0004 9093 0000 sts (file_exit_c+8)+1,r25
47 0008 8093 0000 sts file_exit_c+8,r24
48 .LSM2:
49 000c 1092 0000 sts (file_exit_c+10)+1,__zero_reg__
50 0010 1092 0000 sts file_exit_c+10,__zero_reg__
51 .LSM3:
52 0014 82E0 ldi r24,lo8(2)
53 0016 8093 0000 sts file_exit_c+3,r24
54 .LSM4:
55 001a 1092 0000 sts (file_exit_c+12)+1,__zero_reg__
56 001e 1092 0000 sts file_exit_c+12,__zero_reg__
57 .LSM5:
58 0022 80E0 ldi r24,lo8(file_exit_c)
59 0024 90E0 ldi r25,hi8(file_exit_c)
60 0026 9093 0000 sts (__iob+2)+1,r25
61 002a 8093 0000 sts __iob+2,r24
62 002e 9093 0000 sts (__iob+4)+1,r25
63 0032 8093 0000 sts __iob+4,r24
64 /* epilogue start */
65 .LSM6:
66 .LFE4:
68 .text
69 .global exit
71 exit:
72 .LFB5:
73 .LM4:
74 .LVL2:
75 /* prologue: naked */
76 /* frame size = 0 */
77 .LM5:
78 0008 8FBD out 79-0x20,r24
79 /* epilogue start */
80 .LM6:
81 .LFE5:
83 .global abort
85 abort:
86 .LFB6:
87 .LM7:
88 /* prologue: naked */
89 /* frame size = 0 */
90 .LM8:
91 000a 81E0 ldi r24,lo8(1)
92 000c 89BD out 73-0x20,r24
93 /* epilogue start */
94 .LM9:
95 .LFE6:
97 .global bar
99 bar:
100 .LFB7:
101 .LM10:
102 /* prologue: function */
103 /* frame size = 0 */
104 .LM11:
105 /* #APP */
106 ; 62 "bug27192.c" 1
107 000e 0000 nop
108 ; 0 "" 2
109 .LM12:
110 ; 63 "bug27192.c" 1
111 0010 0000 nop
112 ; 0 "" 2
113 .LM13:
114 ; 64 "bug27192.c" 1
115 0012 0000 nop
116 ; 0 "" 2
117 .LM14:
118 ; 65 "bug27192.c" 1
119 0014 0000 nop
120 ; 0 "" 2
121 .LM15:
122 ; 66 "bug27192.c" 1
123 0016 0000 nop
124 ; 0 "" 2
125 /* epilogue start */
126 .LM16:
127 /* #NOAPP */
128 0018 0895 ret
129 .LFE7:
131 .global init
133 init:
134 .LFB8:
135 .LM17:
136 /* prologue: function */
137 /* frame size = 0 */
138 .LM18:
139 001a 80E0 ldi r24,lo8(gs(bar))
140 001c 90E0 ldi r25,hi8(gs(bar))
141 /* epilogue start */
142 001e 0895 ret
143 .LFE8:
145 .global test1
147 test1:
148 .LFB9:
149 .LM19:
150 /* prologue: function */
151 /* frame size = 0 */
152 .LM20:
153 0020 20E0 ldi r18,lo8(gs(bar+4))
154 0022 30E0 ldi r19,hi8(gs(bar+4))
155 0024 3093 0000 sts (c)+1,r19
156 0028 2093 0000 sts c,r18
157 .LM21:
158 002c C901 movw r24,r18
159 /* epilogue start */
160 002e 0895 ret
161 .LFE9:
163 .global test2
165 test2:
166 .LFB10:
167 .LM22:
168 /* prologue: function */
169 /* frame size = 0 */
170 .LM23:
171 0030 20E0 ldi r18,lo8(gs(bar+4))
172 0032 30E0 ldi r19,hi8(gs(bar+4))
173 0034 3093 0000 sts (c+2)+1,r19
174 0038 2093 0000 sts c+2,r18
175 .LM24:
176 003c C901 movw r24,r18
177 /* epilogue start */
178 003e 0895 ret
179 .LFE10:
181 .global test3
183 test3:
184 .LFB11:
185 .LM25:
186 /* prologue: function */
187 /* frame size = 0 */
188 .LM26:
189 0040 20E0 ldi r18,lo8(gs(bar+4))
190 0042 30E0 ldi r19,hi8(gs(bar+4))
191 0044 3093 0000 sts (c+4)+1,r19
192 0048 2093 0000 sts c+4,r18
193 .LM27:
194 004c C901 movw r24,r18
195 /* epilogue start */
196 004e 0895 ret
197 .LFE11:
199 .global test4
201 test4:
202 .LFB12:
203 .LM28:
204 .LVL3:
205 /* prologue: function */
206 /* frame size = 0 */
207 .LM29:
208 0050 9C01 movw r18,r24
209 0052 2050 subi r18,lo8(-(gs(bar)))
**** Warning:expression dangerous with linker stubs
210 0054 3040 sbci r19,hi8(-(gs(bar)))
**** Warning:expression dangerous with linker stubs
211 0056 3093 0000 sts (c+6)+1,r19
212 005a 2093 0000 sts c+6,r18
213 .LM30:
214 005e C901 movw r24,r18
215 .LVL4:
216 /* epilogue start */
217 0060 0895 ret
218 .LFE12:
220 .global test5
222 test5:
223 .LFB13:
224 .LM31:
225 .LVL5:
226 /* prologue: function */
227 /* frame size = 0 */
228 .LM32:
229 0062 9C01 movw r18,r24
230 0064 2050 subi r18,lo8(-(gs(bar+-4)))
**** Warning:expression dangerous with linker stubs
231 0066 3040 sbci r19,hi8(-(gs(bar+-4)))
**** Warning:expression dangerous with linker stubs
232 0068 3093 0000 sts (c+8)+1,r19
233 006c 2093 0000 sts c+8,r18
234 .LM33:
235 0070 C901 movw r24,r18
236 .LVL6:
237 /* epilogue start */
238 0072 0895 ret
239 .LFE13:
241 .global test6
243 test6:
244 .LFB14:
245 .LM34:
246 .LVL7:
247 /* prologue: function */
248 /* frame size = 0 */
249 .LM35:
250 0074 20E0 ldi r18,lo8(gs(bar+8))
251 0076 30E0 ldi r19,hi8(gs(bar+8))
252 0078 281B sub r18,r24
253 007a 390B sbc r19,r25
254 007c 3093 0000 sts (c+10)+1,r19
255 0080 2093 0000 sts c+10,r18
256 .LM36:
257 0084 C901 movw r24,r18
258 .LVL8:
259 /* epilogue start */
260 0086 0895 ret
261 .LFE14:
263 .global main
265 main:
266 .LFB15:
267 .LM37:
268 0088 0F93 push r16
269 008a 1F93 push r17
270 008c CF93 push r28
271 008e DF93 push r29
272 /* prologue: function */
273 /* frame size = 0 */
274 .LM38:
275 0090 0E94 0000 call init
276 0094 8C01 movw r16,r24
277 .LM39:
278 0096 0E94 0000 call test1
279 009a EC01 movw r28,r24
280 009c 0E5F subi r16,lo8(-(2))
281 009e 1F4F sbci r17,hi8(-(2))
282 00a0 8017 cp r24,r16
283 00a2 9107 cpc r25,r17
284 00a4 01F4 brne .L35
285 .LM40:
286 00a6 0E94 0000 call test2
287 00aa C817 cp r28,r24
288 00ac D907 cpc r29,r25
289 00ae 01F4 brne .L35
290 .LM41:
291 00b0 0E94 0000 call test3
292 00b4 C817 cp r28,r24
293 00b6 D907 cpc r29,r25
294 00b8 01F4 brne .L35
295 .LM42:
296 00ba 82E0 ldi r24,lo8(2)
297 00bc 90E0 ldi r25,hi8(2)
298 00be 0E94 0000 call test4
299 00c2 C817 cp r28,r24
300 00c4 D907 cpc r29,r25
301 00c6 01F4 brne .L35
302 .LM43:
303 00c8 84E0 ldi r24,lo8(4)
304 00ca 90E0 ldi r25,hi8(4)
305 00cc 0E94 0000 call test5
306 00d0 C817 cp r28,r24
307 00d2 D907 cpc r29,r25
308 00d4 01F4 brne .L35
309 .LM44:
310 00d6 82E0 ldi r24,lo8(2)
311 00d8 90E0 ldi r25,hi8(2)
312 00da 0E94 0000 call test6
313 00de C817 cp r28,r24
314 00e0 D907 cpc r29,r25
315 00e2 01F0 breq .L31
316 .L35:
317 00e4 0E94 0000 call abort
318 .L31:
319 .LM45:
320 00e8 80E0 ldi r24,lo8(0)
321 00ea 90E0 ldi r25,hi8(0)
322 00ec 0E94 0000 call exit
323 .LFE15:
325 .comm file_exit_c,14,1
326 .comm c,12,1
447 .Letext0:
DEFINED SYMBOLS
*ABS*:00000000 bug27192.c
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:2 *ABS*:0000003f
__SREG__
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:3 *ABS*:0000003e
__SP_H__
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:4 *ABS*:0000003d
__SP_L__
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:5 *ABS*:00000000
__tmp_reg__
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:6 *ABS*:00000001
__zero_reg__
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:19 .text:00000000
putchar_exit_c
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:38 .init8:00000000
init_exit_c
*COM*:0000000e file_exit_c
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:71 .text:00000008 exit
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:85 .text:0000000a abort
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:99 .text:0000000e bar
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:133 .text:0000001a init
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:147 .text:00000020 test1
*COM*:0000000c c
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:165 .text:00000030 test2
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:183 .text:00000040 test3
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:201 .text:00000050 test4
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:222 .text:00000062 test5
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:243 .text:00000074 test6
/cygdrive/c/DOCUME~1/Andy/LOCALS~1/Temp/ccoE6er9.s:265 .text:00000088 main
UNDEFINED SYMBOLS
__do_copy_data
__do_clear_bss
__iob
------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#define STDIO_PORT 0x52
#define EXIT_PORT 0x4F
#define ABORT_PORT 0x49
int putchar_exit_c(char c, FILE *stream)
__attribute__((no_instrument_function));
int putchar_exit_c(char c, FILE *stream)
{
*((volatile unsigned char *) STDIO_PORT) = c;
return 0;
}
FILE file_exit_c;
void init_exit_c(void) __attribute__ ((section (".init8")))
__attribute__((naked)) __attribute__ ((no_instrument_function));
void init_exit_c(void)
{
file_exit_c.put = putchar_exit_c;
file_exit_c.get = NULL;
file_exit_c.flags = _FDEV_SETUP_WRITE;
file_exit_c.udata = 0;
stderr = stdout = &file_exit_c;
}
/* This file simply defines never returning functions exit() and abort() */
void exit(int code) __attribute__ ((naked));
void exit(int code)
{
*((volatile unsigned char *) EXIT_PORT) = code;
}
void abort (void) __attribute__ ((naked));
void abort (void)
{
*((volatile unsigned char *) ABORT_PORT) = 1;
}
/*------------------------------------------------------------------------*/
struct fseqp_void
{
void (* volatile p1) (void);
void (* p2) (void);
char *p3;
void (* p4) (void);
void (* p5) (void);
void (* p6) (void);
};
struct fseqp_void c[1];
void bar(void)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
unsigned int init(void)
{
return (unsigned int) &bar;
}
unsigned int test1(void)
{
return (unsigned int)( c[0].p1 = bar + 2);
}
unsigned int test2(void)
{
return (unsigned int) (c[0].p2 = bar + 2);
}
unsigned int test3(void)
{
return (unsigned int) (c[0].p3 = (char *) bar + 2);
}
unsigned int test4(unsigned int offset)
{
return (unsigned int) (c[0].p4 = bar + offset);
}
unsigned int test5 (unsigned int offset)
{
return (unsigned int) (c[0].p5 = bar - 2 + offset);
}
unsigned int test6 (unsigned int offset)
{
return (unsigned int) (c[0].p6 = bar + 4 - offset);
}
int main (void)
{
/* All version should give word address of foo plus 2 words */
/* which is the third instruction */
unsigned int ptr = init() + 2; /* get foo+2 */
if (test1 () != ptr) abort ();
if (test2 () != ptr) abort ();
if (test3 () != ptr) abort ();
if (test4 (2) != ptr) abort ();
if (test5 (4) != ptr) abort ();
if (test6 (2) != ptr) abort ();
exit(0);
}
------------------------------------------------------------------------
bug27192.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000001f4 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00000020 00800100 000001f4 00000268 2**0
ALLOC
2 .debug_aranges 00000028 00000000 00000000 00000268 2**0
CONTENTS, READONLY, DEBUGGING
3 .debug_pubnames 000000b4 00000000 00000000 00000290 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_info 0000039a 00000000 00000000 00000344 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_abbrev 000001b2 00000000 00000000 000006de 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_line 00000242 00000000 00000000 00000890 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_frame 000000e0 00000000 00000000 00000ad4 2**2
CONTENTS, READONLY, DEBUGGING
8 .debug_str 0000014d 00000000 00000000 00000bb4 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_loc 0000005b 00000000 00000000 00000d01 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_ranges 00000078 00000000 00000000 00000d5c 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 46 00 jmp 0x8c ; 0x8c <__ctors_end>
4: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
8: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
10: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
14: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
18: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
1c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
20: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
24: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
28: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
2c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
30: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
34: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
38: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
3c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
40: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
44: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
48: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
4c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
50: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
54: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
58: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
5c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
60: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
64: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
68: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
6c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
70: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
74: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
78: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
7c: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
80: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
84: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
88: 0c 94 80 00 jmp 0x100 ; 0x100 <__bad_interrupt>
0000008c <__ctors_end>:
8c: 11 24 eor r1, r1
8e: 1f be out 0x3f, r1 ; 63
90: cf ef ldi r28, 0xFF ; 255
92: d0 e1 ldi r29, 0x10 ; 16
94: de bf out 0x3e, r29 ; 62
96: cd bf out 0x3d, r28 ; 61
00000098 <__do_copy_data>:
98: 11 e0 ldi r17, 0x01 ; 1
9a: a0 e0 ldi r26, 0x00 ; 0
9c: b1 e0 ldi r27, 0x01 ; 1
9e: e4 ef ldi r30, 0xF4 ; 244
a0: f1 e0 ldi r31, 0x01 ; 1
a2: 00 e0 ldi r16, 0x00 ; 0
a4: 0b bf out 0x3b, r16 ; 59
a6: 02 c0 rjmp .+4 ; 0xac <__do_copy_data+0x14>
a8: 07 90 elpm r0, Z+
aa: 0d 92 st X+, r0
ac: a0 30 cpi r26, 0x00 ; 0
ae: b1 07 cpc r27, r17
b0: d9 f7 brne .-10 ; 0xa8 <__do_copy_data+0x10>
000000b2 <__do_clear_bss>:
b2: 11 e0 ldi r17, 0x01 ; 1
b4: a0 e0 ldi r26, 0x00 ; 0
b6: b1 e0 ldi r27, 0x01 ; 1
b8: 01 c0 rjmp .+2 ; 0xbc <.do_clear_bss_start>
000000ba <.do_clear_bss_loop>:
ba: 1d 92 st X+, r1
000000bc <.do_clear_bss_start>:
bc: a0 32 cpi r26, 0x20 ; 32
be: b1 07 cpc r27, r17
c0: e1 f7 brne .-8 ; 0xba <.do_clear_bss_loop>
000000c2 <init_exit_c>:
c2: 82 e8 ldi r24, 0x82 ; 130
c4: 90 e0 ldi r25, 0x00 ; 0
c6: 90 93 15 01 sts 0x0115, r25
ca: 80 93 14 01 sts 0x0114, r24
ce: 10 92 17 01 sts 0x0117, r1
d2: 10 92 16 01 sts 0x0116, r1
d6: 82 e0 ldi r24, 0x02 ; 2
d8: 80 93 0f 01 sts 0x010F, r24
dc: 10 92 19 01 sts 0x0119, r1
e0: 10 92 18 01 sts 0x0118, r1
e4: 8c e0 ldi r24, 0x0C ; 12
e6: 91 e0 ldi r25, 0x01 ; 1
e8: 90 93 1d 01 sts 0x011D, r25
ec: 80 93 1c 01 sts 0x011C, r24
f0: 90 93 1f 01 sts 0x011F, r25
f4: 80 93 1e 01 sts 0x011E, r24
f8: 0e 94 c6 00 call 0x18c ; 0x18c <main>
fc: 0c 94 86 00 jmp 0x10c ; 0x10c <exit>
00000100 <__bad_interrupt>:
100: 0c 94 00 00 jmp 0 ; 0x0 <__vectors>
00000104 <putchar_exit_c>:
104: 82 bf out 0x32, r24 ; 50
106: 80 e0 ldi r24, 0x00 ; 0
108: 90 e0 ldi r25, 0x00 ; 0
10a: 08 95 ret
0000010c <exit>:
10c: 8f bd out 0x2f, r24 ; 47
0000010e <abort>:
10e: 81 e0 ldi r24, 0x01 ; 1
110: 89 bd out 0x29, r24 ; 41
00000112 <bar>:
...
11a: 00 00 nop
11c: 08 95 ret
0000011e <init>:
11e: 89 e8 ldi r24, 0x89 ; 137
120: 90 e0 ldi r25, 0x00 ; 0
122: 08 95 ret
00000124 <test1>:
124: 2b e8 ldi r18, 0x8B ; 139
126: 30 e0 ldi r19, 0x00 ; 0
128: 30 93 01 01 sts 0x0101, r19
12c: 20 93 00 01 sts 0x0100, r18
130: c9 01 movw r24, r18
132: 08 95 ret
00000134 <test2>:
134: 2b e8 ldi r18, 0x8B ; 139
136: 30 e0 ldi r19, 0x00 ; 0
138: 30 93 03 01 sts 0x0103, r19
13c: 20 93 02 01 sts 0x0102, r18
140: c9 01 movw r24, r18
142: 08 95 ret
00000144 <test3>:
144: 2b e8 ldi r18, 0x8B ; 139
146: 30 e0 ldi r19, 0x00 ; 0
148: 30 93 05 01 sts 0x0105, r19
14c: 20 93 04 01 sts 0x0104, r18
150: c9 01 movw r24, r18
152: 08 95 ret
00000154 <test4>:
154: 9c 01 movw r18, r24
156: 27 57 subi r18, 0x77 ; 119
158: 3f 4f sbci r19, 0xFF ; 255
15a: 30 93 07 01 sts 0x0107, r19
15e: 20 93 06 01 sts 0x0106, r18
162: c9 01 movw r24, r18
164: 08 95 ret
00000166 <test5>:
166: 9c 01 movw r18, r24
168: 29 57 subi r18, 0x79 ; 121
16a: 3f 4f sbci r19, 0xFF ; 255
16c: 30 93 09 01 sts 0x0109, r19
170: 20 93 08 01 sts 0x0108, r18
174: c9 01 movw r24, r18
176: 08 95 ret
00000178 <test6>:
178: 2d e8 ldi r18, 0x8D ; 141
17a: 30 e0 ldi r19, 0x00 ; 0
17c: 28 1b sub r18, r24
17e: 39 0b sbc r19, r25
180: 30 93 0b 01 sts 0x010B, r19
184: 20 93 0a 01 sts 0x010A, r18
188: c9 01 movw r24, r18
18a: 08 95 ret
0000018c <main>:
18c: 0f 93 push r16
18e: 1f 93 push r17
190: cf 93 push r28
192: df 93 push r29
194: 0e 94 8f 00 call 0x11e ; 0x11e <init>
198: 8c 01 movw r16, r24
19a: 0e 94 92 00 call 0x124 ; 0x124 <test1>
19e: ec 01 movw r28, r24
1a0: 0e 5f subi r16, 0xFE ; 254
1a2: 1f 4f sbci r17, 0xFF ; 255
1a4: 80 17 cp r24, r16
1a6: 91 07 cpc r25, r17
1a8: f9 f4 brne .+62 ; 0x1e8 <main+0x5c>
1aa: 0e 94 9a 00 call 0x134 ; 0x134 <test2>
1ae: c8 17 cp r28, r24
1b0: d9 07 cpc r29, r25
1b2: d1 f4 brne .+52 ; 0x1e8 <main+0x5c>
1b4: 0e 94 a2 00 call 0x144 ; 0x144 <test3>
1b8: c8 17 cp r28, r24
1ba: d9 07 cpc r29, r25
1bc: a9 f4 brne .+42 ; 0x1e8 <main+0x5c>
1be: 82 e0 ldi r24, 0x02 ; 2
1c0: 90 e0 ldi r25, 0x00 ; 0
1c2: 0e 94 aa 00 call 0x154 ; 0x154 <test4>
1c6: c8 17 cp r28, r24
1c8: d9 07 cpc r29, r25
1ca: 71 f4 brne .+28 ; 0x1e8 <main+0x5c>
1cc: 84 e0 ldi r24, 0x04 ; 4
1ce: 90 e0 ldi r25, 0x00 ; 0
1d0: 0e 94 b3 00 call 0x166 ; 0x166 <test5>
1d4: c8 17 cp r28, r24
1d6: d9 07 cpc r29, r25
1d8: 39 f4 brne .+14 ; 0x1e8 <main+0x5c>
1da: 82 e0 ldi r24, 0x02 ; 2
1dc: 90 e0 ldi r25, 0x00 ; 0
1de: 0e 94 bc 00 call 0x178 ; 0x178 <test6>
1e2: c8 17 cp r28, r24
1e4: d9 07 cpc r29, r25
1e6: 11 f0 breq .+4 ; 0x1ec <main+0x60>
1e8: 0e 94 87 00 call 0x10e ; 0x10e <abort>
1ec: 80 e0 ldi r24, 0x00 ; 0
1ee: 90 e0 ldi r25, 0x00 ; 0
1f0: 0e 94 86 00 call 0x10c ; 0x10c <exit>
------------------------------------------------------------------------
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c (revision 134294)
+++ gcc/config/avr/avr.c (working copy)
@@ -1120,12 +1120,24 @@
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);
- fprintf (file ,")");
+ rtx x = XEXP (addr,0);
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
+ {
+ /* double offset to make it a word offset */
+ fprintf (file, "gs(");
+ output_addr_const (file, XEXP (x,0));
+ fprintf (file ,"+");
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, 2 * INTVAL (XEXP (x,1)));
+ fprintf (file ,")");
+ }
+ else
+ {
+ fprintf (file, "gs(");
+ output_addr_const (file,addr);
+ fprintf (file ,")");
+ }
}
else
output_addr_const (file, addr);
@@ -4474,8 +4486,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);
Index: gcc/config/avr/predicates.md
===================================================================
--- gcc/config/avr/predicates.md (revision 134218)
+++ gcc/config/avr/predicates.md (working copy)
@@ -71,6 +71,27 @@
(define_predicate "symbol_ref_operand"
(match_code "symbol_ref"))
+;; Return true if OP is a text segment reference.
+;; This is needed for program memory address expressions.
+(define_predicate "text_segment_operand"
+ (match_code "label_ref,symbol_ref,plus,const")
+{
+ 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 :
+ gcc_unreachable ();
+ }
+})
+
;; Return true if OP is a constant that contains only one 1 in its
;; binary representation.
(define_predicate "single_one_operand"
------------------------------------------------------------------------
_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list