]> git.pld-linux.org Git - packages/crossavr-gcc.git/blame - 501-gcc-avrtc579.patch
- cleanup, updated BRs, stub texinfo build (not packaged and would require patch...
[packages/crossavr-gcc.git] / 501-gcc-avrtc579.patch
CommitLineData
64c2fd3a
JR
1diff -Naurp gcc/config/avr/avr.c gcc/config/avr/avr.c
2--- gcc/config/avr/avr.c 2012-11-09 19:05:47.000000000 +0530
3+++ gcc/config/avr/avr.c 2012-11-14 13:57:13.000000000 +0530
4@@ -2801,6 +2801,35 @@ avr_out_xload (rtx insn ATTRIBUTE_UNUSED
5 return "";
6 }
7
8+/*
9+AVRTC-579
10+if operand is symbol or constant expression with value > 0xbf
11+ return false, otherwise true
12+This check is used to avoid lds/sts instruction with invalid memory
13+access range (valid range 0x40..0xbf). For io operand range 0x0..0x3f,
14+in/out instruction will be generated.
15+*/
16+bool tiny_valid_direct_memory_access_range(rtx op, enum machine_mode mode)
17+{
18+ rtx x;
19+
20+ if (!AVR_TINY)
21+ return true;
22+
23+ x = XEXP(op,0);
24+
25+ if (MEM_P(op) && x && (GET_CODE(x) == SYMBOL_REF))
26+ {
27+ return false;
28+ }
29+ if (MEM_P(op) && x && (CONSTANT_ADDRESS_P (x)) &&
30+ !(IN_RANGE (INTVAL (x), 0, 0xC0 - GET_MODE_SIZE (mode))))
31+ {
32+ return false;
33+ }
34+
35+ return true;
36+}
37
38 const char*
39 output_movqi (rtx insn, rtx operands[], int *real_l)
40@@ -2956,9 +2985,10 @@ out_movqi_r_mr (rtx insn, rtx op[], int
41
42 if (CONSTANT_ADDRESS_P (x))
43 {
44+ int n_words = AVR_TINY ? 1 : 2;
45 return optimize > 0 && io_address_operand (x, QImode)
46 ? avr_asm_len ("in %0,%i1", op, plen, -1)
47- : avr_asm_len ("lds %0,%m1", op, plen, -2);
48+ : avr_asm_len ("lds %0,%m1", op, plen, -n_words);
49 }
50
51
52@@ -3213,12 +3243,13 @@ out_movhi_r_mr (rtx insn, rtx op[], int
53 }
54 else if (CONSTANT_ADDRESS_P (base))
55 {
56+ int n_words = AVR_TINY ? 2 : 4;
57 return optimize > 0 && io_address_operand (base, HImode)
58 ? avr_asm_len ("in %A0,%i1" CR_TAB
59 "in %B0,%i1+1", op, plen, -2)
60
61 : avr_asm_len ("lds %A0,%m1" CR_TAB
62- "lds %B0,%m1+1", op, plen, -4);
63+ "lds %B0,%m1+1", op, plen, -n_words);
64 }
65
66 fatal_insn ("unknown move insn:",insn);
67@@ -3478,10 +3509,24 @@ out_movsi_r_mr (rtx insn, rtx op[], int
68 "ld %C0,%1" CR_TAB
69 "ld %D0,%1");
70 else if (CONSTANT_ADDRESS_P (base))
71- return *l=8, ("lds %A0,%m1" CR_TAB
72- "lds %B0,%m1+1" CR_TAB
73- "lds %C0,%m1+2" CR_TAB
74- "lds %D0,%m1+3");
75+ {
76+ if (io_address_operand (base, SImode))
77+ {
78+ *l = 4;
79+ return ("in %A0,%i1" CR_TAB
80+ "in %B0,%i1+1" CR_TAB
81+ "in %C0,%i1+2" CR_TAB
82+ "in %D0,%i1+3");
83+ }
84+ else
85+ {
86+ *l = AVR_TINY ? 4 : 8;
87+ return ("lds %A0,%m1" CR_TAB
88+ "lds %B0,%m1+1" CR_TAB
89+ "lds %C0,%m1+2" CR_TAB
90+ "lds %D0,%m1+3");
91+ }
92+ }
93
94 fatal_insn ("unknown move insn:",insn);
95 return "";
96@@ -3608,10 +3653,24 @@ out_movsi_mr_r (rtx insn, rtx op[], int
97 l = &tmp;
98
99 if (CONSTANT_ADDRESS_P (base))
100- return *l=8,("sts %m0,%A1" CR_TAB
101- "sts %m0+1,%B1" CR_TAB
102- "sts %m0+2,%C1" CR_TAB
103- "sts %m0+3,%D1");
104+ {
105+ if (io_address_operand (base, SImode))
106+ {
107+ return *l=4,("out %i0, %A1" CR_TAB
108+ "out %i0+1,%B1" CR_TAB
109+ "out %i0+2,%C1" CR_TAB
110+ "out %i0+3,%D1");
111+ }
112+ else
113+ {
114+ *l = AVR_TINY ? 4 : 8;
115+ return ("sts %m0,%A1" CR_TAB
116+ "sts %m0+1,%B1" CR_TAB
117+ "sts %m0+2,%C1" CR_TAB
118+ "sts %m0+3,%D1");
119+ }
120+ }
121+
122 if (reg_base > 0) /* (r) */
123 {
124 if (AVR_TINY)
125@@ -4031,9 +4090,12 @@ avr_out_load_psi (rtx insn, rtx *op, int
126 "ld %C0,%1", op, plen, -3);
127
128 else if (CONSTANT_ADDRESS_P (base))
129+ {
130+ int n_words = AVR_TINY ? 3 : 6;
131 return avr_asm_len ("lds %A0,%m1" CR_TAB
132 "lds %B0,%m1+1" CR_TAB
133- "lds %C0,%m1+2", op, plen , -6);
134+ "lds %C0,%m1+2", op, plen , -n_words);
135+ }
136
137 fatal_insn ("unknown move insn:",insn);
138 return "";
139@@ -4129,9 +4191,12 @@ avr_out_store_psi (rtx insn, rtx *op, in
140 int reg_base = true_regnum (base);
141
142 if (CONSTANT_ADDRESS_P (base))
143+ {
144+ int n_words = AVR_TINY ? 3 : 6;
145 return avr_asm_len ("sts %m0,%A1" CR_TAB
146 "sts %m0+1,%B1" CR_TAB
147- "sts %m0+2,%C1", op, plen, -6);
148+ "sts %m0+2,%C1", op, plen, -n_words);
149+ }
150
151 if (reg_base > 0) /* (r) */
152 {
153@@ -4314,9 +4379,10 @@ out_movqi_mr_r (rtx insn, rtx op[], int
154
155 if (CONSTANT_ADDRESS_P (x))
156 {
157+ int n_words = AVR_TINY ? 1 : 2;
158 return optimize > 0 && io_address_operand (x, QImode)
159 ? avr_asm_len ("out %i0,%1", op, plen, -1)
160- : avr_asm_len ("sts %m0,%1", op, plen, -2);
161+ : avr_asm_len ("sts %m0,%1", op, plen, -n_words);
162 }
163 else if (GET_CODE (x) == PLUS
164 && REG_P (XEXP (x, 0))
165@@ -4389,12 +4455,15 @@ avr_out_movhi_mr_r_xmega (rtx insn, rtx
166 int mem_volatile_p = MEM_VOLATILE_P (dest);
167
168 if (CONSTANT_ADDRESS_P (base))
169+ {
170+ int n_words = AVR_TINY ? 2 : 4;
171 return optimize > 0 && io_address_operand (base, HImode)
172 ? avr_asm_len ("out %i0,%A1" CR_TAB
173 "out %i0+1,%B1", op, plen, -2)
174
175 : avr_asm_len ("sts %m0,%A1" CR_TAB
176- "sts %m0+1,%B1", op, plen, -4);
177+ "sts %m0+1,%B1", op, plen, -n_words);
178+ }
179
180 if (reg_base > 0)
181 {
182@@ -4574,12 +4643,15 @@ out_movhi_mr_r (rtx insn, rtx op[], int
183 mem_volatile_p = MEM_VOLATILE_P (dest);
184
185 if (CONSTANT_ADDRESS_P (base))
186+ {
187+ int n_words = AVR_TINY ? 2 : 4;
188 return optimize > 0 && io_address_operand (base, HImode)
189 ? avr_asm_len ("out %i0+1,%B1" CR_TAB
190 "out %i0,%A1", op, plen, -2)
191
192 : avr_asm_len ("sts %m0+1,%B1" CR_TAB
193- "sts %m0,%A1", op, plen, -4);
194+ "sts %m0,%A1", op, plen, -n_words);
195+ }
196
197 if (reg_base > 0)
198 {
199diff -Naurp gcc/config/avr/avr.md gcc/config/avr/avr.md
200--- gcc/config/avr/avr.md 2012-11-09 19:05:47.000000000 +0530
201+++ gcc/config/avr/avr.md 2012-11-14 13:57:13.000000000 +0530
202@@ -629,6 +629,32 @@
203 DONE;
204 }
205
206+ /* AVRTC-579
207+ if the source operand expression is out of range for 'lds' instruction
208+ copy source operand expression to register
209+ For tiny core, LDS instruction's memory access range limited to 0x40..0xbf
210+ */
211+ if (!tiny_valid_direct_memory_access_range(src,<MODE>mode))
212+ {
213+ rtx srcx = XEXP(src,0);
214+ operands[1] = src = replace_equiv_address (src,copy_to_mode_reg (GET_MODE(srcx),srcx));
215+ emit_move_insn(dest,src);
216+ DONE;
217+ }
218+
219+ /* AVRTC-579
220+ if the destination operand expression is out of range for 'sts' instruction
221+ copy destination operand expression to register
222+ For tiny core, STS instruction's memory access range limited to 0x40..0xbf
223+ */
224+ if (!tiny_valid_direct_memory_access_range(dest,<MODE>mode))
225+ {
226+ rtx destx = XEXP(dest,0);
227+ operands[0] = dest = replace_equiv_address (dest,copy_to_mode_reg (GET_MODE(destx),destx));
228+ emit_move_insn(dest,src);
229+ DONE;
230+ }
231+
232 /* ; The only address-space for which we use plain MEM and reload
233 ; machinery are 1-byte loads from __flash. */
234 })
235@@ -645,9 +671,14 @@
236 (define_insn "movqi_insn"
237 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
238 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
239- "register_operand (operands[0], QImode)
240+ "(register_operand (operands[0], QImode)
241 || register_operand (operands[1], QImode)
242- || const0_rtx == operands[1]"
243+ || const0_rtx == operands[1]) &&
244+ /* skip if operands are out of lds/sts memory access range(0x40..0xbf)
245+ though access range is checked during define_expand, it is required
246+ here to avoid merging rtls during combine pass */
247+ tiny_valid_direct_memory_access_range(operands[0],QImode) &&
248+ tiny_valid_direct_memory_access_range(operands[1],QImode)"
249 {
250 return output_movqi (insn, operands, NULL);
251 }
252@@ -732,9 +763,14 @@
253 (define_insn "*movhi"
254 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
255 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
256- "register_operand (operands[0], HImode)
257+ "(register_operand (operands[0], HImode)
258 || register_operand (operands[1], HImode)
259- || const0_rtx == operands[1]"
260+ || const0_rtx == operands[1]) &&
261+ /* skip if operands are out of lds/sts memory access range(0x40..0xbf)
262+ though access range is checked during define_expand, it is required
263+ here to avoid merging rtls during combine pass */
264+ tiny_valid_direct_memory_access_range(operands[0],HImode) &&
265+ tiny_valid_direct_memory_access_range(operands[1],HImode)"
266 {
267 return output_movhi (insn, operands, NULL);
268 }
269@@ -842,9 +878,15 @@
270 (define_insn "*movsi"
271 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
272 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
273- "register_operand (operands[0], SImode)
274+ "((register_operand (operands[0], SImode)
275 || register_operand (operands[1], SImode)
276- || const0_rtx == operands[1]"
277+ || const0_rtx == operands[1]) &&
278+ /* skip if operands are out of lds/sts memory access range(0x40..0xbf)
279+ though access range is checked during define_expand, it is required
280+ here to avoid merging rtls during combine pass */
281+ tiny_valid_direct_memory_access_range(operands[0],SImode) &&
282+ tiny_valid_direct_memory_access_range(operands[1],SImode))
283+ "
284 {
285 return output_movsisf (insn, operands, NULL);
286 }
287@@ -858,9 +900,15 @@
288 (define_insn "*movsf"
289 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
290 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
291- "register_operand (operands[0], SFmode)
292+ "((register_operand (operands[0], SFmode)
293 || register_operand (operands[1], SFmode)
294- || operands[1] == CONST0_RTX (SFmode)"
295+ || operands[1] == CONST0_RTX (SFmode)) &&
296+ /* skip if operands are out of lds/sts memory access range(0x40..0xbf)
297+ though access range is checked during define_expand, it is required
298+ here to avoid merging rtls during combine pass */
299+ tiny_valid_direct_memory_access_range(operands[0],SFmode) &&
300+ tiny_valid_direct_memory_access_range(operands[1],SFmode))
301+ "
302 {
303 return output_movsisf (insn, operands, NULL);
304 }
This page took 0.086914 seconds and 4 git commands to generate.