1 ;; Machine Description for Renesas RL78 processors
2 ;; Copyright (C) 2011-2014 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_cs"
41 (match_operand:QI 0 "register_operand" "a"))]
46 (define_insn "*movqi_real"
47 [(set (match_operand:QI 0 "nonimmediate_operand" "=g,RaxbcWab,RaxbcWab,a, bcx,R, WabWd2WhlWh1WhbWbcWs1v, bcx")
48 (match_operand 1 "general_operand" "0,K, M, RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a, R"))]
49 "rl78_real_insns_ok ()"
61 (define_insn "*movhi_real"
62 [(set (match_operand:HI 0 "nonimmediate_operand" "=g,AB,AB,RSv,A,BDTvSWabWd2WdeWhlWh1WbcWs1, BDT,ABDT,v")
63 (match_operand:HI 1 "general_operand" " 0,K, M, i, BDTvSWabWd2WdeWh1WhlWbcWs1,A, BDT,vS, ABDT"))]
64 "rl78_real_insns_ok ()"
77 ;;---------- Conversions ------------------------
79 (define_insn "*zero_extendqihi2_real"
80 [(set (match_operand:HI 0 "nonimmediate_operand" "=rv,A")
81 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,a")))]
82 "rl78_real_insns_ok ()"
85 mov\tx, a \;mov\ta, #0"
88 (define_insn "*extendqihi2_real"
89 [(set (match_operand:HI 0 "nonimmediate_operand" "=A,A")
90 (sign_extend:HI (match_operand:QI 1 "general_operand" "x,a")))]
91 "rl78_real_insns_ok ()"
93 shlw\t%0, 8 \;sarw\t%0, 8
97 ;;---------- Arithmetic ------------------------
99 (define_insn "*addqi3_real"
100 [(set (match_operand:QI 0 "nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl")
101 (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
102 (match_operand:QI 2 "general_operand" "K,L,RWhlWh1Wabi,a")))
104 "rl78_real_insns_ok ()"
112 (define_insn "*addhi3_real"
113 [(set (match_operand:HI 0 "nonimmediate_operand" "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A")
114 (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0,0,S")
115 (match_operand:HI 2 "general_operand" "K,L,N,O,RWh1WhlWabiv,Int8,J,Ri")))
117 "rl78_real_insns_ok ()"
126 movw\t%0, %1 \;addw\t%0, %2"
129 (define_insn "*addqihi3a_real"
130 [(set (match_operand:HI 0 "register_operand" "=r")
131 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
132 (match_operand:HI 2 "register_operand" "0")))
134 "rl78_real_insns_ok ()"
135 "add\t%q0, %q1 \;addc\t%Q0, #0"
138 (define_insn "*subqi3_real"
139 [(set (match_operand:QI 0 "nonimmediate_operand" "=a,R,v")
140 (minus:QI (match_operand:QI 1 "general_operand" "0,0,0")
141 (match_operand:QI 2 "general_operand" "RiWabWhbWh1Whl,a,i")))
143 "rl78_real_insns_ok ()"
147 (define_insn "*subhi3_real"
148 [(set (match_operand:HI 0 "nonimmediate_operand" "=A,S")
149 (minus:HI (match_operand:HI 1 "general_operand" "0,0")
150 (match_operand:HI 2 "general_operand" "iBDTWabWh1v,i")))
152 "rl78_real_insns_ok ()"
156 (define_insn "*umulhi3_shift_real"
157 [(set (match_operand:HI 0 "register_operand" "=A,A")
158 (mult:HI (match_operand:HI 1 "rl78_nonfar_operand" "0,0")
159 (match_operand:HI 2 "rl78_24_operand" "N,i")))]
160 "rl78_real_insns_ok () && !TARGET_G10"
166 (define_insn "*umulqihi3_real"
167 [(set (match_operand:HI 0 "nonimmediate_operand" "=A")
168 (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%a"))
169 (zero_extend:HI (match_operand:QI 2 "general_operand" "x"))))]
170 "rl78_real_insns_ok () && !TARGET_G10"
174 (define_insn "*andqi3_real"
175 [(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
176 (and:QI (match_operand:QI 1 "general_operand" "%0,0,0")
177 (match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
179 "rl78_real_insns_ok ()"
183 (define_insn "*iorqi3_real"
184 [(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
185 (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0")
186 (match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
188 "rl78_real_insns_ok ()"
192 (define_insn "*xorqi3_real"
193 [(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
194 (xor:QI (match_operand:QI 1 "general_operand" "%0,0,0")
195 (match_operand 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
197 "rl78_real_insns_ok ()"
201 ;;---------- Shifts ------------------------
203 (define_insn "*ashlqi3_real"
204 [(set (match_operand:QI 0 "nonimmediate_operand" "=abc,a,a")
205 (ashift:QI (match_operand:QI 1 "general_operand" "0,0,0")
206 (match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
208 "rl78_real_insns_ok ()"
211 cmp0 %2\; bz $2f\; 1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:
212 inc %2\;dec %2\;bz $2f\;1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:"
215 (define_insn "*ashlhi3_real"
216 [(set (match_operand:HI 0 "nonimmediate_operand" "=AB,A,A")
217 (ashift:HI (match_operand:HI 1 "general_operand" "0,0,0")
218 (match_operand:QI 2 "general_operand" "P,bc,dehl")))
220 "rl78_real_insns_ok ()"
223 cmp0 %2\; bz $2f\; 1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:
224 inc %2\;dec %2\;bz $2f\;1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:"
229 (define_insn "*ashrqi3_real"
230 [(set (match_operand:QI 0 "nonimmediate_operand" "=abc,a,a")
231 (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0,0")
232 (match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
234 "rl78_real_insns_ok ()"
237 cmp0 %2\; bz $2f\; 1: sar\t%0, 1 \;dec %2 \;bnz $1b\;2:
238 inc %2\;dec %2\;bz $2f\;1: sar\t%0, 1\;dec %2 \;bnz $1b\;2:"
241 (define_insn "*ashrhi3_real"
242 [(set (match_operand:HI 0 "nonimmediate_operand" "=AB,A,A")
243 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0,0,0")
244 (match_operand:QI 2 "general_operand" "P,bc,dehl")))
246 "rl78_real_insns_ok ()"
249 cmp0 %2\; bz $2f\; 1: sarw\t%0, 1 \;dec %2 \;bnz $1b\;2:
250 inc %2\;dec %2\;bz $2f\;1: sarw\t%0, 1\;dec %2\;bnz $1b\;2:"
255 (define_insn "*lshrqi3_real"
256 [(set (match_operand:QI 0 "nonimmediate_operand" "=abc,a,a")
257 (lshiftrt:QI (match_operand:QI 1 "general_operand" "0,0,0")
258 (match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
260 "rl78_real_insns_ok ()"
263 cmp0 %2\; bz $2f\; 1: shr\t%0, 1 \;dec %2 \;bnz $1b\;2:
264 inc %2\;dec %2\;bz $2f\;1: shr\t%0, 1\;dec %2\;bnz $1b\;2:"
267 (define_insn "*lshrhi3_real"
268 [(set (match_operand:HI 0 "nonimmediate_operand" "=AB,A,A")
269 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0,0")
270 (match_operand:QI 2 "general_operand" "P,bc,dehl")))
272 "rl78_real_insns_ok ()"
275 cmp0 %2\; bz $2f\; 1: shrw\t%0, 1 \;dec %2 \;bnz $1b\;2:
276 inc %2\;dec %2\;bz $2f\;1: shrw\t%0, 1\;dec %2\;bnz $1b\;2:"
279 ;;---------- Branching ------------------------
281 (define_insn "*indirect_jump_real"
283 (match_operand:HI 0 "nonimmediate_operand" "A"))]
284 "rl78_real_insns_ok ()"
290 (label_ref (match_operand 0 "" "")))]
292 ;; $rel8, $!rel16, !abs16, !!abs20
296 (define_insn "*call_real"
297 [(call (match_operand:HI 0 "memory_operand" "Wab,Wca")
298 (match_operand 1 "" ""))]
299 "rl78_real_insns_ok ()"
305 (define_insn "*call_value_real"
306 [(set (match_operand 0 "register_operand" "=v,v")
307 (call (match_operand:HI 1 "memory_operand" "Wab,Wca")
308 (match_operand 2 "" "")))]
309 "rl78_real_insns_ok ()"
315 (define_insn "*cbranchqi4_real_signed"
316 [(set (pc) (if_then_else
317 (match_operator 0 "rl78_cmp_operator_signed"
318 [(match_operand:QI 1 "general_operand" "A,A,A")
319 (match_operand:QI 2 "general_operand" "ISqi,i,v")])
320 (label_ref (match_operand 3 "" ""))
322 "rl78_real_insns_ok ()"
324 cmp\t%1, %2 \;xor1 CY,%1.7\;not1 CY\;sk%C0 \;br\t!!%3
325 cmp\t%1, %2 \;xor1 CY,%1.7\;sk%C0 \;br\t!!%3
326 cmp\t%1, %2 \;xor1 CY,%1.7\;xor1 CY,%2.7\;sk%C0 \;br\t!!%3"
329 (define_insn "*cbranchqi4_real"
330 [(set (pc) (if_then_else
331 (match_operator 0 "rl78_cmp_operator_real"
332 [(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl")
333 (match_operand:QI 2 "general_operand" "M, irvWabWhlWh1Whb,i,a")])
334 (label_ref (match_operand 3 "" ""))
336 "rl78_real_insns_ok ()"
338 cmp0\t%1 \;sk%C0 \;br\t!!%3
339 cmp\t%1, %2 \;sk%C0 \;br\t!!%3
340 cmp\t%1, %2 \;sk%C0 \;br\t!!%3
341 cmp\t%1, %2 \;sk%C0 \;br\t!!%3"
344 (define_insn "*cbranchhi4_real_signed"
345 [(set (pc) (if_then_else
346 (match_operator 0 "rl78_cmp_operator_signed"
347 [(match_operand:HI 1 "general_operand" "A,A,A,vR")
348 (match_operand:HI 2 "general_operand" "IShi,i,v,1")])
349 (label_ref (match_operand 3))
351 "rl78_real_insns_ok ()"
353 cmpw\t%1, %2 \;xor1 CY,%Q1.7\;not1 CY\;sk%C0 \;br\t!!%3
354 cmpw\t%1, %2 \;xor1 CY,%Q1.7\;sk%C0 \;br\t!!%3
355 cmpw\t%1, %2 \;xor1 CY,%Q1.7\;xor1 CY,%Q2.7\;sk%C0 \;br\t!!%3
359 (define_insn "cbranchhi4_real"
360 [(set (pc) (if_then_else
361 (match_operator 0 "rl78_cmp_operator_real"
362 [(match_operand:HI 1 "general_operand" "A,vR")
363 (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1,1")])
364 (label_ref (match_operand 3 "" ""))
366 "rl78_real_insns_ok ()"
368 cmpw\t%1, %2 \;sk%C0 \;br\t!!%3
372 (define_insn "cbranchhi4_real_inverted"
373 [(set (pc) (if_then_else
374 (match_operator 0 "rl78_cmp_operator_real"
375 [(match_operand:HI 1 "general_operand" "A")
376 (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1")])
378 (label_ref (match_operand 3 "" ""))))]
379 "rl78_real_insns_ok ()"
380 "cmpw\t%1, %2 \;sk%C0 \;br\t!!%3"
383 (define_insn "*cbranchsi4_real_lt"
384 [(set (pc) (if_then_else
385 (lt (match_operand:SI 0 "general_operand" "U,vWabWhlWh1")
387 (label_ref (match_operand 1 "" ""))
389 (clobber (reg:HI AX_REG))
391 "rl78_real_insns_ok ()"
393 mov a, %E0 \;mov1 CY,a.7 \;sknc \;br\t!!%1
394 mov1 CY,%E0.7 \;sknc \;br\t!!%1"
397 (define_insn "*cbranchsi4_real_ge"
398 [(set (pc) (if_then_else
399 (ge (match_operand:SI 0 "general_operand" "U,vWabWhlWh1")
401 (label_ref (match_operand 1 "" ""))
403 (clobber (reg:HI AX_REG))
405 "rl78_real_insns_ok ()"
407 mov a, %E0 \;mov1 CY,a.7 \;skc \;br\t!!%1
408 mov1 CY,%E0.7 \;skc \;br\t!!%1"
411 (define_insn "*cbranchsi4_real_signed"
412 [(set (pc) (if_then_else
413 (match_operator 0 "rl78_cmp_operator_signed"
414 [(match_operand:SI 1 "general_operand" "vU,vU,vU,i,i")
415 (match_operand:SI 2 "nonmemory_operand" "ISsi,i,v,S,v")])
416 (label_ref (match_operand 3 "" ""))
418 (clobber (reg:HI AX_REG))
420 "rl78_real_insns_ok ()"
422 movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;not1 CY\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3
423 movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3
424 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
425 movw ax, %H1\; cmpw ax, %H2\; xor1 CY, a.7\; not1 CY\; movw ax, %h1 \;sknz\; cmpw ax, %h2 \;sk%0 \;br\t!!%3
426 movw ax, %H1\; cmpw ax, %H2\; xor1 CY, a.7\; movw ax, %h1\; sknz\; cmpw ax, %h2\; sk%0\; br\t!!%3"
429 (define_insn "*cbranchsi4_real"
430 [(set (pc) (if_then_else
431 (match_operator 0 "rl78_cmp_operator_real"
432 [(match_operand:SI 1 "general_operand" "vUi")
433 (match_operand:SI 2 "general_operand" "iWhlWh1v")])
434 (label_ref (match_operand 3 "" ""))
436 (clobber (reg:HI AX_REG))
438 "rl78_real_insns_ok ()"
439 "movw ax,%H1 \;cmpw ax, %H2 \;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3"
442 ;; Peephole to match:
444 ;; (set (mem (sp)) (ax))
445 ;; (set (ax) (mem (sp)))
447 ;; (set (mem (plus (sp) (const)) (ax))
448 ;; (set (ax) (mem (plus (sp) (const))))
450 ;; which can be generated as the last instruction of the conversion
451 ;; of one virtual insn into a real insn and the first instruction of
452 ;; the conversion of the following virtual insn.
455 [(set (match_operand:HI 0 "rl78_stack_based_mem")
460 [(set (match_dup 0) (reg:HI AX_REG))]
463 ;; Bit test and branch insns.
465 ;; NOTE: These patterns will work for bits in other places, not just A.
469 (if_then_else (eq (and (reg:QI A_REG)
470 (match_operand 0 "immediate_operand" "n"))
472 (label_ref (match_operand 1 "" ""))
480 (if_then_else (ne (and (reg:QI A_REG)
481 (match_operand 0 "immediate_operand" "n"))
483 (label_ref (match_operand 1 "" ""))
489 ;; NOTE: These peepholes are fragile. They rely upon GCC generating
490 ;; a specific sequence on insns, based upon examination of test code.
491 ;; Improvements to GCC or using code other than the test code can result
492 ;; in the peephole not matching and the optimization being missed.
495 [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
496 (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand")))
497 (set (pc) (if_then_else (eq (match_dup 0) (const_int 0))
498 (label_ref (match_operand 2 ""))
500 "peep2_regno_dead_p (3, REGNO (operands[0]))
501 && exact_log2 (INTVAL (operands[1])) >= 0"
502 [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup 1)) (const_int 0))
503 (label_ref (match_dup 2))
508 [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
509 (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand")))
510 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
511 (label_ref (match_operand 2 ""))
513 "peep2_regno_dead_p (3, REGNO (operands[0]))
514 && exact_log2 (INTVAL (operands[1])) >= 0"
515 [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup 1)) (const_int 0))
516 (label_ref (match_dup 2))
520 ;; Eliminate needless register copies.
522 [(set (match_operand:HI 0 "register_operand") (match_operand:HI 1 "register_operand"))
523 (set (match_operand:HI 2 "register_operand") (match_dup 0))]
524 "peep2_regno_dead_p (2, REGNO (operands[0]))
525 && (REGNO (operands[1]) < 8 || REGNO (operands[2]) < 8)"
526 [(set (match_dup 2) (match_dup 1))]
529 ;; Eliminate needless register copying when performing bit manipulations.
531 [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
532 (set (match_dup 0) (ior:QI (match_dup 0) (match_operand 1 "immediate_operand")))
533 (set (reg:QI A_REG) (match_dup 0))]
534 "peep2_regno_dead_p (3, REGNO (operands[0]))"
535 [(set (reg:QI A_REG) (ior:QI (reg:QI A_REG) (match_dup 1)))]
539 [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
540 (set (match_dup 0) (xor:QI (match_dup 0) (match_operand 1 "immediate_operand")))
541 (set (reg:QI A_REG) (match_dup 0))]
542 "peep2_regno_dead_p (3, REGNO (operands[0]))"
543 [(set (reg:QI A_REG) (xor:QI (reg:QI A_REG) (match_dup 1)))]
547 [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
548 (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand")))
549 (set (reg:QI A_REG) (match_dup 0))]
550 "peep2_regno_dead_p (3, REGNO (operands[0]))"
551 [(set (reg:QI A_REG) (and:QI (reg:QI A_REG) (match_dup 1)))]
554 (define_insn "*negandhi3_real"
555 [(set (match_operand:HI 0 "register_operand" "=A")
556 (and:HI (neg:HI (match_operand:HI 1 "register_operand" "0"))
557 (match_operand:HI 2 "immediate_operand" "n")))
559 "rl78_real_insns_ok ()"
560 "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"