]> code.ossystems Code Review - openembedded-core.git/blob
a929828ef79e9224b96804459bdb2c513bd01dce
[openembedded-core.git] /
1 Upstream-Status: Inappropriate [Backport]
2 From 04688242805dcf2a1e9c8948a3d15611d88c1520 Mon Sep 17 00:00:00 2001
3 From: nickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
4 Date: Tue, 29 Mar 2011 12:27:07 +0000
5 Subject: [PATCH 020/200]        * config/rx/rx.h (LABEL_ALIGN_AFTER_BARRIER): Define.
6         (ASM_OUTPUT_MAX_SKIP): Define.
7         * config/rx/predicates.md (rx_zs_comparison_operator): Do not
8         allow LT aor GE comparisons.
9         * config/rx/rx-protos.h (rx_align_for_label): Prototype.
10         * config/rx/rx.md: Add peepholes and patterns to combine extending
11         loads with simple arithmetic instructions.
12         * config/rx/rx.c (rx_is_legitimate_address): Allow QI and HI modes
13         to use pre-decrement and post-increment addressing.
14         (rx_is_restricted_memory_address): For REG+INT addressing, ensure
15         that the INT is a valid offset.
16         (rx_print_operand): Handle %R.
17         Fix %Q's handling of MEMs.
18         (rx_option_override): Set alignments.
19         (rx_align_for_label): New function.
20         (rx_max_skip_for_label): New function.
21         (TARGET_ASM_JUMP_ALIGN_MAX_SKIP): Define.
22         (TARGET_ASM_LOOP_ALIGN_MAX_SKIP): Define.
23         (TARGET_ASM_LABEL_ALIGN_MAX_SKIP): Define.
24         (TARGET_ASM_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP): Define.
25
26 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@171659 138bc75d-0d04-0410-961f-82ee72b054a4
27
28 index 77b3353..82cac42 100644
29 --- a/gcc/config/rx/predicates.md
30 +++ b/gcc/config/rx/predicates.md
31 @@ -284,7 +284,7 @@
32  )
33  
34  (define_predicate "rx_zs_comparison_operator"
35 -  (match_code "eq,ne,lt,ge")
36 +  (match_code "eq,ne")
37  )
38  
39  ;; GT and LE omitted due to operand swap required.
40 diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h
41 index a6ae416..e1ab9c2 100644
42 --- a/gcc/config/rx/rx-protos.h
43 +++ b/gcc/config/rx/rx-protos.h
44 @@ -30,16 +30,17 @@ extern void         rx_expand_prologue (void);
45  extern int             rx_initial_elimination_offset (int, int);
46  
47  #ifdef RTX_CODE
48 +extern int             rx_align_for_label (void);
49  extern void             rx_emit_stack_popm (rtx *, bool);
50  extern void             rx_emit_stack_pushm (rtx *);
51  extern void            rx_expand_epilogue (bool);
52  extern char *          rx_gen_move_template (rtx *, bool);
53  extern bool            rx_is_legitimate_constant (rtx);
54  extern bool            rx_is_restricted_memory_address (rtx, Mmode);
55 +extern bool            rx_match_ccmode (rtx, Mmode);
56  extern void            rx_notice_update_cc (rtx body, rtx insn);
57  extern void            rx_split_cbranch (Mmode, Rcode, rtx, rtx, rtx);
58  extern Mmode           rx_select_cc_mode (Rcode, rtx, rtx);
59 -extern bool            rx_match_ccmode (rtx, Mmode);
60  #endif
61  
62  #endif /* GCC_RX_PROTOS_H */
63 diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
64 index 6b179e7..ad8d0bb 100644
65 --- a/gcc/config/rx/rx.c
66 +++ b/gcc/config/rx/rx.c
67 @@ -57,7 +57,7 @@ static void rx_print_operand (FILE *, rtx, int);
68  #define CC_FLAG_Z      (1 << 1)
69  #define CC_FLAG_O      (1 << 2)
70  #define CC_FLAG_C      (1 << 3)
71 -#define CC_FLAG_FP     (1 << 4)        /* fake, to differentiate CC_Fmode */
72 +#define CC_FLAG_FP     (1 << 4)        /* Fake, to differentiate CC_Fmode.  */
73  
74  static unsigned int flags_from_mode (enum machine_mode mode);
75  static unsigned int flags_from_code (enum rtx_code code);
76 @@ -85,7 +85,9 @@ rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
77      /* Register Indirect.  */
78      return true;
79  
80 -  if (GET_MODE_SIZE (mode) == 4
81 +  if ((GET_MODE_SIZE (mode) == 4
82 +       || GET_MODE_SIZE (mode) == 2
83 +       || GET_MODE_SIZE (mode) == 1)
84        && (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
85      /* Pre-decrement Register Indirect or
86         Post-increment Register Indirect.  */
87 @@ -187,7 +189,10 @@ rx_is_restricted_memory_address (rtx mem, enum machine_mode mode)
88        base = XEXP (mem, 0);
89        index = XEXP (mem, 1);
90  
91 -      return RX_REG_P (base) && CONST_INT_P (index);
92 +      if (! RX_REG_P (base) || ! CONST_INT_P (index))
93 +         return false;
94 +
95 +      return IN_RANGE (INTVAL (index), 0, (0x10000 * GET_MODE_SIZE (mode)) - 1);
96  
97      case SYMBOL_REF:
98        /* Can happen when small data is being supported.
99 @@ -386,11 +391,14 @@ rx_assemble_integer (rtx x, unsigned int size, int is_aligned)
100       %L  Print low part of a DImode register, integer or address.
101       %N  Print the negation of the immediate value.
102       %Q  If the operand is a MEM, then correctly generate
103 -         register indirect or register relative addressing.  */
104 +         register indirect or register relative addressing.
105 +     %R  Like %Q but for zero-extending loads.  */
106  
107  static void
108  rx_print_operand (FILE * file, rtx op, int letter)
109  {
110 +  bool unsigned_load = false;
111 +
112    switch (letter)
113      {
114      case 'A':
115 @@ -450,6 +458,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
116         else
117           {
118             unsigned int flags = flags_from_mode (mode);
119 +
120             switch (code)
121               {
122               case LT:
123 @@ -588,10 +597,15 @@ rx_print_operand (FILE * file, rtx op, int letter)
124        rx_print_integer (file, - INTVAL (op));
125        break;
126  
127 +    case 'R':
128 +      gcc_assert (GET_MODE_SIZE (GET_MODE (op)) < 4);
129 +      unsigned_load = true;
130 +      /* Fall through.  */
131      case 'Q':
132        if (MEM_P (op))
133         {
134           HOST_WIDE_INT offset;
135 +         rtx mem = op;
136  
137           op = XEXP (op, 0);
138  
139 @@ -626,22 +640,24 @@ rx_print_operand (FILE * file, rtx op, int letter)
140           rx_print_operand (file, op, 0);
141           fprintf (file, "].");
142  
143 -         switch (GET_MODE_SIZE (GET_MODE (op)))
144 +         switch (GET_MODE_SIZE (GET_MODE (mem)))
145             {
146             case 1:
147 -             gcc_assert (offset < 65535 * 1);
148 -             fprintf (file, "B");
149 +             gcc_assert (offset <= 65535 * 1);
150 +             fprintf (file, unsigned_load ? "UB" : "B");
151               break;
152             case 2:
153               gcc_assert (offset % 2 == 0);
154 -             gcc_assert (offset < 65535 * 2);
155 -             fprintf (file, "W");
156 +             gcc_assert (offset <= 65535 * 2);
157 +             fprintf (file, unsigned_load ? "UW" : "W");
158               break;
159 -           default:
160 +           case 4:
161               gcc_assert (offset % 4 == 0);
162 -             gcc_assert (offset < 65535 * 4);
163 +             gcc_assert (offset <= 65535 * 4);
164               fprintf (file, "L");
165               break;
166 +           default:
167 +             gcc_unreachable ();
168             }
169           break;
170         }
171 @@ -2336,6 +2352,13 @@ rx_option_override (void)
172      flag_strict_volatile_bitfields = 1;
173  
174    rx_override_options_after_change ();
175 +
176 +  if (align_jumps == 0 && ! optimize_size)
177 +    align_jumps = 3;
178 +  if (align_loops == 0 && ! optimize_size)
179 +    align_loops = 3;
180 +  if (align_labels == 0 && ! optimize_size)
181 +    align_labels = 3;
182  }
183  
184  /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
185 @@ -2728,6 +2751,45 @@ rx_match_ccmode (rtx insn, enum machine_mode cc_mode)
186  }
187  
188  \f
189 +int
190 +rx_align_for_label (void)
191 +{
192 +  return optimize_size ? 1 : 3;
193 +}
194 +
195 +static int
196 +rx_max_skip_for_label (rtx lab)
197 +{
198 +  int opsize;
199 +  rtx op;
200 +
201 +  if (lab == NULL_RTX)
202 +    return 0;
203 +  op = lab;
204 +  do
205 +    {
206 +      op = next_nonnote_insn (op);
207 +    }
208 +  while (op && (LABEL_P (op)
209 +               || (INSN_P (op) && GET_CODE (PATTERN (op)) == USE)));
210 +  if (!op)
211 +    return 0;
212 +
213 +  opsize = get_attr_length (op);
214 +  if (opsize >= 0 && opsize < 8)
215 +    return opsize - 1;
216 +  return 0;
217 +}
218 +\f
219 +#undef  TARGET_ASM_JUMP_ALIGN_MAX_SKIP
220 +#define TARGET_ASM_JUMP_ALIGN_MAX_SKIP                 rx_max_skip_for_label
221 +#undef  TARGET_ASM_LOOP_ALIGN_MAX_SKIP
222 +#define TARGET_ASM_LOOP_ALIGN_MAX_SKIP                 rx_max_skip_for_label
223 +#undef  TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
224 +#define TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP      rx_max_skip_for_label
225 +#undef  TARGET_ASM_LABEL_ALIGN_MAX_SKIP
226 +#define TARGET_ASM_LABEL_ALIGN_MAX_SKIP                        rx_max_skip_for_label
227 +
228  #undef  TARGET_FUNCTION_VALUE
229  #define TARGET_FUNCTION_VALUE          rx_function_value
230  
231 diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
232 index e3966ed..01fc23b 100644
233 --- a/gcc/config/rx/rx.h
234 +++ b/gcc/config/rx/rx.h
235 @@ -615,4 +615,23 @@ typedef unsigned int CUMULATIVE_ARGS;
236  #define BRANCH_COST(SPEED,PREDICT)       1
237  #define REGISTER_MOVE_COST(MODE,FROM,TO) 2
238  
239 -#define SELECT_CC_MODE(OP,X,Y)  rx_select_cc_mode(OP, X, Y)
240 +#define SELECT_CC_MODE(OP,X,Y)  rx_select_cc_mode((OP), (X), (Y))
241 +
242 +#define LABEL_ALIGN_AFTER_BARRIER(x)           rx_align_for_label ()
243 +
244 +#define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM, LOG, MAX_SKIP)       \
245 +  do                                           \
246 +    {                                          \
247 +      if ((LOG) == 0 || (MAX_SKIP) == 0)       \
248 +        break;                                 \
249 +      if (TARGET_AS100_SYNTAX)                 \
250 +       {                                       \
251 +         if ((LOG) >= 2)                       \
252 +           fprintf (STREAM, "\t.ALIGN 4\t; %d alignment actually requested\n", 1 << (LOG)); \
253 +         else                                  \
254 +           fprintf (STREAM, "\t.ALIGN 2\n");   \
255 +       }                                       \
256 +      else                                     \
257 +       fprintf (STREAM, "\t.balign %d,3,%d\n", 1 << (LOG), (MAX_SKIP));        \
258 +    }                                          \
259 +  while (0)
260 diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
261 index cd5b571..641f1d4 100644
262 --- a/gcc/config/rx/rx.md
263 +++ b/gcc/config/rx/rx.md
264 @@ -1545,6 +1545,139 @@
265     (set_attr "length" "3,4,5,6,7,6")]
266  )
267  \f
268 +;; A set of peepholes to catch extending loads followed by arithmetic operations.
269 +;; We use iterators where possible to reduce the amount of typing and hence the
270 +;; possibilities for typos.
271 +
272 +(define_code_iterator extend_types [(zero_extend "") (sign_extend "")])
273 +(define_code_attr     letter       [(zero_extend "R") (sign_extend "Q")])
274 +
275 +(define_code_iterator memex_commutative [(plus "") (and "") (ior "") (xor "")])
276 +(define_code_iterator memex_noncomm     [(div "") (udiv "") (minus "")])
277 +(define_code_iterator memex_nocc        [(smax "") (smin "") (mult "")])
278 +
279 +(define_code_attr     op                [(plus "add") (and "and") (div "div") (udiv "divu") (smax "max") (smin "min") (mult "mul") (ior "or") (minus "sub") (xor "xor")])
280 +
281 +(define_peephole2
282 +  [(set (match_operand:SI                               0 "register_operand")
283 +       (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
284 +   (parallel [(set (match_operand:SI                    2 "register_operand")
285 +                  (memex_commutative:SI (match_dup 0)
286 +                                        (match_dup 2)))
287 +             (clobber (reg:CC CC_REG))])]
288 +  "peep2_regno_dead_p (2, REGNO (operands[0]))"
289 +  [(parallel [(set:SI (match_dup 2)
290 +                     (memex_commutative:SI (match_dup 2)
291 +                                           (extend_types:SI (match_dup 1))))
292 +             (clobber (reg:CC CC_REG))])]
293 +)
294 +
295 +(define_peephole2
296 +  [(set (match_operand:SI                               0 "register_operand")
297 +       (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
298 +   (parallel [(set (match_operand:SI                    2 "register_operand")
299 +                  (memex_commutative:SI (match_dup 2)
300 +                                        (match_dup 0)))
301 +             (clobber (reg:CC CC_REG))])]
302 +  "peep2_regno_dead_p (2, REGNO (operands[0]))"
303 +  [(parallel [(set:SI (match_dup 2)
304 +                     (memex_commutative:SI (match_dup 2)
305 +                                           (extend_types:SI (match_dup 1))))
306 +             (clobber (reg:CC CC_REG))])]
307 +)
308 +
309 +(define_peephole2
310 +  [(set (match_operand:SI                               0 "register_operand")
311 +       (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
312 +   (parallel [(set (match_operand:SI                    2 "register_operand")
313 +                  (memex_noncomm:SI (match_dup 2)
314 +                                    (match_dup 0)))
315 +             (clobber (reg:CC CC_REG))])]
316 +  "peep2_regno_dead_p (2, REGNO (operands[0]))"
317 +  [(parallel [(set:SI (match_dup 2)
318 +                     (memex_noncomm:SI (match_dup 2)
319 +                                       (extend_types:SI (match_dup 1))))
320 +             (clobber (reg:CC CC_REG))])]
321 +)
322 +
323 +(define_peephole2
324 +  [(set (match_operand:SI                               0 "register_operand")
325 +       (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
326 +   (set (match_operand:SI                               2 "register_operand")
327 +       (memex_nocc:SI (match_dup 0)
328 +                      (match_dup 2)))]
329 +  "peep2_regno_dead_p (2, REGNO (operands[0]))"
330 +  [(set:SI (match_dup 2)
331 +          (memex_nocc:SI (match_dup 2)
332 +                         (extend_types:SI (match_dup 1))))]
333 +)
334 +
335 +(define_peephole2
336 +  [(set (match_operand:SI                               0 "register_operand")
337 +       (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
338 +   (set (match_operand:SI                               2 "register_operand")
339 +       (memex_nocc:SI (match_dup 2)
340 +                      (match_dup 0)))]
341 +  "peep2_regno_dead_p (2, REGNO (operands[0]))"
342 +  [(set:SI (match_dup 2)
343 +          (memex_nocc:SI (match_dup 2)
344 +                         (extend_types:SI (match_dup 1))))]
345 +)
346 +
347 +(define_insn "*<memex_commutative:code>si3_<extend_types:code><small_int_modes:mode>"
348 +  [(set (match_operand:SI                                                     0 "register_operand" "=r")
349 +       (memex_commutative:SI (match_operand:SI                               1 "register_operand" "%0")
350 +                             (extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))
351 +   (clobber (reg:CC CC_REG))]
352 +  ""
353 +  "<memex_commutative:op>\t%<extend_types:letter>2, %0"
354 +  [(set_attr "timings" "33")
355 +   (set_attr "length"  "5")] ;; Worst case sceanario.  FIXME: If we defined separate patterns 
356 +)                            ;; rather than using iterators we could specify exact sizes.
357 +
358 +(define_insn "*<memex_noncomm:code>si3_<extend_types:code><small_int_modes:mode>"
359 +  [(set (match_operand:SI                                                 0 "register_operand" "=r")
360 +       (memex_noncomm:SI (match_operand:SI                               1 "register_operand" "0")
361 +                          (extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))
362 +   (clobber (reg:CC CC_REG))]
363 +  ""
364 +  "<memex_noncomm:op>\t%<extend_types:letter>2, %0"
365 +  [(set_attr "timings" "33")
366 +   (set_attr "length"  "5")] ;; Worst case sceanario.  FIXME: If we defined separate patterns 
367 +)                            ;; rather than using iterators we could specify exact sizes.
368 +
369 +(define_insn "*<memex_nocc:code>si3_<extend_types:code><small_int_modes:mode>"
370 +  [(set (match_operand:SI                                              0 "register_operand" "=r")
371 +       (memex_nocc:SI (match_operand:SI                               1 "register_operand" "%0")
372 +                      (extend_types:SI (match_operand:small_int_modes 2 "rx_restricted_mem_operand" "Q"))))]
373 +  ""
374 +  "<memex_nocc:op>\t%<extend_types:letter>2, %0"
375 +  [(set_attr "timings" "33")
376 +   (set_attr "length"  "5")] ;; Worst case sceanario.  FIXME: If we defined separate patterns 
377 +)                            ;; rather than using iterators we could specify exact sizes.
378 +
379 +(define_peephole2
380 +  [(set (match_operand:SI                               0 "register_operand")
381 +       (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand")))
382 +   (set (reg:CC CC_REG)
383 +       (compare:CC (match_operand:SI                   2 "register_operand")
384 +                   (match_dup 0)))]
385 +  "peep2_regno_dead_p (2, REGNO (operands[0]))"
386 +  [(set (reg:CC CC_REG)
387 +       (compare:CC (match_dup 2)
388 +                   (extend_types:SI (match_dup 1))))]
389 +)
390 +
391 +(define_insn "*comparesi3_<extend_types:code><small_int_modes:mode>"
392 +  [(set (reg:CC CC_REG)
393 +       (compare:CC (match_operand:SI                               0 "register_operand" "=r")
394 +                   (extend_types:SI (match_operand:small_int_modes 1 "rx_restricted_mem_operand" "Q"))))]
395 +  ""
396 +  "cmp\t%<extend_types:letter>1, %0"
397 +  [(set_attr "timings" "33")
398 +   (set_attr "length"  "5")] ;; Worst case sceanario.  FIXME: If we defined separate patterns 
399 +)                            ;; rather than using iterators we could specify exact sizes.
400 +\f
401  ;; Floating Point Instructions
402  
403  (define_insn "addsf3"
404 -- 
405 1.7.0.4
406