OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [config/] [m32c/] [cond.md] - Blame information for rev 38

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
;; Machine Descriptions for R8C/M16C/M32C
2
;; Copyright (C) 2005, 2007
3
;; Free Software Foundation, Inc.
4
;; Contributed by Red Hat.
5
;;
6
;; This file is part of GCC.
7
;;
8
;; GCC is free software; you can redistribute it and/or modify it
9
;; under the terms of the GNU General Public License as published
10
;; by the Free Software Foundation; either version 3, or (at your
11
;; option) any later version.
12
;;
13
;; GCC is distributed in the hope that it will be useful, but WITHOUT
14
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16
;; License for more details.
17
;;
18
;; You should have received a copy of the GNU General Public License
19
;; along with GCC; see the file COPYING3.  If not see
20
;; .
21
 
22
; conditionals - cmp, jcc, setcc, etc.
23
 
24
; Special note about conditional instructions: GCC always emits the
25
; compare right before the insn, which is good, because m32c's mov
26
; insns modify the flags.  However, this means that any conditional
27
; insn that may require reloading must be kept with its compare until
28
; after reload finishes, else the reload insns might clobber the
29
; flags.  Thus, these rules:
30
;
31
; * the cmp* expanders just save the operands in compare_op0 and
32
;   compare_op1 via m32c_pend_compare.
33
; * conditional insns that won't need reload can call
34
;   m32c_unpend_compare before their expansion.
35
; * other insns must expand to include the compare operands within,
36
;   then split after reload to a separate compare and conditional.
37
 
38
; Until support for relaxing is supported in gas, we must assume that
39
; short labels won't reach, so we must use long labels.
40
; Unfortunately, there aren't any conditional jumps with long labels,
41
; so instead we invert the conditional and jump around a regular jump.
42
 
43
; Note that we can, at some point in the future, add code to omit the
44
; "cmp" portion of the insn if the preceding insn happened to set the
45
; right flags already.  For example, a mov followed by a "cmp *,0" is
46
; redundant; the move already set the Z flag.
47
 
48
(define_insn_and_split "cbranch4"
49
  [(set (pc) (if_then_else
50
              (match_operator 0 "m32c_cmp_operator"
51
                              [(match_operand:QHPSI 1 "mra_operand" "RraSd")
52
                               (match_operand:QHPSI 2 "mrai_operand" "iRraSd")])
53
              (label_ref (match_operand 3 "" ""))
54
              (pc)))]
55
  ""
56
  "#"
57
  "reload_completed"
58
  [(set (reg:CC FLG_REGNO)
59
        (compare (match_dup 1)
60
                 (match_dup 2)))
61
   (set (pc) (if_then_else (match_dup 4)
62
                           (label_ref (match_dup 3))
63
                           (pc)))]
64
  "operands[4] = m32c_cmp_flg_0 (operands[0]);"
65
  )
66
 
67
(define_insn "stzx_16"
68
  [(set (match_operand:QI 0 "mrai_operand" "=R0w,R0w,R0w")
69
        (if_then_else:QI (eq (reg:CC FLG_REGNO) (const_int 0))
70
                         (match_operand:QI 1 "const_int_operand" "i,i,0")
71
                         (match_operand:QI 2 "const_int_operand" "i,0,i")))]
72
  "TARGET_A16 && reload_completed"
73
  "@
74
   stzx\t%1,%2,%0
75
   stz\t%1,%0
76
   stnz\t%2,%0"
77
  [(set_attr "flags" "n,n,n")]
78
)
79
 
80
(define_insn "stzx_24_"
81
  [(set (match_operand:QHI 0 "mrai_operand" "=RraSd,RraSd,RraSd")
82
        (if_then_else:QHI (eq (reg:CC FLG_REGNO) (const_int 0))
83
                         (match_operand:QHI 1 "const_int_operand" "i,i,0")
84
                         (match_operand:QHI 2 "const_int_operand" "i,0,i")))]
85
  "TARGET_A24 && reload_completed"
86
  "@
87
   stzx.\t%1,%2,%0
88
   stz.\t%1,%0
89
   stnz.\t%2,%0"
90
  [(set_attr "flags" "n,n,n")])
91
 
92
(define_insn_and_split "stzx_reversed_"
93
  [(set (match_operand:QHI 0 "m32c_r0_operand" "")
94
        (if_then_else:QHI (ne (reg:CC FLG_REGNO) (const_int 0))
95
                         (match_operand:QHI 1 "const_int_operand" "")
96
                         (match_operand:QHI 2 "const_int_operand" "")))]
97
  "(TARGET_A24 || GET_MODE (operands[0]) == QImode) && reload_completed"
98
  "#"
99
  ""
100
  [(set (match_dup 0)
101
        (if_then_else:QHI (eq (reg:CC FLG_REGNO) (const_int 0))
102
                      (match_dup 2)
103
                      (match_dup 1)))]
104
  ""
105
  )
106
 
107
 
108
(define_insn "cmp_op"
109
  [(set (reg:CC FLG_REGNO)
110
        (compare (match_operand:QHPSI 0 "mra_operand" "RraSd")
111
                 (match_operand:QHPSI 1 "mrai_operand" "RraSdi")))]
112
  ""
113
  "* return m32c_output_compare(insn, operands); "
114
  [(set_attr "flags" "oszc")])
115
 
116
(define_expand "cmp"
117
  [(set (reg:CC FLG_REGNO)
118
        (compare (match_operand:QHPSI 0 "mra_operand" "RraSd")
119
                 (match_operand:QHPSI 1 "mrai_operand" "RraSdi")))]
120
  ""
121
  "m32c_pend_compare (operands); DONE;")
122
 
123
(define_insn "b_op"
124
  [(set (pc)
125
        (if_then_else (any_cond (reg:CC FLG_REGNO)
126
                                (const_int 0))
127
                      (label_ref (match_operand 0 ""))
128
                      (pc)))]
129
  ""
130
  "j\t%l0"
131
  [(set_attr "flags" "n")]
132
)
133
 
134
(define_expand "b"
135
  [(set (pc)
136
        (if_then_else (any_cond (reg:CC FLG_REGNO)
137
                                (const_int 0))
138
                      (label_ref (match_operand 0 ""))
139
                      (pc)))]
140
  ""
141
  "m32c_unpend_compare ();"
142
)
143
 
144
;; m32c_conditional_register_usage changes the setcc_gen_code array to
145
;; point to the _24 variants if needed.
146
 
147
;; We need to keep the compare and conditional sets together through
148
;; reload, because reload might need to add address reloads to the
149
;; set, which would clobber the flags.  By keeping them together, the
150
;; reloads get put before the compare, thus preserving the flags.
151
 
152
;; These are the post-split patterns for the conditional sets.
153
 
154
(define_insn "s_op"
155
  [(set (match_operand:QI 0 "register_operand" "=Rqi")
156
        (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
157
  "TARGET_A16 && reload_completed"
158
  "* return m32c_scc_pattern(operands, );")
159
 
160
(define_insn "s_24_op"
161
  [(set (match_operand:HI 0 "mra_operand" "=RhiSd")
162
        (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
163
  "TARGET_A24 && reload_completed"
164
  "sc\t%0"
165
  [(set_attr "flags" "n")]
166
)
167
 
168
;; These are the pre-split patterns for the conditional sets.  Yes,
169
;; there are a lot of permutations.
170
 
171
(define_insn_and_split "s_"
172
  [(set (match_operand:QI 0 "register_operand" "=Rqi")
173
        (any_cond:QI (match_operand:QHPSI 1 "mra_operand" "RraSd")
174
                     (match_operand:QHPSI 2 "mrai_operand" "RraSdi")))]
175
  "TARGET_A16"
176
  "#"
177
  "reload_completed"
178
  [(set (reg:CC FLG_REGNO)
179
        (compare (match_dup 1)
180
                 (match_dup 2)))
181
   (set (match_dup 0)
182
        (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
183
  ""
184
  [(set_attr "flags" "x")]
185
)
186
 
187
(define_insn_and_split "s__24"
188
  [(set (match_operand:HI 0 "mra_nopp_operand" "=RhiSd")
189
        (any_cond:HI (match_operand:QHPSI 1 "mra_operand" "RraSd")
190
                     (match_operand:QHPSI 2 "mrai_operand" "RraSdi")))]
191
  "TARGET_A24"
192
  "#"
193
  "reload_completed"
194
  [(set (reg:CC FLG_REGNO)
195
        (compare (match_dup 1)
196
                 (match_dup 2)))
197
   (set (match_dup 0)
198
        (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
199
  ""
200
  [(set_attr "flags" "x")]
201
)
202
 
203
(define_insn_and_split "movqicc__"
204
  [(set (match_operand:QI 0 "register_operand" "")
205
        (if_then_else:QI (eqne_cond:QI (match_operand:QHPSI 1 "mra_operand" "RraSd")
206
                                       (match_operand:QHPSI 2 "mrai_operand" "RraSdi"))
207
                          (match_operand:QI 3 "const_int_operand" "")
208
                          (match_operand:QI 4 "const_int_operand" "")))]
209
  ""
210
  "#"
211
  "reload_completed"
212
  [(set (reg:CC FLG_REGNO)
213
        (compare (match_dup 1)
214
                 (match_dup 2)))
215
   (set (match_dup 0)
216
        (if_then_else:QI (eqne_cond:QI (reg:CC FLG_REGNO) (const_int 0))
217
                         (match_dup 3)
218
                         (match_dup 4)))]
219
  ""
220
  [(set_attr "flags" "x")]
221
  )
222
 
223
(define_insn_and_split "movhicc__"
224
  [(set (match_operand:HI 0 "register_operand" "")
225
        (if_then_else:HI (eqne_cond:HI (match_operand:QHPSI 1 "mra_operand" "RraSd")
226
                                       (match_operand:QHPSI 2 "mrai_operand" "RraSdi"))
227
                          (match_operand:QI 3 "const_int_operand" "")
228
                          (match_operand:QI 4 "const_int_operand" "")))]
229
  "TARGET_A24"
230
  "#"
231
  "reload_completed"
232
  [(set (reg:CC FLG_REGNO)
233
        (compare (match_dup 1)
234
                 (match_dup 2)))
235
   (set (match_dup 0)
236
        (if_then_else:HI (eqne_cond:HI (reg:CC FLG_REGNO) (const_int 0))
237
                         (match_dup 3)
238
                         (match_dup 4)))]
239
  ""
240
  [(set_attr "flags" "x")]
241
  )
242
 
243
;; And these are the expanders, which read the pending compare
244
;; operands to build a combined insn.
245
 
246
(define_expand "s"
247
  [(set (match_operand:QI 0 "register_operand" "=Rqi")
248
        (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
249
  "TARGET_A16"
250
  "m32c_expand_scc (, operands); DONE;")
251
 
252
(define_expand "s_24"
253
  [(set (match_operand:HI 0 "mra_nopp_operand" "=RhiSd")
254
        (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
255
  "TARGET_A24"
256
  "m32c_expand_scc (, operands); DONE;")
257
 
258
 
259
(define_expand "movqicc"
260
  [(set (match_operand:QI 0 "register_operand" "")
261
        (if_then_else:QI (match_operand 1 "m32c_eqne_operator" "")
262
                         (match_operand:QI 2 "const_int_operand" "")
263
                         (match_operand:QI 3 "const_int_operand" "")))]
264
  ""
265
  "if (m32c_expand_movcc(operands))
266
     FAIL;
267
   DONE;"
268
)
269
 
270
(define_expand "movhicc"
271
  [(set (match_operand:HI 0 "mra_operand" "")
272
        (if_then_else:HI (match_operand 1 "m32c_eqne_operator" "")
273
                         (match_operand:HI 2 "const_int_operand" "")
274
                         (match_operand:HI 3 "const_int_operand" "")))]
275
  "TARGET_A24"
276
  "if (m32c_expand_movcc(operands))
277
     FAIL;
278
   DONE;"
279
)
280
 
281
 
282
;; CMP opcodes subtract two values, set the flags, and discard the
283
;; value.  This pattern recovers the sign of the discarded value based
284
;; on the flags.  Operand 0 is set to -1, 0, or 1.  This is used for
285
;; the cmpstr pattern.  For optimal code, this should be removed if
286
;; followed by a suitable CMP insn (see the peephole following).  This
287
;; pattern is 7 bytes and 5 cycles.  If you don't need specific
288
;; values, a 5/4 pattern can be made with SCGT and BMLT to set the
289
;; appropriate bits.
290
 
291
(define_insn "cond_to_int"
292
  [(set (match_operand:HI 0 "mra_qi_operand" "=Rqi")
293
        (if_then_else:HI (lt (reg:CC FLG_REGNO) (const_int 0))
294
                         (const_int -1)
295
                         (if_then_else:HI (eq (reg:CC FLG_REGNO) (const_int 0))
296
                                          (const_int 0)
297
                                          (const_int -1))))]
298
  "TARGET_A24"
299
  "sceq\t%0\n\tbmgt\t1,%h0\n\tdec.w\t%0"
300
  [(set_attr "flags" "x")]
301
  )
302
 
303
;; A cond_to_int followed by a compare against zero is essentially a no-op.
304
 
305
(define_peephole2
306
  [(set (match_operand:HI 0 "mra_qi_operand" "")
307
        (if_then_else:HI (lt (reg:CC FLG_REGNO) (const_int 0))
308
                         (const_int -1)
309
                         (if_then_else:HI (eq (reg:CC FLG_REGNO) (const_int 0))
310
                                          (const_int 0)
311
                                          (const_int -1))))
312
   (set (reg:CC FLG_REGNO)
313
        (compare (match_operand:HI 1 "mra_qi_operand" "")
314
                 (const_int 0)))
315
   ]
316
  "rtx_equal_p(operands[0], operands[1])"
317
  [(const_int 1)]
318
  "")

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.