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