1;; Machine Descriptions for R8C/M16C/M32C 2;; Copyright (C) 2005 3;; Free Software Foundation, Inc. 4;; Contributed by Red Hat. 5;; 6;; This file is part of GCC. 7;; 8;; GCC is free software; you can redistribute it and/or modify it 9;; under the terms of the GNU General Public License as published 10;; by the Free Software Foundation; either version 2, or (at your 11;; option) any later version. 12;; 13;; GCC is distributed in the hope that it will be useful, but WITHOUT 14;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16;; License for more details. 17;; 18;; You should have received a copy of the GNU General Public License 19;; along with GCC; see the file COPYING. If not, write to the Free 20;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 21;; 02110-1301, USA. 22 23;; Bit-wise operations (and, ior, xor, shift) 24 25; On the R8C and M16C, "address" for bit instructions is usually (but 26; not always!) the *bit* address, not the *byte* address. This 27; confuses gcc, so we avoid cases where gcc would produce the wrong 28; code. We're left with absolute addresses and registers, and the odd 29; case of shifting a bit by a variable. 30 31; On the M32C, "address" for bit instructions is a regular address, 32; and the bit number is stored in a separate field. Thus, we can let 33; gcc do more interesting things. However, the M32C cannot set all 34; the bits in a 16 bit register, which the R8C/M16C can do. 35 36; However, it all means that we end up with two sets of patterns, one 37; for each chip. 38 39;;---------------------------------------------------------------------- 40 41;; First off, all the ways we can set one bit, other than plain IOR. 42 43(define_insn "bset_qi" 44 [(set (match_operand:QI 0 "memsym_operand" "+Si") 45 (ior:QI (subreg:QI (ashift:HI (const_int 1) 46 (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0)) 0) 47 (match_operand:QI 2 "" "0")))] 48 "TARGET_A16" 49 "bset\t%0[%1]" 50 [(set_attr "flags" "n")] 51 ) 52 53(define_insn "bset_hi" 54 [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") 55 (const_int 1) 56 (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) 57 (const_int 1))] 58 "TARGET_A16" 59 "bset\t%0[%1]" 60 [(set_attr "flags" "n")] 61 ) 62 63;;---------------------------------------------------------------------- 64 65;; Now all the ways we can clear one bit, other than plain AND. 66 67; This is odd because the shift patterns use QI counts, but we can't 68; easily put QI in $aN without causing problems elsewhere. 69(define_insn "bclr_qi" 70 [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") 71 (const_int 1) 72 (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) 73 (const_int 0))] 74 "TARGET_A16" 75 "bclr\t%0[%1]" 76 [(set_attr "flags" "n")] 77 ) 78 79 80;;---------------------------------------------------------------------- 81 82;; Now the generic patterns. 83 84(define_insn "andqi3_16" 85 [(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RhlSd,RhlSd,??Rmm,??Rmm") 86 (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") 87 (match_operand 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))] 88 "TARGET_A16" 89 "@ 90 bclr\t%B2,%0 91 bclr\t%B2,%h0 92 and.b\t%x2,%0 93 and.b\t%x2,%0 94 and.b\t%x2,%0 95 and.b\t%x2,%0" 96 [(set_attr "flags" "n,n,sz,sz,sz,sz")] 97 ) 98 99(define_insn "andhi3_16" 100 [(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,??Rmm,RhiSd,??Rmm") 101 (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0") 102 (match_operand:HI 2 "mrai_operand" "Imb,Imw,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))] 103 "TARGET_A16" 104 "@ 105 106 bclr\t%B2,%0 107 bclr\t%B2-8,1+%0 108 bclr\t%B2,%0 109 and.w\t%X2,%0 110 and.w\t%X2,%0 111 and.w\t%X2,%0 112 and.w\t%X2,%0" 113 [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] 114 ) 115 116(define_insn "andsi3" 117 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") 118 (and:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") 119 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] 120 "" 121 "* 122 switch (which_alternative) 123 { 124 case 0: 125 output_asm_insn (\"and.w %X2,%h0\",operands); 126 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 127 return \"and.w %X2,%H0\"; 128 case 1: 129 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 130 case 2: 131 output_asm_insn (\"and.w %X2,%h0\",operands); 132 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 133 return \"and.w %X2,%H0\"; 134 case 3: 135 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 136 case 4: 137 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 138 case 5: 139 return \"and.w %h2,%h0\;and.w %H2,%H0\"; 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" "Imb,Imw,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 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,Rqi,Rqi,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,Rqi,Rqi,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 }" 319 [(set_attr "flags" "x,x,x,x,x,x")] 320) 321 322(define_insn "xorqi3" 323 [(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm") 324 (xor:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") 325 (match_operand:QI 2 "mrai_operand" "iRhlSd,?Rmm,iRhlSd,?Rmm")))] 326 "" 327 "xor.b\t%x2,%0" 328 [(set_attr "flags" "sz,sz,sz,sz")] 329 ) 330 331(define_insn "xorhi3" 332 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm") 333 (xor:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0") 334 (match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))] 335 "" 336 "xor.w\t%X2,%0" 337 [(set_attr "flags" "sz,sz,sz,sz")] 338 ) 339 340(define_insn "xorsi3" 341 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") 342 (xor:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") 343 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] 344 "" 345 "* 346 switch (which_alternative) 347 { 348 case 0: 349 output_asm_insn (\"xor.w %X2,%h0\",operands); 350 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 351 return \"xor.w %X2,%H0\"; 352 case 1: 353 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 354 case 2: 355 output_asm_insn (\"xor.w %X2,%h0\",operands); 356 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); 357 return \"xor.w %X2,%H0\"; 358 case 3: 359 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 360 case 4: 361 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 362 case 5: 363 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; 364 }" 365 [(set_attr "flags" "x,x,x,x,x,x")] 366) 367 368(define_insn "one_cmplqi2" 369 [(set (match_operand:QI 0 "mra_operand" "=RhlSd,??Rmm") 370 (not:QI (match_operand:QI 1 "mra_operand" "0,0")))] 371 "" 372 "not.b\t%0" 373 [(set_attr "flags" "sz,sz")] 374 ) 375 376(define_insn "one_cmplhi2" 377 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm") 378 (not:HI (match_operand:HI 1 "mra_operand" "0,0")))] 379 "" 380 "not.w\t%0" 381 [(set_attr "flags" "sz,sz")] 382 ) 383 384; Optimizations using bit opcodes 385 386; We need this because combine only looks at three insns at a time, 387; and the bclr_qi pattern uses four - mov, shift, not, and. GCC 388; should never expand this pattern, because it only shifts a constant 389; by a constant, so gcc should do that itself. 390(define_insn "shift1_qi" 391 [(set (match_operand:QI 0 "mra_operand" "=Rqi") 392 (ashift:QI (const_int 1) 393 (match_operand 1 "const_int_operand" "In4")))] 394 "" 395 "mov.b\t#1,%0\n\tshl.b\t%1,%0" 396 ) 397(define_insn "shift1_hi" 398 [(set (match_operand:HI 0 "mra_operand" "=Rhi") 399 (ashift:HI (const_int 1) 400 (match_operand 1 "const_int_operand" "In4")))] 401 "" 402 "mov.w\t#1,%0\n\tshl.w\t%1,%0" 403 ) 404 405; Generic insert-bit expander, needed so that we can use the bit 406; opcodes for volatile bitfields. 407 408(define_expand "insv" 409 [(set (zero_extract:HI (match_operand:HI 0 "mra_operand" "") 410 (match_operand 1 "const_int_operand" "") 411 (match_operand 2 "const_int_operand" "")) 412 (match_operand:HI 3 "const_int_operand" ""))] 413 "" 414 "if (m32c_expand_insv (operands)) 415 FAIL; 416 DONE;" 417 ) 418