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.
26 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@171659 138bc75d-0d04-0410-961f-82ee72b054a4
28 index 77b3353..82cac42 100644
29 --- a/gcc/config/rx/predicates.md
30 +++ b/gcc/config/rx/predicates.md
34 (define_predicate "rx_zs_comparison_operator"
35 - (match_code "eq,ne,lt,ge")
36 + (match_code "eq,ne")
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);
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);
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. */
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. */
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)
89 index = XEXP (mem, 1);
91 - return RX_REG_P (base) && CONST_INT_P (index);
92 + if (! RX_REG_P (base) || ! CONST_INT_P (index))
95 + return IN_RANGE (INTVAL (index), 0, (0x10000 * GET_MODE_SIZE (mode)) - 1);
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. */
108 rx_print_operand (FILE * file, rtx op, int letter)
110 + bool unsigned_load = false;
115 @@ -450,6 +458,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
118 unsigned int flags = flags_from_mode (mode);
123 @@ -588,10 +597,15 @@ rx_print_operand (FILE * file, rtx op, int letter)
124 rx_print_integer (file, - INTVAL (op));
128 + gcc_assert (GET_MODE_SIZE (GET_MODE (op)) < 4);
129 + unsigned_load = true;
130 + /* Fall through. */
134 HOST_WIDE_INT offset;
139 @@ -626,22 +640,24 @@ rx_print_operand (FILE * file, rtx op, int letter)
140 rx_print_operand (file, op, 0);
141 fprintf (file, "].");
143 - switch (GET_MODE_SIZE (GET_MODE (op)))
144 + switch (GET_MODE_SIZE (GET_MODE (mem)))
147 - gcc_assert (offset < 65535 * 1);
148 - fprintf (file, "B");
149 + gcc_assert (offset <= 65535 * 1);
150 + fprintf (file, unsigned_load ? "UB" : "B");
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");
161 gcc_assert (offset % 4 == 0);
162 - gcc_assert (offset < 65535 * 4);
163 + gcc_assert (offset <= 65535 * 4);
167 + gcc_unreachable ();
171 @@ -2336,6 +2352,13 @@ rx_option_override (void)
172 flag_strict_volatile_bitfields = 1;
174 rx_override_options_after_change ();
176 + if (align_jumps == 0 && ! optimize_size)
178 + if (align_loops == 0 && ! optimize_size)
180 + if (align_labels == 0 && ! optimize_size)
184 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
185 @@ -2728,6 +2751,45 @@ rx_match_ccmode (rtx insn, enum machine_mode cc_mode)
190 +rx_align_for_label (void)
192 + return optimize_size ? 1 : 3;
196 +rx_max_skip_for_label (rtx lab)
201 + if (lab == NULL_RTX)
206 + op = next_nonnote_insn (op);
208 + while (op && (LABEL_P (op)
209 + || (INSN_P (op) && GET_CODE (PATTERN (op)) == USE)));
213 + opsize = get_attr_length (op);
214 + if (opsize >= 0 && opsize < 8)
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
228 #undef TARGET_FUNCTION_VALUE
229 #define TARGET_FUNCTION_VALUE rx_function_value
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
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))
242 +#define LABEL_ALIGN_AFTER_BARRIER(x) rx_align_for_label ()
244 +#define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM, LOG, MAX_SKIP) \
247 + if ((LOG) == 0 || (MAX_SKIP) == 0) \
249 + if (TARGET_AS100_SYNTAX) \
252 + fprintf (STREAM, "\t.ALIGN 4\t; %d alignment actually requested\n", 1 << (LOG)); \
254 + fprintf (STREAM, "\t.ALIGN 2\n"); \
257 + fprintf (STREAM, "\t.balign %d,3,%d\n", 1 << (LOG), (MAX_SKIP)); \
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")]
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.
272 +(define_code_iterator extend_types [(zero_extend "") (sign_extend "")])
273 +(define_code_attr letter [(zero_extend "R") (sign_extend "Q")])
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 "")])
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")])
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)
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))])]
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)
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))])]
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)
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))])]
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)
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))))]
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)
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))))]
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))]
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.
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))]
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.
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"))))]
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.
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")
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))))]
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"))))]
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.
401 ;; Floating Point Instructions
403 (define_insn "addsf3"