Fix build on sparc64-linux-gnu.
[official-gcc.git] / gcc / config / rl78 / rl78-real.md
blobd1c3089fb8d76766a6f11d8d72bc7313afbe36f0
1 ;;  Machine Description for Renesas RL78 processors
2 ;;  Copyright (C) 2011-2018 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)
10 ;; any later version.
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 ;; This attribute reflects how the insn alters the Z flag,
31 ;; based upon the value of the it's output.  The default is NO
32 ;; for no change, but other possibilities are UPDATE_Z if it changes
33 ;; the Z flag and CLOBBER if the state of the flag is indeterminate.
34 ;; The CY and AC flags are not set in the same way as the Z flag, so
35 ;; their values are not tracked.
36 (define_attr "update_Z" "no,update_Z,clobber" (const_string "no"))
38 ;;---------- Moving ------------------------
40 (define_insn "movqi_to_es"
41   [(set (reg:QI ES_REG)
42         (match_operand:QI 0 "register_operand" "a"))]
43   ""
44   "mov\tes, %0"
47 (define_insn "movqi_from_es"
48   [(set (match_operand:QI 0 "register_operand" "=a")
49         (reg:QI ES_REG))]
50   ""
51   "mov\t%0, es"
54 (define_insn "movqi_cs"
55   [(set (reg:QI CS_REG)
56         (match_operand:QI 0 "register_operand" "a"))]
57   ""
58   "mov\tcs, %0"
61 (define_insn "*movqi_real"
62   [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=Rv,RaxbcWab,RaxbcWab,a,                               bcx,R,     WabWd2WhlWh1WhbWbcWs1v, bcx,WsaWsf")
63         (match_operand    1 "rl78_general_operand"      "0,K,        M,       RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a,                      R,  i"))]
64   "rl78_real_insns_ok ()"
65   "@
66    ; mov\t%0, %1
67    oneb\t%0
68    clrb\t%0
69    mov\t%0, %1
70    mov\t%0, %1
71    mov\t%0, %1
72    mov\t%0, %1
73    mov\t%0, %S1
74    mov\t%0, %1"
77 (define_insn "*movhi_real"
78   [(set (match_operand:HI 0 "rl78_nonimmediate_operand" "=Rv,AB,AB,RSv,A,BDTvSWabWd2WdeWhlWh1WbcWs1, BDT,ABDT,v")
79         (match_operand:HI 1 "rl78_general_operand"      " 0,K, M, i,  BDTvSWabWd2WdeWh1WhlWbcWs1,A, BDT,vS,  ABDT"))]
80   "rl78_real_insns_ok ()"
81   "@
82    ; movw\t%0, %1
83    onew\t%0
84    clrw\t%0
85    movw\t%0, %1
86    movw\t%0, %1
87    movw\t%0, %1
88    movw\t%0, %S1
89    movw\t%0, %1
90    movw\t%0, %1"
93 (define_insn "*bswaphi2_real"
94   [(set (match_operand:HI           0 "rl78_nonfar_nonimm_operand" "=A,A")
95         (bswap:HI (match_operand:HI 1 "general_operand"  "0,viU")))]
96   "rl78_real_insns_ok ()"
97   "@
98    xch\ta, x
99    movw\tax, %1\n\txch\ta, x"
102 ;;---------- Conversions ------------------------
104 (define_insn "*zero_extendqihi2_real"
105   [(set (match_operand:HI                 0 "nonimmediate_operand" "=Rv,A")
106         (zero_extend:HI (match_operand:QI 1 "general_operand" "0,a")))]
107   "rl78_real_insns_ok ()"
108   "@
109    mov\t%Q0, #0
110    mov\tx, a \;mov\ta, #0"
111   )
113 (define_insn "*extendqihi2_real"
114   [(set (match_operand:HI                 0 "nonimmediate_operand" "=A,A")
115         (sign_extend:HI (match_operand:QI 1 "general_operand" "x,a")))]
116   "rl78_real_insns_ok ()"
117   "@
118    shlw\t%0, 8 \;sarw\t%0, 8
119    sarw\t%0, 8"
120   )
122 ;;---------- Arithmetic ------------------------
124 (define_insn "*addqi3_real"
125   [(set (match_operand:QI          0 "rl78_nonimmediate_operand"  "=RvWabWhlWh1Wsa,RvWabWhlWh1Wsa,a,*bcdehl,Wsa")
126         (plus:QI (match_operand:QI 1 "rl78_general_operand"  "%0,0,0,0,0")
127                  (match_operand:QI 2 "rl78_general_operand" "K,L,RWhlWh1Wabi,a,i")))
128    ]
129   "rl78_real_insns_ok ()"
130   "@
131     inc\t%p0
132     dec\t%p0
133     add\t%0, %2
134     add\t%0, %2
135     add\t%0, %2"
136   [(set (attr "update_Z") (const_string "update_Z"))]
139 (define_insn "*addhi3_real"
140   [(set (match_operand:HI          0 "rl78_nonimmediate_operand"  "=vABDTWhlWh1WabWsa,vABDTWhlWh1WabWsa,v,v,A,S,S,A")
141         (plus:HI (match_operand:HI 1 "rl78_general_operand"  "%0,0,0,0,0,0,0,S")
142                  (match_operand:HI 2 "" "K,L,N,O,RWh1WhlWabiv,Int8Qs8,J,Ri")))
143    ]
144   "rl78_real_insns_ok ()"
145   "@
146    incw\t%p0
147    decw\t%p0
148    incw\t%0 \;incw\t%0
149    decw\t%0 \;decw\t%0
150    addw\t%0, %p2
151    addw\t%0, %2
152    subw\t%0, %m2
153    movw\t%0, %1 \;addw\t%0, %2"
154   [(set_attr "update_Z" "*,*,*,*,update_Z,update_Z,update_Z,update_Z")]
157 (define_insn "*addqihi3a_real"
158   [(set (match_operand:HI                          0 "register_operand" "=R")
159         (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand"  "R"))
160                  (match_operand:HI                 2 "register_operand"  "0")))
161    ]
162   "rl78_real_insns_ok ()"
163   "add\t%q0, %q1 \;addc\t%Q0, #0"
164   [(set (attr "update_Z") (const_string "update_Z"))]
167 (define_insn "*subqi3_real"
168   [(set (match_operand:QI           0 "nonimmediate_operand"  "=a,R,v")
169         (minus:QI (match_operand:QI 1 "general_operand"  "0,0,0")
170                   (match_operand:QI 2 "rl78_general_operand" "RiWabWhbWh1Whl,a,i")))
171    ]
172   "rl78_real_insns_ok ()"
173   "sub\t%0, %2"
174   [(set (attr "update_Z") (const_string "update_Z"))]
177 (define_insn "*subhi3_real"
178   [(set (match_operand:HI           0 "nonimmediate_operand"  "=A,S")
179         (minus:HI (match_operand:HI 1 "general_operand"  "0,0")
180                   (match_operand:HI 2 "rl78_general_operand" "iBDTWabWh1v,i")))
181    ]
182   "rl78_real_insns_ok ()"
183   "subw\t%0, %2"
184   [(set (attr "update_Z") (const_string "update_Z"))]
187 (define_insn "*umulhi3_shift_real"
188   [(set (match_operand:HI 0 "register_operand" "=A,A")
189         (mult:HI (match_operand:HI 1 "rl78_nonfar_operand" "0,0")
190                  (match_operand:HI 2 "rl78_24_operand" "N,i")))]
191   "rl78_real_insns_ok ()"
192   "@
193    shlw\t%0, 1
194    shlw\t%0, 2"
197 (define_insn "*umulqihi3_real"
198   [(set (match_operand:HI 0 "nonimmediate_operand" "=A")
199         (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%a"))
200                  (zero_extend:HI (match_operand:QI 2 "general_operand" "x"))))]
201   "rl78_real_insns_ok ()"
202   "mulu\t%2"
205 (define_insn "*andqi3_real"
206   [(set (match_operand:QI         0 "rl78_nonimmediate_operand"  "=WsfWsaWhlWab,A,R,vWsa")
207         (and:QI (match_operand:QI 1 "rl78_general_operand"       "%0,0,0,0")
208                 (match_operand:QI 2 "rl78_general_operand"       "IBqi,iRvWabWhbWh1Whl,A,i")))
209    ]
210   "rl78_real_insns_ok ()"
211   "@
212    clr1\t%0.%B2
213    and\t%0, %2
214    and\t%0, %2
215    and\t%0, %2"
216   [(set_attr "update_Z" "*,update_Z,update_Z,update_Z")]
219 (define_insn "*iorqi3_real"
220   [(set (match_operand:QI         0 "rl78_nonimmediate_operand"  "=WsfWsaWhlWab,A,R,vWsa")
221         (ior:QI (match_operand:QI 1 "rl78_general_operand"       "%0,0,0,0")
222                 (match_operand:QI 2 "rl78_general_operand"       "Ibqi,iRvWabWhbWh1Whl,A,i")))
223    ]
224   "rl78_real_insns_ok ()"
225   "@
226    set1\t%0.%B2
227    or\t%0, %2
228    or\t%0, %2
229    or\t%0, %2"
230   [(set_attr "update_Z" "*,update_Z,update_Z,update_Z")]
233 (define_insn "*xorqi3_real"
234   [(set (match_operand:QI         0 "rl78_nonimmediate_operand"  "=A,R,vWsa")
235         (xor:QI (match_operand:QI 1 "rl78_general_operand"       "%0,0,0")
236                 (match_operand    2 "rl78_general_operand"       "iRvWabWhbWh1Whl,A,i")))
237    ]
238   "rl78_real_insns_ok ()"
239   "xor\t%0, %2"
240   [(set (attr "update_Z") (const_string "update_Z"))]
243 ;;---------- Shifts ------------------------
245 (define_insn "*ashlqi3_real"
246   [(set (match_operand:QI            0 "nonimmediate_operand"  "=abc,a,a")
247         (ashift:QI (match_operand:QI 1 "general_operand"  "0,0,0")
248                    (match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
249    ]
250   "rl78_real_insns_ok ()"
251   "@
252    shl\t%0, %u2
253    cmp0 %2\; bz $2f\; 1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:
254    inc %2\;dec %2\;bz $2f\;1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:"
255   [(set_attr "update_Z" "*,clobber,clobber")]
258 (define_insn "*ashlhi3_real"
259   [(set (match_operand:HI            0 "nonimmediate_operand"  "=AB,A,A")
260         (ashift:HI (match_operand:HI 1 "general_operand"  "0,0,0")
261                    (match_operand:QI 2 "general_operand" "P,bc,dehl")))
262    ]
263   "rl78_real_insns_ok ()"
264   "@
265    shlw\t%0, %u2
266    cmp0 %2\; bz $2f\; 1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:
267    inc %2\;dec %2\;bz $2f\;1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:"
268   [(set_attr "update_Z" "*,clobber,clobber")]
271 ;;----------
273 (define_insn "*ashrqi3_real"
274   [(set (match_operand:QI              0 "nonimmediate_operand"  "=abc,a,a")
275         (ashiftrt:QI (match_operand:QI 1 "general_operand"  "0,0,0")
276                      (match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
277    ]
278   "rl78_real_insns_ok ()"
279   "@
280    sar\t%0, %u2
281    cmp0 %2\; bz $2f\; 1: sar\t%0, 1 \;dec %2 \;bnz $1b\;2:
282    inc %2\;dec %2\;bz $2f\;1: sar\t%0, 1\;dec %2 \;bnz $1b\;2:"
283   [(set_attr "update_Z" "*,clobber,clobber")]
286 (define_insn "*ashrhi3_real"
287   [(set (match_operand:HI              0 "nonimmediate_operand"  "=AB,A,A")
288         (ashiftrt:HI (match_operand:HI 1 "general_operand"  "0,0,0")
289                      (match_operand:QI 2 "general_operand" "P,bc,dehl")))
290    ]
291   "rl78_real_insns_ok ()"
292   "@
293    sarw\t%0, %u2
294    cmp0 %2\; bz $2f\; 1: sarw\t%0, 1 \;dec %2 \;bnz $1b\;2:
295    inc %2\;dec %2\;bz $2f\;1: sarw\t%0, 1\;dec %2\;bnz $1b\;2:"
296   [(set_attr "update_Z" "*,clobber,clobber")]
299 ;;----------
301 (define_insn "*lshrqi3_real"
302   [(set (match_operand:QI              0 "nonimmediate_operand"  "=abc,a,a")
303         (lshiftrt:QI (match_operand:QI 1 "general_operand"  "0,0,0")
304                      (match_operand:QI 2 "general_operand" "Int3,bc,dehl")))
305    ]
306   "rl78_real_insns_ok ()"
307   "@
308    shr\t%0, %u2
309    cmp0 %2\; bz $2f\; 1: shr\t%0, 1 \;dec %2 \;bnz $1b\;2:
310    inc %2\;dec %2\;bz $2f\;1: shr\t%0, 1\;dec %2\;bnz $1b\;2:"
311   [(set_attr "update_Z" "*,clobber,clobber")]
314 (define_insn "*lshrhi3_real"
315   [(set (match_operand:HI              0 "nonimmediate_operand"  "=AB,A,A")
316         (lshiftrt:HI (match_operand:HI 1 "general_operand"  "0,0,0")
317                      (match_operand:QI 2 "general_operand" "P,bc,dehl")))
318    ]
319   "rl78_real_insns_ok ()"
320   "@
321    shrw\t%0, %u2
322    cmp0 %2\; bz $2f\; 1: shrw\t%0, 1 \;dec %2 \;bnz $1b\;2:
323    inc %2\;dec %2\;bz $2f\;1: shrw\t%0, 1\;dec %2\;bnz $1b\;2:"
324   [(set_attr "update_Z" "*,clobber,clobber")]
327 ;;---------- Branching ------------------------
329 (define_insn "*indirect_jump_real"
330   [(set (pc)
331         (match_operand:HI 0 "nonimmediate_operand" "A"))]
332   "rl78_real_insns_ok ()"
333   "br\t%0"
336 (define_insn "jump"
337   [(set (pc)
338         (label_ref (match_operand 0 "" "")))]
339   ""
340   ;; $rel8, $!rel16, !abs16, !!abs20
341   "br\t!!%0"
344 (define_insn "*call_real"
345   [(call (match_operand:HI 0 "memory_operand" "Wab,Wca")
346          (match_operand 1 "" ""))]
347   "rl78_real_insns_ok ()"
348   "@
349    call\t!!%A0
350    call\t%A0"
351   [(set (attr "update_Z") (const_string "clobber"))]
352   )
354 ;; Peephole to match:
356 ;;      (set (reg1) (reg2))
357 ;;      (call (mem (reg1)))
359 ;;  and replace it with:
361 ;;      (call (mem (reg2)))
363 (define_peephole2
364   [(set (match_operand:HI 0 "register_operand") (match_operand:HI 1 "register_operand"))
365    (call (mem:HI (match_dup 0))(const_int 0))
366   ]
367   "peep2_regno_dead_p (2, REGNO (operands[0]))
368    && REGNO (operands[1]) < 8"
369   [(call (mem:HI (match_dup 1))(const_int 0))
370   ]
373 (define_insn "*call_value_real"
374   [(set (match_operand 0 "register_operand" "=v,v")
375         (call (match_operand:HI 1 "memory_operand" "Wab,Wca")
376               (match_operand 2 "" "")))]
377   "rl78_real_insns_ok ()"
378   "@
379    call\t!!%A1
380    call\t%A1"
381   [(set (attr "update_Z") (const_string "clobber"))]
382   )
384 ;; Peephole to match:
386 ;;      (set (reg1) (reg2))
387 ;;      (set (reg3) (call (mem (reg1))))
389 ;;  and replace it with:
391 ;;      (set (reg3) (call (mem (reg2))))
393 (define_peephole2
394   [(set (match_operand:HI 0 "register_operand") (match_operand:HI 1 "register_operand"))
395    (set (match_operand:HI 2 "register_operand") (call (mem:HI (match_dup 0))(const_int 0)))
396   ]
397   "peep2_regno_dead_p (2, REGNO (operands[0]))
398    && REGNO (operands[1]) < 8"
399   [(set (match_dup 2) (call (mem:HI (match_dup 1))(const_int 0)))
400   ]
403 (define_insn "*cbranchqi4_real_signed"
404   [(set (pc) (if_then_else
405               (match_operator 0 "rl78_cmp_operator_signed"
406                               [(match_operand:QI 1 "general_operand" "A,A,A,A,Wsa")
407                                (match_operand:QI 2 "general_operand" "M,ISqi,i,v,i")])
408               (label_ref (match_operand 3 "" ""))
409               (pc)))]
410   "rl78_real_insns_ok ()"
411   {
412     gcc_assert (GET_CODE (operands[0]) != EQ && GET_CODE (operands[0]) != NE);
414     switch (which_alternative)
415     {
416     case 0: return "cmp0\t%1\; xor1\tCY, %1.7\; sk%C0\; br\t!!%3";
417     case 1: return "cmp\t%1, %2\; xor1\tCY, %1.7\; not1\tCY\; sk%C0\; br\t!!%3";
418     case 4:
419     case 2: return "cmp\t%1, %2\; xor1\tCY, %1.7\; sk%C0\; br\t!!%3";
420     case 3: return "cmp\t%1, %2\; xor1\tCY, %1.7\; xor1\tCY, %2.7\; sk%C0\; br\t!!%3";
421     default: gcc_unreachable ();
422     }
423   }   
424   [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: flags are set based on %1 vs %2
425   )
427 (define_insn "*cbranchqi4_real"
428   [(set (pc) (if_then_else
429               (match_operator 0 "rl78_cmp_operator_real"
430                               [(match_operand:QI 1 "rl78_general_operand" "Wabvaxbc,a,              vWsaWab,bcdehl")
431                                (match_operand:QI 2 "rl78_general_operand" "M,       iRvWabWhlWh1Whb,i,a")])
432               (label_ref (match_operand 3 "" ""))
433               (pc)))]
434   "rl78_real_insns_ok ()"
435   {
436     if (which_alternative == 0)
437       {
438         if (rl78_flags_already_set (operands[0], operands[1]))
439           return "sk%C0\; br\t!!%3\; # zero-comparison eliminated";
440         else
441           return "cmp0\t%1\; sk%C0\; br\t!!%3";
442       }
443     return "cmp\t%1, %2\; sk%C0\; br\t!!%3";
444   }
445   [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: alt 0: flags are set based on %1 vs %2
446   )
448 (define_insn "*cbranchhi4_real_signed"
449   [(set (pc) (if_then_else
450               (match_operator 0 "rl78_cmp_operator_signed"
451                               [(match_operand:HI 1 "general_operand" "A,A,A,vR")
452                                (match_operand:HI 2 "general_operand" "IShi,i,v,1")])
453               (label_ref (match_operand 3))
454               (pc)))]
455   "rl78_real_insns_ok ()"
456   "@
457    cmpw\t%1, %2\; xor1\tCY, %Q1.7\; not1\tCY\; sk%C0\; br\t!!%3
458    cmpw\t%1, %2\; xor1\tCY, %Q1.7\; sk%C0\; br\t!!%3
459    cmpw\t%1, %2\; xor1\tCY, %Q1.7\; xor1\tCY, %Q2.7\; sk%C0\; br\t!!%3
460    %z0\t!!%3"
461   [(set_attr "update_Z" "clobber,clobber,clobber,*")]
462   )
464 (define_insn "cbranchhi4_real"
465   [(set (pc) (if_then_else
466               (match_operator                    0 "rl78_cmp_operator_real"
467                               [(match_operand:HI 1 "general_operand" "A,A,vR")
468                                (match_operand:HI 2 "rl78_general_operand" "M,iBDTvWabWhlWh1,1")])
469               (label_ref (match_operand          3 "" ""))
470               (pc)))]
471   "rl78_real_insns_ok ()"
472   {
473     switch (which_alternative)
474       {
475       case 0:
476         if (rl78_flags_already_set (operands[0], operands[1]))
477           return "sk%C0\; br\t!!%3\; # cmpw eliminated";
478         /* else fall through.  */
479       case 1:
480         return "cmpw\t%1, %2\; sk%C0\; br\t!!%3";
481       case 2:
482         return "%z0\t!!%3";
483       default:
484         gcc_unreachable ();
485       }
486   }
487   [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: Z might be set based on %1 vs %2
488   )
490 (define_insn "cbranchhi4_real_inverted"  
491   [(set (pc) (if_then_else
492               (match_operator                    0 "rl78_cmp_operator_real"
493                               [(match_operand:HI 1 "general_operand" "A,A")
494                                (match_operand:HI 2 "rl78_general_operand" "M,iBDTvWabWhlWh1")])
495               (pc)
496               (label_ref (match_operand          3 "" ""))))]
497   "rl78_real_insns_ok ()"
498   {
499     if (which_alternative == 0 && rl78_flags_already_set (operands[0], operands[1]))
500       return "sk%C0\; br\t!!%3\; # inverted cmpw eliminated";
501     else
502       return "cmpw\t%1, %2\; sk%C0\; br\t!!%3";
503   }
504   [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: flags are set based on %1 vs %2
505   )
507 (define_insn "*cbranchsi4_real_lt"
508   [(set (pc) (if_then_else
509               (lt (match_operand:SI 0 "rl78_general_operand" "U,vWabWhlWh1")
510                   (const_int 0))
511               (label_ref (match_operand 1 "" ""))
512               (pc)))
513    (clobber (reg:HI AX_REG))
514    ]
515   "rl78_real_insns_ok ()"
516   "@
517    mov\ta, %E0\; mov1\tCY, a.7\; sknc\; br\t!!%1
518    mov1\tCY, %E0.7\; sknc\; br\t!!%1"
519   )
521 (define_insn "*cbranchsi4_real_ge"
522   [(set (pc) (if_then_else
523               (ge (match_operand:SI 0 "rl78_general_operand" "U,vWabWhlWh1")
524                   (const_int 0))
525               (label_ref (match_operand 1 "" ""))
526               (pc)))
527    (clobber (reg:HI AX_REG))
528    ]
529   "rl78_real_insns_ok ()"
530   "@
531    mov\ta, %E0\; mov1\tCY, a.7\; skc\; br\t!!%1
532    mov1\tCY, %E0.7\; skc\; br\t!!%1"
533   )
535 (define_insn "*cbranchsi4_real_signed"
536   [(set (pc) (if_then_else
537               (match_operator 0 "rl78_cmp_operator_signed"
538                               [(match_operand:SI 1 "general_operand"   "vU,vU,vU,i,i")
539                                (match_operand:SI 2 "nonmemory_operand" "ISsi,i,v,S,v")])
540               (label_ref (match_operand 3 "" ""))
541               (pc)))
542    (clobber (reg:HI AX_REG))
543    ]
544   "rl78_real_insns_ok ()"
545   "@
546    movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; not1\tCY\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3
547    movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3
548    movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; xor1\tCY, %E2.7\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3
549    movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; not1\tCY\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%0\; br\t!!%3
550    movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%0\; br\t!!%3"
551   [(set (attr "update_Z") (const_string "clobber"))]
552   )
554 (define_insn "*cbranchsi4_real"
555   [(set (pc) (if_then_else
556               (match_operator 0 "rl78_cmp_operator_real"
557                               [(match_operand:SI 1 "general_operand" "vUi")
558                                (match_operand:SI 2 "general_operand" "iWhlWh1v")])
559               (label_ref (match_operand 3 "" ""))
560               (pc)))
561    (clobber (reg:HI AX_REG))
562    ]
563   "rl78_real_insns_ok ()"
564   "movw\tax, %H1\; cmpw\tax, %H2\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3"
565   [(set (attr "update_Z") (const_string "clobber"))]
566   )
568 ;; Peephole to match:
570 ;;     (set (mem (sp)) (ax))
571 ;;     (set (ax) (mem (sp)))
572 ;; or:
573 ;;     (set (mem (plus (sp) (const)) (ax))
574 ;;     (set (ax) (mem (plus (sp) (const))))
576 ;; which can be generated as the last instruction of the conversion
577 ;; of one virtual insn into a real insn and the first instruction of
578 ;; the conversion of the following virtual insn.
580 (define_peephole2
581   [(set (match_operand:HI 0 "rl78_stack_based_mem")
582         (reg:HI AX_REG))
583    (set (reg:HI AX_REG)
584         (match_dup 0))]
585   ""
586   [(set (match_dup 0) (reg:HI AX_REG))]
587   )
589 ;; Bit test and branch insns.
591 ;; NOTE: These patterns will work for bits in other places, not just A.
593 (define_insn "bf"
594   [(set (pc)
595         (if_then_else (eq (and (reg:QI A_REG)
596                                (match_operand 0 "immediate_operand" "n"))
597                           (const_int 0))
598                       (label_ref (match_operand 1 "" ""))
599                       (pc)))]
600   ""
601   "bt\tA.%B0, $1f\n\tbr !!%1\n\t1:"
602   [(set (attr "update_Z") (const_string "clobber"))]
605 (define_insn "bt"
606   [(set (pc)
607         (if_then_else (ne (and (reg:QI A_REG)
608                                (match_operand 0 "immediate_operand" "n"))
609                           (const_int 0))
610                       (label_ref (match_operand 1 "" ""))
611                       (pc)))]
612   ""
613   "bf\tA.%B0, $1f\n\tbr !!%1\n\t1:"
614   [(set (attr "update_Z") (const_string "clobber"))]
617 ;; NOTE: These peepholes are fragile.  They rely upon GCC generating
618 ;; a specific sequence on insns, based upon examination of test code.
619 ;; Improvements to GCC or using code other than the test code can result
620 ;; in the peephole not matching and the optimization being missed.
622 (define_peephole2
623   [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
624    (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand")))
625    (set (pc) (if_then_else (eq (match_dup 0) (const_int 0))
626                            (label_ref (match_operand 2 ""))
627                            (pc)))]
628   "peep2_regno_dead_p (3, REGNO (operands[0]))
629    && exact_log2 (INTVAL (operands[1])) >= 0"
630   [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup 1)) (const_int 0))
631                            (label_ref (match_dup 2))
632                            (pc)))]
633   )
635 (define_peephole2
636   [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
637    (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand")))
638    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
639                            (label_ref (match_operand 2 ""))
640                            (pc)))]
641   "peep2_regno_dead_p (3, REGNO (operands[0]))
642    && exact_log2 (INTVAL (operands[1])) >= 0"
643   [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup 1)) (const_int 0))
644                            (label_ref (match_dup 2))
645                            (pc)))]
646   )
648 ;; Eliminate needless register copies.
649 (define_peephole2
650   [(set (match_operand:HI 0 "register_operand") (match_operand:HI 1 "register_operand"))
651    (set (match_operand:HI 2 "register_operand") (match_dup 0))]
652   "peep2_regno_dead_p (2, REGNO (operands[0]))
653    && (REGNO (operands[1]) < 8 || REGNO (operands[2]) < 8)"
654   [(set (match_dup 2) (match_dup 1))]
655   )
657 ;; Eliminate needless register copying when performing bit manipulations.
658 (define_peephole2
659   [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
660    (set (match_dup 0) (ior:QI (match_dup 0) (match_operand 1 "immediate_operand")))
661    (set (reg:QI A_REG) (match_dup 0))]
662   "peep2_regno_dead_p (3, REGNO (operands[0]))"
663   [(set (reg:QI A_REG) (ior:QI (reg:QI A_REG) (match_dup 1)))]
664   )
666 (define_peephole2
667   [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
668    (set (match_dup 0) (xor:QI (match_dup 0) (match_operand 1 "immediate_operand")))
669    (set (reg:QI A_REG) (match_dup 0))]
670   "peep2_regno_dead_p (3, REGNO (operands[0]))"
671   [(set (reg:QI A_REG) (xor:QI (reg:QI A_REG) (match_dup 1)))]
672   )
674 (define_peephole2
675   [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG))
676    (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand")))
677    (set (reg:QI A_REG) (match_dup 0))]
678   "peep2_regno_dead_p (3, REGNO (operands[0]))"
679   [(set (reg:QI A_REG) (and:QI (reg:QI A_REG) (match_dup 1)))]
680   )
682 (define_insn "*negandhi3_real"
683   [(set (match_operand:HI                 0 "register_operand"  "=A")
684         (and:HI (neg:HI (match_operand:HI 1 "register_operand"  "0"))
685                 (match_operand:HI         2 "immediate_operand" "n")))
686    ]
687   "rl78_real_insns_ok ()"
688   "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"
689   [(set (attr "update_Z") (const_string "clobber"))]