1;; Machine Descriptions for R8C/M16C/M32C 2;; Copyright (C) 2005-2020 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 it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; 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;; move, push, extend, etc. 22 23;; Be careful to never create an alternative that has memory as both 24;; src and dest, as that makes gcc think that mem-mem moves in general 25;; are supported. While the chip does support this, it only has two 26;; address registers and sometimes gcc requires more than that. One 27;; example is code like this: a = *b where both a and b are spilled to 28;; the stack. 29 30(define_insn "mov<mode>_far_op1" 31 [(set (match_operand:QHI 0 "register_operand" "=Rhi") 32 (mem:QHI (plus:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "Ra0")) 33 (match_operand 2 "immediate_operand" "si")))) 34 ] 35 "" 36 "lde.<bwl>\t%D2[%1],%0" 37 [(set_attr "flags" "sz")] 38 ) 39 40(define_insn "mov<mode>_far_op2" 41 [(set (mem:QHI (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "Ra0")) 42 (match_operand 1 "immediate_operand" "si"))) 43 (match_operand:QHI 2 "register_operand" 44 "=Rhi")) 45 ] 46 "" 47 "ste.<bwl>\t%2,%D1[%0]" 48 [(set_attr "flags" "sz")] 49 ) 50 51;; Match push/pop before mov.b for passing char as arg, 52;; e.g. stdlib/efgcvt.c. 53(define_insn "movqi_op" 54 [(set (match_operand:QI 0 "m32c_nonimmediate_operand" 55 "=SF,Rhi*Rmm, Rqi*Rmm, <, RqiSd*Rmm, SdSs, Rqi*Rmm, Sd") 56 (match_operand:QI 1 "m32c_any_operand" 57 "Rhi*Rmm,SF, iRqi*Rmm, iRqiSd*Rmm, >, Rqi*Rmm, SdSs, i"))] 58 "m32c_mov_ok (operands, QImode)" 59 "@ 60 lde.b\t%1,%0 61 ste.b\t%1,%0 62 mov.b\t%1,%0 63 push.b\t%1 64 pop.b\t%0 65 mov.b\t%1,%0 66 mov.b\t%1,%0 67 mov.b\t%1,%0" 68 [(set_attr "flags" "sz,sz,sz,*,*,sz,sz,sz")] 69 ) 70 71(define_expand "movqi" 72 [(set (match_operand:QI 0 "nonimmediate_operand" "=RqiSd*Rmm") 73 (match_operand:QI 1 "general_operand" "iRqiSd*Rmm"))] 74 "" 75 "if (m32c_prepare_move (operands, QImode)) DONE;" 76 ) 77 78 79(define_insn "movhi_op" 80 [(set (match_operand:HI 0 "m32c_nonimmediate_operand" 81 "=SF,Rhi*Rmm, Rhi*Rmm, Sd, SdSs, *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr") 82 (match_operand:HI 1 "m32c_any_operand" 83 " Rhi*Rmm,SF, iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))] 84 "m32c_mov_ok (operands, HImode)" 85 "@ 86 ste.w\t%1,%0 87 lde.w\t%1,%0 88 mov.w\t%1,%0 89 mov.w\t%1,%0 90 mov.w\t%1,%0 91 ldc\t%1,%0 92 stc\t%1,%0 93 push.w\t%1 94 pop.w\t%0 95 pushc\t%1 96 popc\t%0" 97 [(set_attr "flags" "sz,sz,sz,sz,sz,n,n,n,n,n,n")] 98 ) 99 100(define_expand "movhi" 101 [(set (match_operand:HI 0 "m32c_nonimmediate_operand" "=RhiSd*Rmm") 102 (match_operand:HI 1 "m32c_any_operand" "iRhiSd*Rmm"))] 103 "" 104 "if (m32c_prepare_move (operands, HImode)) DONE;" 105 ) 106 107 108(define_insn "movpsi_op" 109 [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" 110 "=Raa, SdRmmRpi, Rcl, RpiSd*Rmm, <, <, Rcl, RpiRaa*Rmm") 111 (match_operand:PSI 1 "m32c_any_operand" 112 "sIU3, iSdRmmRpi, iRpiSd*Rmm, Rcl, Rpi*Rmm, Rcl, >, >"))] 113 "TARGET_A24 && m32c_mov_ok (operands, PSImode)" 114 "@ 115 mov.l:s\t%1,%0 116 mov.l\t%1,%0 117 ldc\t%1,%0 118 stc\t%1,%0 119 push.l\t%1 120 pushc\t%1 121 popc\t%0 122 #" 123 [(set_attr "flags" "sz,sz,n,n,n,n,n,*")] 124 ) 125 126 127;; The intention here is to combine the add with the move to create an 128;; indexed move. GCC doesn't always figure this out itself. 129 130(define_peephole2 131 [(set (match_operand:HPSI 0 "register_operand" "") 132 (plus:HPSI (match_operand:HPSI 1 "register_operand" "") 133 (match_operand:HPSI 2 "immediate_operand" ""))) 134 (set (match_operand:QHSI 3 "nonimmediate_operand" "") 135 (mem:QHSI (match_operand:HPSI 4 "register_operand" "")))] 136 "REGNO (operands[0]) == REGNO (operands[1]) 137 && REGNO (operands[0]) == REGNO (operands[4]) 138 && (rtx_equal_p (operands[0], operands[3]) 139 || (dead_or_set_p (peep2_next_insn (1), operands[4]) 140 && ! reg_mentioned_p (operands[0], operands[3])))" 141 [(set (match_dup 3) 142 (mem:QHSI (plus:HPSI (match_dup 1) 143 (match_dup 2))))] 144 "") 145 146(define_peephole2 147 [(set (match_operand:HPSI 0 "register_operand" "") 148 (plus:HPSI (match_operand:HPSI 1 "register_operand" "") 149 (match_operand:HPSI 2 "immediate_operand" ""))) 150 (set (mem:QHSI (match_operand:HPSI 4 "register_operand" "")) 151 (match_operand:QHSI 3 "m32c_any_operand" ""))] 152 "REGNO (operands[0]) == REGNO (operands[1]) 153 && REGNO (operands[0]) == REGNO (operands[4]) 154 && dead_or_set_p (peep2_next_insn (1), operands[4]) 155 && ! reg_mentioned_p (operands[0], operands[3])" 156 [(set (mem:QHSI (plus:HPSI (match_dup 1) 157 (match_dup 2))) 158 (match_dup 3))] 159 "") 160 161; Peephole to generate SImode mov instructions for storing an 162; immediate double data to a memory location. 163(define_peephole2 164 [(set (match_operand:HI 0 "memory_operand" "") 165 (match_operand:HI 1 "const_int_operand" "")) 166 (set (match_operand:HI 2 "memory_operand" "") 167 (match_operand:HI 3 "const_int_operand" ""))] 168 "TARGET_A24 && m32c_immd_dbl_mov (operands, HImode)" 169 [(set (match_dup 4) (match_dup 5))] 170 "" 171) 172 173; Some PSI moves must be split. 174(define_split 175 [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "") 176 (match_operand:PSI 1 "m32c_any_operand" ""))] 177 "reload_completed && m32c_split_psi_p (operands)" 178 [(set (match_dup 2) 179 (match_dup 3)) 180 (set (match_dup 4) 181 (match_dup 5))] 182 "m32c_split_move (operands, PSImode, 3);" 183 ) 184 185(define_expand "movpsi" 186 [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "") 187 (match_operand:PSI 1 "m32c_any_operand" ""))] 188 "" 189 "if (m32c_prepare_move (operands, PSImode)) DONE;" 190 ) 191 192 193 194(define_expand "movsi" 195 [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=RsiSd*Rmm") 196 (match_operand:SI 1 "m32c_any_operand" "iRsiSd*Rmm"))] 197 "" 198 "if (m32c_split_move (operands, SImode, 0)) DONE;" 199 ) 200 201; All SI moves are split if TARGET_A16 202(define_insn_and_split "movsi_splittable" 203 [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=RsiRaa<*Rmm, RsiRaaSd*Rmm, Ss") 204 (match_operand:SI 1 "m32c_any_operand" "iRsiRaaSd*Rmm, iRsiRaa>*Rmm, RsiRaa*Rmm"))] 205 "TARGET_A16" 206 "#" 207 "TARGET_A16" 208 [(pc)] 209 "m32c_split_move (operands, SImode, 1); DONE;" 210 ) 211 212; The movsi pattern doesn't always match because sometimes the modes 213; don't match. 214(define_insn "push_a01_l" 215 [(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO))) 216 (match_operand:SI 0 "a_operand" "Raa"))] 217 "" 218 "push.l\t%0" 219 [(set_attr "flags" "n")] 220 ) 221 222(define_insn "movsi_24" 223 [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=Rsi*Rmm, Sd, RsiSd*Rmm, <") 224 (match_operand:SI 1 "m32c_any_operand" "iRsiSd*Rmm, iRsi*Rmm, >, iRsiRaaSd*Rmm"))] 225 "TARGET_A24" 226 "@ 227 mov.l\t%1,%0 228 mov.l\t%1,%0 229 # 230 push.l\t%1" 231 [(set_attr "flags" "sz,sz,*,n")] 232 ) 233 234(define_expand "movdi" 235 [(set (match_operand:DI 0 "m32c_nonimmediate_operand" "=RdiSd*Rmm") 236 (match_operand:DI 1 "m32c_any_operand" "iRdiSd*Rmm"))] 237 "" 238 "if (m32c_split_move (operands, DImode, 0)) DONE;" 239 ) 240 241(define_insn_and_split "movdi_splittable" 242 [(set (match_operand:DI 0 "m32c_nonimmediate_operand" "=Rdi<*Rmm,RdiSd*Rmm") 243 (match_operand:DI 1 "m32c_any_operand" "iRdiSd*Rmm,iRdi>*Rmm"))] 244 "" 245 "#" 246 "reload_completed" 247 [(pc)] 248 "m32c_split_move (operands, DImode, 1); DONE;" 249 ) 250 251 252 253 254(define_insn "pushqi" 255 [(set (mem:QI (pre_dec:PSI (reg:PSI SP_REGNO))) 256 (match_operand:QI 0 "mrai_operand" "iRqiSd*Rmm"))] 257 "" 258 "push.b\t%0" 259 [(set_attr "flags" "n")] 260 ) 261 262(define_expand "pushhi" 263 [(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO))) 264 (match_operand:HI 0 "" ""))] 265 "" 266 "if (TARGET_A16) 267 gen_pushhi_16 (operands[0]); 268 else 269 gen_pushhi_24 (operands[0]); 270 DONE;" 271 ) 272 273(define_insn "pushhi_16" 274 [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO))) 275 (match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm,Rcr"))] 276 "TARGET_A16" 277 "@ 278 push.w\t%0 279 pushc\t%0" 280 [(set_attr "flags" "n,n")] 281 ) 282 283(define_insn "pushhi_24" 284 [(set (mem:HI (pre_dec:PSI (reg:PSI SP_REGNO))) 285 (match_operand:HI 0 "mrai_operand" "iRhiSd*Rmm"))] 286 "TARGET_A24" 287 "push.w\t%0" 288 [(set_attr "flags" "n")] 289 ) 290 291;(define_insn "pushpi" 292; [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO))) 293; (match_operand:PI 0 "mrai_operand" "iRaa,Rcr"))] 294; "TARGET_A24" 295; "@ 296; push.l\t%0 297; pushc\t%0" 298; ) 299 300(define_insn "pushsi" 301 [(set (mem:SI (pre_dec:PSI (reg:PSI SP_REGNO))) 302 (match_operand:SI 0 "mrai_operand" "iRsiSd*Rmm"))] 303 "TARGET_A24" 304 "push.l\t%0" 305 [(set_attr "flags" "n")] 306 ) 307 308(define_expand "pophi" 309 [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr") 310 (mem:HI (post_inc:HI (reg:HI SP_REGNO))))] 311 "" 312 "if (TARGET_A16) 313 gen_pophi_16 (operands[0]); 314 else 315 gen_pophi_24 (operands[0]); 316 DONE;" 317 ) 318 319(define_insn "pophi_16" 320 [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,Rcr") 321 (mem:HI (post_inc:HI (reg:HI SP_REGNO))))] 322 "TARGET_A16" 323 "@ 324 pop.w\t%0 325 popc\t%0" 326 [(set_attr "flags" "n,n")] 327 ) 328 329(define_insn "pophi_24" 330 [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm") 331 (mem:HI (post_inc:PSI (reg:PSI SP_REGNO))))] 332 "TARGET_A24" 333 "pop.w\t%0" 334 [(set_attr "flags" "n")] 335 ) 336 337(define_insn "poppsi" 338 [(set (match_operand:PSI 0 "cr_operand" "=Rcl") 339 (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))] 340 "TARGET_A24" 341 "popc\t%0" 342 [(set_attr "flags" "n")] 343 ) 344 345 346;; Rhl used here as an HI-mode Rxl 347(define_insn "extendqihi2" 348[(set (match_operand:HI 0 "m32c_nonimmediate_operand" "=RhlSd*Rmm") 349 (sign_extend:HI (match_operand:QI 1 "mra_operand" "0")))] 350 "" 351 "exts.b\t%1" 352 [(set_attr "flags" "sz")] 353 ) 354 355(define_insn "extendhisi2" 356 [(set (match_operand:SI 0 "register_operand" "=R03") 357 (sign_extend:SI (match_operand:HI 1 "r0123_operand" "0")))] 358 "" 359 "* 360 if (REGNO(operands[0]) == 0) return \"exts.w\t%1\"; 361 else return \"mov.w r1,r3 | sha.w #-8,r3 | sha.w #-7,r3\";" 362 [(set_attr "flags" "x")] 363 ) 364 365(define_insn "extendhipsi2" 366 [(set (match_operand:PSI 0 "register_operand" "=R03") 367 (sign_extend:PSI (match_operand:HI 1 "register_operand" "0")))] 368 "" 369 "* 370 if (REGNO(operands[0]) == 0) return \"exts.w\t%1\"; 371 else return \"mov.w r1,r3 | sha.w #-8,r3 | sha.w #-7,r3\";" 372 [(set_attr "flags" "x")] 373 ) 374 375(define_insn "extendpsisi2" 376 [(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm") 377 (sign_extend:SI (match_operand:PSI 1 "mr_operand" "0")))] 378 "" 379 "; expand psi %1 to si %0" 380 [(set_attr "flags" "n")] 381 ) 382 383(define_insn "zero_extendpsisi2" 384 [(set (match_operand:SI 0 "mr_operand" "=R03Sd*Rmm") 385 (zero_extend:SI (match_operand:PSI 1 "mr_operand" "0")))] 386 "" 387 "; expand psi %1 to si %0" 388 [(set_attr "flags" "n")] 389 ) 390 391(define_insn "zero_extendhipsi2" 392 [(set (match_operand:PSI 0 "register_operand" "=Raa") 393 (truncate:PSI (zero_extend:SI (match_operand:HI 1 "register_operand" "R03"))))] 394 "" 395 "mov.w\t%1,%0" 396 [(set_attr "flags" "sz")] 397 ) 398 399(define_insn "zero_extendhisi2" 400 [(set (match_operand:SI 0 "m32c_nonimmediate_operand" "=RsiSd") 401 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))] 402 "" 403 "mov.w\t#0,%H0" 404 [(set_attr "flags" "x")] 405 ) 406 407(define_insn "zero_extendqihi2" 408 [(set (match_operand:HI 0 "m32c_nonimmediate_operand" "=?Rhl,RhiSd*Rmm") 409 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 410 "" 411 "@ 412 mov.b\t#0,%H0 413 and.w\t#255,%0" 414 [(set_attr "flags" "x,x")] 415 ) 416 417(define_insn "truncsipsi2_16" 418 [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm") 419 (truncate:PSI (match_operand:SI 1 "nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))] 420 "TARGET_A16" 421 "@ 422 ; no-op trunc si %1 to psi %0 423 # 424 ldc\t%1,%0 425 stc\t%1,%0" 426 [(set_attr "flags" "n,*,n,n")] 427 ) 428 429(define_insn "trunchiqi2" 430 [(set (match_operand:QI 0 "m32c_nonimmediate_operand" "=RqiRmmSd") 431 (truncate:QI (match_operand:HI 1 "mra_qi_operand" "0")))] 432 "" 433 "; no-op trunc hi %1 to qi %0" 434 [(set_attr "flags" "n")] 435 ) 436 437(define_insn "truncsipsi2_24" 438 [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "=RsiSd*Rmm,Raa,!Rcl,RsiSd*Rmm") 439 (truncate:PSI (match_operand:SI 1 "m32c_nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,!Rcl")))] 440 "TARGET_A24" 441 "@ 442 ; no-op trunc si %1 to psi %0 443 mov.l\t%1,%0 444 ldc\t%1,%0 445 stc\t%1,%0" 446 [(set_attr "flags" "n,sz,n,n")] 447 ) 448 449(define_expand "truncsipsi2" 450 [(set (match_operand:PSI 0 "m32c_nonimmediate_operand" "=RsiRadSd*Rmm,Raa,Rcr,RsiSd*Rmm") 451 (truncate:PSI (match_operand:SI 1 "m32c_nonimmediate_operand" "0,RsiSd*Rmm,RsiSd*Rmm,Rcr")))] 452 "" 453 "" 454 ) 455 456(define_expand "reload_inqi" 457 [(set (match_operand:QI 2 "" "=&Rqi") 458 (match_operand:QI 1 "" "")) 459 (set (match_operand:QI 0 "" "") 460 (match_dup 2)) 461 ] 462 "" 463 "") 464 465(define_expand "reload_outqi" 466 [(set (match_operand:QI 2 "" "=&Rqi") 467 (match_operand:QI 1 "" "")) 468 (set (match_operand:QI 0 "" "") 469 (match_dup 2)) 470 ] 471 "" 472 "") 473 474(define_expand "reload_inhi" 475 [(set (match_operand:HI 2 "" "=&Rhi") 476 (match_operand:HI 1 "" "")) 477 (set (match_operand:HI 0 "" "") 478 (match_dup 2)) 479 ] 480 "" 481 "") 482 483(define_expand "reload_outhi" 484 [(set (match_operand:HI 2 "" "=&Rhi") 485 (match_operand:HI 1 "" "")) 486 (set (match_operand:HI 0 "" "") 487 (match_dup 2)) 488 ] 489 "" 490 "") 491