1;; Machine Description for Renesas RL78 processors 2;; Copyright (C) 2011-2021 Free Software Foundation, Inc. 3;; Contributed by Red Hat. 4 5;; This file is part of GCC. 6 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. 11 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. 16 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/>. 20 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. 29 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")) 37 38;;---------- Moving ------------------------ 39 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" 45) 46 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" 52) 53 54(define_insn "movqi_cs" 55 [(set (reg:QI CS_REG) 56 (match_operand:QI 0 "register_operand" "a"))] 57 "" 58 "mov\tcs, %0" 59) 60 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" 75) 76 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" 91) 92 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" 100) 101 102;;---------- Conversions ------------------------ 103 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 ) 112 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 ) 121 122;;---------- Arithmetic ------------------------ 123 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"))] 137) 138 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")] 155) 156 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"))] 165) 166 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"))] 175) 176 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"))] 185) 186 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" 195) 196 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" 203) 204 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")] 217) 218 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")] 231) 232 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"))] 241) 242 243;;---------- Shifts ------------------------ 244 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")] 256) 257 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")] 269) 270 271;;---------- 272 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")] 284) 285 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")] 297) 298 299;;---------- 300 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")] 312) 313 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")] 325) 326 327;;---------- Branching ------------------------ 328 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" 334) 335 336(define_insn "jump" 337 [(set (pc) 338 (label_ref (match_operand 0 "" "")))] 339 "" 340 ;; $rel8, $!rel16, !abs16, !!abs20 341 "br\t!!%0" 342) 343 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 ) 353 354;; Peephole to match: 355;; 356;; (set (reg1) (reg2)) 357;; (call (mem (reg1))) 358;; 359;; and replace it with: 360;; 361;; (call (mem (reg2))) 362 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 ] 371) 372 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 ) 383 384;; Peephole to match: 385;; 386;; (set (reg1) (reg2)) 387;; (set (reg3) (call (mem (reg1)))) 388;; 389;; and replace it with: 390;; 391;; (set (reg3) (call (mem (reg2)))) 392 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 ] 401) 402 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); 413 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 ) 426 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 ) 447 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 ) 463 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 ) 489 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 ) 506 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 ) 520 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 ) 534 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 ) 553 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 ) 567 568;; Peephole to match: 569;; 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)))) 575;; 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. 579 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 ) 588 589;; Bit test and branch insns. 590 591;; NOTE: These patterns will work for bits in other places, not just A. 592 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"))] 603) 604 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"))] 615) 616 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. 621 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 ) 634 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 ) 647 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 ) 656 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 ) 665 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 ) 673 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 ) 681 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"))] 690) 691