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;; Bit-wise operations (and, ior, xor, shift) 22 23; On the R8C and M16C, "address" for bit instructions is usually (but 24; not always!) the *bit* address, not the *byte* address. This 25; confuses gcc, so we avoid cases where gcc would produce the wrong 26; code. We're left with absolute addresses and registers, and the odd 27; case of shifting a bit by a variable. 28 29; On the M32C, "address" for bit instructions is a regular address, 30; and the bit number is stored in a separate field. Thus, we can let 31; gcc do more interesting things. However, the M32C cannot set all 32; the bits in a 16-bit register, which the R8C/M16C can do. 33 34; However, it all means that we end up with two sets of patterns, one 35; for each chip. 36 37;;---------------------------------------------------------------------- 38 39;; First off, all the ways we can set one bit, other than plain IOR. 40 41(define_insn "bset_qi" 42 [(set (match_operand:QI 0 "memsym_operand" "+Si") 43 (ior:QI (subreg:QI (ashift:HI (const_int 1) 44 (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0)) 0) 45 (match_dup 0)))] 46 "TARGET_A16" 47 "bset\t%0[%1]" 48 [(set_attr "flags" "n")] 49 ) 50 51(define_insn "bset_hi" 52 [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") 53 (const_int 1) 54 (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) 55 (const_int 1))] 56 "TARGET_A16" 57 "bset\t%0[%1]" 58 [(set_attr "flags" "n")] 59 ) 60 61;;---------------------------------------------------------------------- 62 63;; Now all the ways we can clear one bit, other than plain AND. 64 65; This is odd because the shift patterns use QI counts, but we can't 66; easily put QI in $aN without causing problems elsewhere. 67(define_insn "bclr_qi" 68 [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") 69 (const_int 1) 70 (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) 71 (const_int 0))] 72 "TARGET_A16" 73 "bclr\t%0[%1]" 74 [(set_attr "flags" "n")] 75 ) 76 77 78;;---------------------------------------------------------------------- 79 80;; Now the generic patterns. 81 82(define_insn "andqi3_16" 83 [(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RhlSd,RhlSd,??Rmm,??Rmm") 84 (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") 85 (match_operand:QI 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))] 86 "TARGET_A16" 87 "@ 88 bclr\t%B2,%0 89 bclr\t%B2,%h0 90 and.b\t%x2,%0 91 and.b\t%x2,%0 92 and.b\t%x2,%0 93 and.b\t%x2,%0" 94 [(set_attr "flags" "n,n,sz,sz,sz,sz")] 95 ) 96 97(define_insn "andhi3_16" 98 [(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,??Rmm,RhiSd,??Rmm") 99 (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0") 100 (match_operand:HI 2 "mrai_operand" "ImB,Imw,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))] 101 "TARGET_A16" 102 "@ 103 104 bclr\t%B2,%0 105 bclr\t%B2-8,1+%0 106 bclr\t%B2,%0 107 and.w\t%X2,%0 108 and.w\t%X2,%0 109 and.w\t%X2,%0 110 and.w\t%X2,%0" 111 [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] 112 ) 113 114(define_insn "andsi3" 115 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") 116 (and:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") 117 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] 118 "" 119 "* 120 switch (which_alternative) 121 { 122 case 0: 123 output_asm_insn (\"and.w %X2,%h0\",operands); 124 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 125 return \"and.w %X2,%H0\"; 126 case 1: 127 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 128 case 2: 129 output_asm_insn (\"and.w %X2,%h0\",operands); 130 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 131 return \"and.w %X2,%H0\"; 132 case 3: 133 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 134 case 4: 135 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 136 case 5: 137 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 138 default: 139 gcc_unreachable (); 140 }" 141 [(set_attr "flags" "x,x,x,x,x,x")] 142) 143 144 145(define_insn "iorqi3_16" 146 [(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RqiSd,??Rmm,RqiSd,??Rmm") 147 (ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") 148 (match_operand:QI 2 "mrai_operand" "Ilb,Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))] 149 "TARGET_A16" 150 "@ 151 bset\t%B2,%0 152 bset\t%B2,%h0 153 or.b\t%x2,%0 154 or.b\t%x2,%0 155 or.b\t%x2,%0 156 or.b\t%x2,%0" 157 [(set_attr "flags" "n,n,sz,sz,sz,sz")] 158 ) 159 160(define_insn "iorhi3_16" 161 [(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,RhiSd,??Rmm,??Rmm") 162 (ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0") 163 (match_operand:HI 2 "mrai_operand" "Ilb,Ilw,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))] 164 "TARGET_A16" 165 "@ 166 bset %B2,%0 167 bset\t%B2-8,1+%0 168 bset\t%B2,%0 169 or.w\t%X2,%0 170 or.w\t%X2,%0 171 or.w\t%X2,%0 172 or.w\t%X2,%0" 173 [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] 174 ) 175 176; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 177 178(define_insn "andqi3_24" 179 [(set (match_operand:QI 0 "mra_operand" "=Sd,Rqi,RhlSd,RhlSd,??Rmm,??Rmm") 180 (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") 181 (match_operand:QI 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))] 182 "TARGET_A24" 183 "@ 184 bclr\t%B2,%0 185 bclr\t%B2,%0 186 and.b\t%x2,%0 187 and.b\t%x2,%0 188 and.b\t%x2,%0 189 and.b\t%x2,%0" 190 [(set_attr "flags" "n,n,sz,sz,sz,sz")] 191 ) 192 193(define_insn "andhi3_24" 194 [(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,?Rhl,?Rhl,RhiSd,??Rmm,RhiSd,??Rmm") 195 (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0") 196 (match_operand:HI 2 "mrai_operand" "ImB,Imw,ImB,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))] 197 "TARGET_A24" 198 "@ 199 bclr\t%B2,%0 200 bclr\t%B2-8,1+%0 201 bclr\t%B2,%h0 202 bclr\t%B2-8,%H0 203 and.w\t%X2,%0 204 and.w\t%X2,%0 205 and.w\t%X2,%0 206 and.w\t%X2,%0" 207 [(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")] 208 ) 209 210 211 212(define_insn "iorqi3_24" 213 [(set (match_operand:QI 0 "mra_operand" "=RqiSd,RqiSd,??Rmm,RqiSd,??Rmm") 214 (ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0") 215 (match_operand:QI 2 "mrai_operand" "Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))] 216 "TARGET_A24" 217 "@ 218 bset\t%B2,%0 219 or.b\t%x2,%0 220 or.b\t%x2,%0 221 or.b\t%x2,%0 222 or.b\t%x2,%0" 223 [(set_attr "flags" "n,sz,sz,sz,sz")] 224 ) 225 226(define_insn "iorhi3_24" 227 [(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,?Rhl,?Rhl,RhiSd,RhiSd,??Rmm,??Rmm") 228 (ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0") 229 (match_operand:HI 2 "mrai_operand" "Ilb,Ilw,Ilb,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))] 230 "TARGET_A24" 231 "@ 232 bset\t%B2,%0 233 bset\t%B2-8,1+%0 234 bset\t%B2,%h0 235 bset\t%B2-8,%H0 236 or.w\t%X2,%0 237 or.w\t%X2,%0 238 or.w\t%X2,%0 239 or.w\t%X2,%0" 240 [(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")] 241 ) 242 243 244; ---------------------------------------------------------------------- 245 246(define_expand "andqi3" 247 [(set (match_operand:QI 0 "mra_operand" "") 248 (and:QI (match_operand:QI 1 "mra_operand" "") 249 (match_operand:QI 2 "mrai_operand" "")))] 250 "" 251 "if (TARGET_A16) 252 emit_insn (gen_andqi3_16 (operands[0], operands[1], operands[2])); 253 else 254 emit_insn (gen_andqi3_24 (operands[0], operands[1], operands[2])); 255 DONE;" 256 ) 257 258(define_expand "andhi3" 259 [(set (match_operand:HI 0 "mra_operand" "") 260 (and:HI (match_operand:HI 1 "mra_operand" "") 261 (match_operand:HI 2 "mrai_operand" "")))] 262 "" 263 "if (TARGET_A16) 264 emit_insn (gen_andhi3_16 (operands[0], operands[1], operands[2])); 265 else 266 emit_insn (gen_andhi3_24 (operands[0], operands[1], operands[2])); 267 DONE;" 268 ) 269 270(define_expand "iorqi3" 271 [(set (match_operand:QI 0 "mra_operand" "") 272 (ior:QI (match_operand:QI 1 "mra_operand" "") 273 (match_operand:QI 2 "mrai_operand" "")))] 274 "" 275 "if (TARGET_A16) 276 emit_insn (gen_iorqi3_16 (operands[0], operands[1], operands[2])); 277 else 278 emit_insn (gen_iorqi3_24 (operands[0], operands[1], operands[2])); 279 DONE;" 280 ) 281 282(define_expand "iorhi3" 283 [(set (match_operand:HI 0 "mra_operand" "") 284 (ior:HI (match_operand:HI 1 "mra_operand" "") 285 (match_operand:HI 2 "mrai_operand" "")))] 286 "" 287 "if (TARGET_A16) 288 emit_insn (gen_iorhi3_16 (operands[0], operands[1], operands[2])); 289 else 290 emit_insn (gen_iorhi3_24 (operands[0], operands[1], operands[2])); 291 DONE;" 292 ) 293 294(define_insn "iorsi3" 295 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") 296 (ior:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") 297 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] 298 "" 299 "* 300 switch (which_alternative) 301 { 302 case 0: 303 output_asm_insn (\"or.w %X2,%h0\",operands); 304 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 305 return \"or.w %X2,%H0\"; 306 case 1: 307 return \"or.w %h2,%h0\;or.w %H2,%H0\"; 308 case 2: 309 output_asm_insn (\"or.w %X2,%h0\",operands); 310 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 311 return \"or.w %X2,%H0\"; 312 case 3: 313 return \"or.w %h2,%h0\;or.w %H2,%H0\"; 314 case 4: 315 return \"or.w %h2,%h0\;or.w %H2,%H0\"; 316 case 5: 317 return \"or.w %h2,%h0\;or.w %H2,%H0\"; 318 default: 319 gcc_unreachable (); 320 }" 321 [(set_attr "flags" "x,x,x,x,x,x")] 322) 323 324(define_insn "xorqi3" 325 [(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm") 326 (xor:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") 327 (match_operand:QI 2 "mrai_operand" "iRhlSd,?Rmm,iRhlSd,?Rmm")))] 328 "" 329 "xor.b\t%x2,%0" 330 [(set_attr "flags" "sz,sz,sz,sz")] 331 ) 332 333(define_insn "xorhi3" 334 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm") 335 (xor:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0") 336 (match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))] 337 "" 338 "xor.w\t%X2,%0" 339 [(set_attr "flags" "sz,sz,sz,sz")] 340 ) 341 342(define_insn "xorsi3" 343 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") 344 (xor:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") 345 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] 346 "" 347 "* 348 switch (which_alternative) 349 { 350 case 0: 351 output_asm_insn (\"xor.w %X2,%h0\",operands); 352 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 353 return \"xor.w %X2,%H0\"; 354 case 1: 355 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 356 case 2: 357 output_asm_insn (\"xor.w %X2,%h0\",operands); 358 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 359 return \"xor.w %X2,%H0\"; 360 case 3: 361 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 362 case 4: 363 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 364 case 5: 365 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 366 default: 367 gcc_unreachable (); 368 }" 369 [(set_attr "flags" "x,x,x,x,x,x")] 370) 371 372(define_insn "one_cmplqi2" 373 [(set (match_operand:QI 0 "mra_operand" "=RhlSd,??Rmm") 374 (not:QI (match_operand:QI 1 "mra_operand" "0,0")))] 375 "" 376 "not.b\t%0" 377 [(set_attr "flags" "sz,sz")] 378 ) 379 380(define_insn "one_cmplhi2" 381 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm") 382 (not:HI (match_operand:HI 1 "mra_operand" "0,0")))] 383 "" 384 "not.w\t%0" 385 [(set_attr "flags" "sz,sz")] 386 ) 387 388; Optimizations using bit opcodes 389 390; We need this because combine only looks at three insns at a time, 391; and the bclr_qi pattern uses four - mov, shift, not, and. GCC 392; should never expand this pattern, because it only shifts a constant 393; by a constant, so gcc should do that itself. 394(define_insn "shift1_qi" 395 [(set (match_operand:QI 0 "mra_operand" "=Rqi") 396 (ashift:QI (const_int 1) 397 (match_operand 1 "const_int_operand" "In4")))] 398 "" 399 "mov.b\t#1,%0\n\tshl.b\t%1,%0" 400 ) 401(define_insn "shift1_hi" 402 [(set (match_operand:HI 0 "mra_operand" "=Rhi") 403 (ashift:HI (const_int 1) 404 (match_operand 1 "const_int_operand" "In4")))] 405 "" 406 "mov.w\t#1,%0\n\tshl.w\t%1,%0" 407 ) 408 409; Generic insert-bit expander, needed so that we can use the bit 410; opcodes for volatile bitfields. 411 412(define_expand "insv" 413 [(set (zero_extract:HI (match_operand:HI 0 "mra_operand" "") 414 (match_operand 1 "const_int_operand" "") 415 (match_operand 2 "const_int_operand" "")) 416 (match_operand:HI 3 "const_int_operand" ""))] 417 "" 418 "if (m32c_expand_insv (operands)) 419 FAIL; 420 DONE;" 421 ) 422