1 ;; Machine Description for Renesas RL78 processors
2 ;; Copyright (C)
2011-
2015 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version
3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; The insns in this file correspond to the actual opcodes the RL78
22 ;; can issue with real registers. All insns in here should be
23 ;; conditional on rl78_real_insns_ok() returning true, and should
24 ;; allow virtual registers in their predicates - the reorg pass that
25 ;; allocates physical registers uses the constraints to select
26 ;; registers, but insns with virtual registers MUST match one of these
27 ;; patterns - other than the constraints - so that the operand info is
28 ;; properly set up for the alloc pass.
30 ;;---------- Moving ------------------------
32 (define_insn "movqi_es"
34 (match_operand:QI
0 "register_operand" "a"))]
39 (define_insn "movqi_from_es"
40 [(set (match_operand:QI
0 "register_operand" "=a")
46 (define_insn "movqi_cs"
48 (match_operand:QI
0 "register_operand" "a"))]
53 (define_insn "*movqi_real"
54 [(set (match_operand:QI
0 "nonimmediate_operand" "=g,RaxbcWab,RaxbcWab,a, bcx,R, WabWd2WhlWh1WhbWbcWs1v, bcx")
55 (match_operand
1 "general_operand" "
0,K, M, RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a, R"))]
56 "rl78_real_insns_ok ()"
68 (define_insn "*movhi_real"
69 [(set (match_operand:HI
0 "nonimmediate_operand" "=g,AB,AB,RSv,A,BDTvSWabWd2WdeWhlWh1WbcWs1, BDT,ABDT,v")
70 (match_operand:HI
1 "general_operand" "
0,K, M, i, BDTvSWabWd2WdeWh1WhlWbcWs1,A, BDT,vS, ABDT"))]
71 "rl78_real_insns_ok ()"
84 ;;---------- Conversions ------------------------
86 (define_insn "*zero_extendqihi2_real"
87 [(set (match_operand:HI
0 "nonimmediate_operand" "=rv,A")
88 (zero_extend:HI (match_operand:QI
1 "general_operand" "
0,a")))]
89 "rl78_real_insns_ok ()"
92 mov
\tx, a \;mov
\ta, #
0"
95 (define_insn "*extendqihi2_real"
96 [(set (match_operand:HI
0 "nonimmediate_operand" "=A,A")
97 (sign_extend:HI (match_operand:QI
1 "general_operand" "x,a")))]
98 "rl78_real_insns_ok ()"
100 shlw
\t%
0,
8 \;sarw
\t%
0,
8
104 ;;---------- Arithmetic ------------------------
106 (define_insn "*addqi3_real"
107 [(set (match_operand:QI
0 "nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl")
108 (plus:QI (match_operand:QI
1 "general_operand" "%
0,
0,
0,
0")
109 (match_operand:QI
2 "general_operand" "K,L,RWhlWh1Wabi,a")))
111 "rl78_real_insns_ok ()"
119 (define_insn "*addhi3_real"
120 [(set (match_operand:HI
0 "nonimmediate_operand" "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A")
121 (plus:HI (match_operand:HI
1 "general_operand" "%
0,
0,
0,
0,
0,
0,
0,S")
122 (match_operand:HI
2 "general_operand" "K,L,N,O,RWh1WhlWabiv,Int8,J,Ri")))
124 "rl78_real_insns_ok ()"
133 movw
\t%
0, %
1 \;addw
\t%
0, %
2"
136 (define_insn "*addqihi3a_real"
137 [(set (match_operand:HI
0 "register_operand" "=r")
138 (plus:HI (zero_extend:HI (match_operand:QI
1 "register_operand" "r"))
139 (match_operand:HI
2 "register_operand" "
0")))
141 "rl78_real_insns_ok ()"
142 "add
\t%q0, %q1 \;addc
\t%Q0, #
0"
145 (define_insn "*subqi3_real"
146 [(set (match_operand:QI
0 "nonimmediate_operand" "=a,R,v")
147 (minus:QI (match_operand:QI
1 "general_operand" "
0,
0,
0")
148 (match_operand:QI
2 "general_operand" "RiWabWhbWh1Whl,a,i")))
150 "rl78_real_insns_ok ()"
154 (define_insn "*subhi3_real"
155 [(set (match_operand:HI
0 "nonimmediate_operand" "=A,S")
156 (minus:HI (match_operand:HI
1 "general_operand" "
0,
0")
157 (match_operand:HI
2 "general_operand" "iBDTWabWh1v,i")))
159 "rl78_real_insns_ok ()"
163 (define_insn "*umulhi3_shift_real"
164 [(set (match_operand:HI
0 "register_operand" "=A,A")
165 (mult:HI (match_operand:HI
1 "rl78_nonfar_operand" "
0,
0")
166 (match_operand:HI
2 "rl78_24_operand" "N,i")))]
167 "rl78_real_insns_ok () && !TARGET_G10"
173 (define_insn "*umulqihi3_real"
174 [(set (match_operand:HI
0 "nonimmediate_operand" "=A")
175 (mult:HI (zero_extend:HI (match_operand:QI
1 "general_operand" "%a"))
176 (zero_extend:HI (match_operand:QI
2 "general_operand" "x"))))]
177 "rl78_real_insns_ok () && !TARGET_G10"
181 (define_insn "*andqi3_real"
182 [(set (match_operand:QI
0 "nonimmediate_operand" "=A,R,v")
183 (and:QI (match_operand:QI
1 "general_operand" "%
0,
0,
0")
184 (match_operand:QI
2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
186 "rl78_real_insns_ok ()"
190 (define_insn "*iorqi3_real"
191 [(set (match_operand:QI
0 "nonimmediate_operand" "=A,R,v")
192 (ior:QI (match_operand:QI
1 "general_operand" "%
0,
0,
0")
193 (match_operand:QI
2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
195 "rl78_real_insns_ok ()"
199 (define_insn "*xorqi3_real"
200 [(set (match_operand:QI
0 "nonimmediate_operand" "=A,R,v")
201 (xor:QI (match_operand:QI
1 "general_operand" "%
0,
0,
0")
202 (match_operand
2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
204 "rl78_real_insns_ok ()"
208 ;;---------- Shifts ------------------------
210 (define_insn "*ashlqi3_real"
211 [(set (match_operand:QI
0 "nonimmediate_operand" "=abc,a,a")
212 (ashift:QI (match_operand:QI
1 "general_operand" "
0,
0,
0")
213 (match_operand:QI
2 "general_operand" "Int3,bc,dehl")))
215 "rl78_real_insns_ok ()"
218 cmp0 %
2\; bz $
2f\;
1: shl
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:
219 inc %
2\;dec %
2\;bz $
2f\;
1: shl
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:"
222 (define_insn "*ashlhi3_real"
223 [(set (match_operand:HI
0 "nonimmediate_operand" "=AB,A,A")
224 (ashift:HI (match_operand:HI
1 "general_operand" "
0,
0,
0")
225 (match_operand:QI
2 "general_operand" "P,bc,dehl")))
227 "rl78_real_insns_ok ()"
230 cmp0 %
2\; bz $
2f\;
1: shlw
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:
231 inc %
2\;dec %
2\;bz $
2f\;
1: shlw
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:"
236 (define_insn "*ashrqi3_real"
237 [(set (match_operand:QI
0 "nonimmediate_operand" "=abc,a,a")
238 (ashiftrt:QI (match_operand:QI
1 "general_operand" "
0,
0,
0")
239 (match_operand:QI
2 "general_operand" "Int3,bc,dehl")))
241 "rl78_real_insns_ok ()"
244 cmp0 %
2\; bz $
2f\;
1: sar
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:
245 inc %
2\;dec %
2\;bz $
2f\;
1: sar
\t%
0,
1\;dec %
2 \;bnz $
1b\;
2:"
248 (define_insn "*ashrhi3_real"
249 [(set (match_operand:HI
0 "nonimmediate_operand" "=AB,A,A")
250 (ashiftrt:HI (match_operand:HI
1 "general_operand" "
0,
0,
0")
251 (match_operand:QI
2 "general_operand" "P,bc,dehl")))
253 "rl78_real_insns_ok ()"
256 cmp0 %
2\; bz $
2f\;
1: sarw
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:
257 inc %
2\;dec %
2\;bz $
2f\;
1: sarw
\t%
0,
1\;dec %
2\;bnz $
1b\;
2:"
262 (define_insn "*lshrqi3_real"
263 [(set (match_operand:QI
0 "nonimmediate_operand" "=abc,a,a")
264 (lshiftrt:QI (match_operand:QI
1 "general_operand" "
0,
0,
0")
265 (match_operand:QI
2 "general_operand" "Int3,bc,dehl")))
267 "rl78_real_insns_ok ()"
270 cmp0 %
2\; bz $
2f\;
1: shr
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:
271 inc %
2\;dec %
2\;bz $
2f\;
1: shr
\t%
0,
1\;dec %
2\;bnz $
1b\;
2:"
274 (define_insn "*lshrhi3_real"
275 [(set (match_operand:HI
0 "nonimmediate_operand" "=AB,A,A")
276 (lshiftrt:HI (match_operand:HI
1 "general_operand" "
0,
0,
0")
277 (match_operand:QI
2 "general_operand" "P,bc,dehl")))
279 "rl78_real_insns_ok ()"
282 cmp0 %
2\; bz $
2f\;
1: shrw
\t%
0,
1 \;dec %
2 \;bnz $
1b\;
2:
283 inc %
2\;dec %
2\;bz $
2f\;
1: shrw
\t%
0,
1\;dec %
2\;bnz $
1b\;
2:"
286 ;;---------- Branching ------------------------
288 (define_insn "*indirect_jump_real"
290 (match_operand:HI
0 "nonimmediate_operand" "A"))]
291 "rl78_real_insns_ok ()"
297 (label_ref (match_operand
0 "" "")))]
299 ;; $rel8, $!rel16, !abs16, !!abs20
303 (define_insn "*call_real"
304 [(call (match_operand:HI
0 "memory_operand" "Wab,Wca")
305 (match_operand
1 "" ""))]
306 "rl78_real_insns_ok ()"
312 (define_insn "*call_value_real"
313 [(set (match_operand
0 "register_operand" "=v,v")
314 (call (match_operand:HI
1 "memory_operand" "Wab,Wca")
315 (match_operand
2 "" "")))]
316 "rl78_real_insns_ok ()"
322 (define_insn "*cbranchqi4_real_signed"
323 [(set (pc) (if_then_else
324 (match_operator
0 "rl78_cmp_operator_signed"
325 [(match_operand:QI
1 "general_operand" "A,A,A")
326 (match_operand:QI
2 "general_operand" "ISqi,i,v")])
327 (label_ref (match_operand
3 "" ""))
329 "rl78_real_insns_ok ()"
331 cmp
\t%
1, %
2 \;xor1 CY,%
1.7\;not1 CY\;sk%C0 \;br
\t!!%
3
332 cmp
\t%
1, %
2 \;xor1 CY,%
1.7\;sk%C0 \;br
\t!!%
3
333 cmp
\t%
1, %
2 \;xor1 CY,%
1.7\;xor1 CY,%
2.7\;sk%C0 \;br
\t!!%
3"
336 (define_insn "*cbranchqi4_real"
337 [(set (pc) (if_then_else
338 (match_operator
0 "rl78_cmp_operator_real"
339 [(match_operand:QI
1 "general_operand" "Wabvaxbc,a, v,bcdehl")
340 (match_operand:QI
2 "general_operand" "M, irvWabWhlWh1Whb,i,a")])
341 (label_ref (match_operand
3 "" ""))
343 "rl78_real_insns_ok ()"
345 cmp0
\t%
1 \;sk%C0 \;br
\t!!%
3
346 cmp
\t%
1, %
2 \;sk%C0 \;br
\t!!%
3
347 cmp
\t%
1, %
2 \;sk%C0 \;br
\t!!%
3
348 cmp
\t%
1, %
2 \;sk%C0 \;br
\t!!%
3"
351 (define_insn "*cbranchhi4_real_signed"
352 [(set (pc) (if_then_else
353 (match_operator
0 "rl78_cmp_operator_signed"
354 [(match_operand:HI
1 "general_operand" "A,A,A,vR")
355 (match_operand:HI
2 "general_operand" "IShi,i,v,
1")])
356 (label_ref (match_operand
3))
358 "rl78_real_insns_ok ()"
360 cmpw
\t%
1, %
2 \;xor1 CY,%Q1.7\;not1 CY\;sk%C0 \;br
\t!!%
3
361 cmpw
\t%
1, %
2 \;xor1 CY,%Q1.7\;sk%C0 \;br
\t!!%
3
362 cmpw
\t%
1, %
2 \;xor1 CY,%Q1.7\;xor1 CY,%Q2.7\;sk%C0 \;br
\t!!%
3
366 (define_insn "cbranchhi4_real"
367 [(set (pc) (if_then_else
368 (match_operator
0 "rl78_cmp_operator_real"
369 [(match_operand:HI
1 "general_operand" "A,vR")
370 (match_operand:HI
2 "general_operand" "iBDTvWabWhlWh1,
1")])
371 (label_ref (match_operand
3 "" ""))
373 "rl78_real_insns_ok ()"
375 cmpw
\t%
1, %
2 \;sk%C0 \;br
\t!!%
3
379 (define_insn "cbranchhi4_real_inverted"
380 [(set (pc) (if_then_else
381 (match_operator
0 "rl78_cmp_operator_real"
382 [(match_operand:HI
1 "general_operand" "A")
383 (match_operand:HI
2 "general_operand" "iBDTvWabWhlWh1")])
385 (label_ref (match_operand
3 "" ""))))]
386 "rl78_real_insns_ok ()"
387 "cmpw
\t%
1, %
2 \;sk%C0 \;br
\t!!%
3"
390 (define_insn "*cbranchsi4_real_lt"
391 [(set (pc) (if_then_else
392 (lt (match_operand:SI
0 "general_operand" "U,vWabWhlWh1")
394 (label_ref (match_operand
1 "" ""))
396 (clobber (reg:HI AX_REG))
398 "rl78_real_insns_ok ()"
400 mov a, %E0 \;mov1 CY,a
.7 \;sknc \;br
\t!!%
1
401 mov1 CY,%E0.7 \;sknc \;br
\t!!%
1"
404 (define_insn "*cbranchsi4_real_ge"
405 [(set (pc) (if_then_else
406 (ge (match_operand:SI
0 "general_operand" "U,vWabWhlWh1")
408 (label_ref (match_operand
1 "" ""))
410 (clobber (reg:HI AX_REG))
412 "rl78_real_insns_ok ()"
414 mov a, %E0 \;mov1 CY,a
.7 \;skc \;br
\t!!%
1
415 mov1 CY,%E0.7 \;skc \;br
\t!!%
1"
418 (define_insn "*cbranchsi4_real_signed"
419 [(set (pc) (if_then_else
420 (match_operator
0 "rl78_cmp_operator_signed"
421 [(match_operand:SI
1 "general_operand" "vU,vU,vU,i,i")
422 (match_operand:SI
2 "nonmemory_operand" "ISsi,i,v,S,v")])
423 (label_ref (match_operand
3 "" ""))
425 (clobber (reg:HI AX_REG))
427 "rl78_real_insns_ok ()"
429 movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a
.7\;not1 CY\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br
\t!!%
3
430 movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a
.7\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br
\t!!%
3
431 movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a
.7\;xor1 CY,%E2.7\;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br
\t!!%
3
432 movw ax, %H1\; cmpw ax, %H2\; xor1 CY, a
.7\; not1 CY\; movw ax, %h1 \;sknz\; cmpw ax, %h2 \;sk%
0 \;br
\t!!%
3
433 movw ax, %H1\; cmpw ax, %H2\; xor1 CY, a
.7\; movw ax, %h1\; sknz\; cmpw ax, %h2\; sk%
0\; br
\t!!%
3"
436 (define_insn "*cbranchsi4_real"
437 [(set (pc) (if_then_else
438 (match_operator
0 "rl78_cmp_operator_real"
439 [(match_operand:SI
1 "general_operand" "vUi")
440 (match_operand:SI
2 "general_operand" "iWhlWh1v")])
441 (label_ref (match_operand
3 "" ""))
443 (clobber (reg:HI AX_REG))
445 "rl78_real_insns_ok ()"
446 "movw ax,%H1 \;cmpw ax, %H2 \;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br
\t!!%
3"
449 ;; Peephole to match:
451 ;; (set (mem (sp)) (ax))
452 ;; (set (ax) (mem (sp)))
454 ;; (set (mem (plus (sp) (const)) (ax))
455 ;; (set (ax) (mem (plus (sp) (const))))
457 ;; which can be generated as the last instruction of the conversion
458 ;; of one virtual insn into a real insn and the first instruction of
459 ;; the conversion of the following virtual insn.
462 [(set (match_operand:HI
0 "rl78_stack_based_mem")
467 [(set (match_dup
0) (reg:HI AX_REG))]
470 ;; Bit test and branch insns.
472 ;; NOTE: These patterns will work for bits in other places, not just A.
476 (if_then_else (eq (and (reg:QI A_REG)
477 (match_operand
0 "immediate_operand" "n"))
479 (label_ref (match_operand
1 "" ""))
487 (if_then_else (ne (and (reg:QI A_REG)
488 (match_operand
0 "immediate_operand" "n"))
490 (label_ref (match_operand
1 "" ""))
496 ;; NOTE: These peepholes are fragile. They rely upon GCC generating
497 ;; a specific sequence on insns, based upon examination of test code.
498 ;; Improvements to GCC or using code other than the test code can result
499 ;; in the peephole not matching and the optimization being missed.
502 [(set (match_operand:QI
0 "register_operand") (reg:QI A_REG))
503 (set (match_dup
0) (and:QI (match_dup
0) (match_operand
1 "immediate_operand")))
504 (set (pc) (if_then_else (eq (match_dup
0) (const_int
0))
505 (label_ref (match_operand
2 ""))
507 "peep2_regno_dead_p (
3, REGNO (operands[
0]))
508 && exact_log2 (INTVAL (operands[
1])) >=
0"
509 [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup
1)) (const_int
0))
510 (label_ref (match_dup
2))
515 [(set (match_operand:QI
0 "register_operand") (reg:QI A_REG))
516 (set (match_dup
0) (and:QI (match_dup
0) (match_operand
1 "immediate_operand")))
517 (set (pc) (if_then_else (ne (match_dup
0) (const_int
0))
518 (label_ref (match_operand
2 ""))
520 "peep2_regno_dead_p (
3, REGNO (operands[
0]))
521 && exact_log2 (INTVAL (operands[
1])) >=
0"
522 [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup
1)) (const_int
0))
523 (label_ref (match_dup
2))
527 ;; Eliminate needless register copies.
529 [(set (match_operand:HI
0 "register_operand") (match_operand:HI
1 "register_operand"))
530 (set (match_operand:HI
2 "register_operand") (match_dup
0))]
531 "peep2_regno_dead_p (
2, REGNO (operands[
0]))
532 && (REGNO (operands[
1]) <
8 || REGNO (operands[
2]) <
8)"
533 [(set (match_dup
2) (match_dup
1))]
536 ;; Eliminate needless register copying when performing bit manipulations.
538 [(set (match_operand:QI
0 "register_operand") (reg:QI A_REG))
539 (set (match_dup
0) (ior:QI (match_dup
0) (match_operand
1 "immediate_operand")))
540 (set (reg:QI A_REG) (match_dup
0))]
541 "peep2_regno_dead_p (
3, REGNO (operands[
0]))"
542 [(set (reg:QI A_REG) (ior:QI (reg:QI A_REG) (match_dup
1)))]
546 [(set (match_operand:QI
0 "register_operand") (reg:QI A_REG))
547 (set (match_dup
0) (xor:QI (match_dup
0) (match_operand
1 "immediate_operand")))
548 (set (reg:QI A_REG) (match_dup
0))]
549 "peep2_regno_dead_p (
3, REGNO (operands[
0]))"
550 [(set (reg:QI A_REG) (xor:QI (reg:QI A_REG) (match_dup
1)))]
554 [(set (match_operand:QI
0 "register_operand") (reg:QI A_REG))
555 (set (match_dup
0) (and:QI (match_dup
0) (match_operand
1 "immediate_operand")))
556 (set (reg:QI A_REG) (match_dup
0))]
557 "peep2_regno_dead_p (
3, REGNO (operands[
0]))"
558 [(set (reg:QI A_REG) (and:QI (reg:QI A_REG) (match_dup
1)))]
561 (define_insn "*negandhi3_real"
562 [(set (match_operand:HI
0 "register_operand" "=A")
563 (and:HI (neg:HI (match_operand:HI
1 "register_operand" "
0"))
564 (match_operand:HI
2 "immediate_operand" "n")))
566 "rl78_real_insns_ok ()"
567 "xor a, #
0xff @ xch a, x @ xor a, #
0xff @ xch a, x @ addw ax, #
1 @ and a, %Q2 @ xch a, x @ and a, %q2 @ xch a, x"