1;; ----------------------------------------------------------------- 2;; BIT FIELDS 3;; ----------------------------------------------------------------- 4;; The H8/300 has given 1/8th of its opcode space to bitfield 5;; instructions so let's use them as well as we can. 6 7;; You'll never believe all these patterns perform one basic action -- 8;; load a bit from the source, optionally invert the bit, then store it 9;; in the destination (which is known to be zero). 10;; 11;; Combine obviously need some work to better identify this situation and 12;; canonicalize the form better. 13 14;; 15;; Inverted loads with a 16bit destination. 16;; 17 18(define_insn_and_split "" 19 [(set (match_operand:HI 0 "register_operand" "=&r") 20 (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r") 21 (match_operand:HI 3 "const_int_operand" "n")) 22 (const_int 1) 23 (match_operand:HI 2 "const_int_operand" "n")))] 24 "(TARGET_H8300SX) 25 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])" 26 "#" 27 "&& reload_completed" 28 [(parallel [(set (match_dup 0) 29 (zero_extract:HI (xor:HI (match_dup 1) (match_dup 3)) 30 (const_int 1) 31 (match_dup 2))) 32 (clobber (reg:CC CC_REG))])]) 33 34(define_insn "" 35 [(set (match_operand:HI 0 "register_operand" "=&r") 36 (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r") 37 (match_operand:HI 3 "const_int_operand" "n")) 38 (const_int 1) 39 (match_operand:HI 2 "const_int_operand" "n"))) 40 (clobber (reg:CC CC_REG))] 41 "(TARGET_H8300SX) 42 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])" 43 "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" 44 [(set_attr "length" "8")]) 45 46;; 47;; Normal loads with a 32bit destination. 48;; 49 50(define_insn_and_split "*extzv_1_r" 51 [(set (match_operand:SI 0 "register_operand" "=r,r") 52 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r") 53 (const_int 1) 54 (match_operand 2 "const_int_operand" "n,n")))] 55 "INTVAL (operands[2]) < 16" 56 "#" 57 "&& reload_completed" 58 [(parallel [(set (match_dup 0) 59 (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2))) 60 (clobber (reg:CC CC_REG))])]) 61 62(define_insn "*extzv_1_r_clobber_flags" 63 [(set (match_operand:SI 0 "register_operand" "=r,r") 64 (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r") 65 (const_int 1) 66 (match_operand 2 "const_int_operand" "n,n"))) 67 (clobber (reg:CC CC_REG))] 68 "INTVAL (operands[2]) < 16" 69{ 70 return output_simode_bld (0, operands); 71} 72 [(set_attr "length" "8,6")]) 73 74;; 75;; Inverted loads with a 32bit destination. 76;; 77 78(define_insn_and_split "*extzv_1_r_inv" 79 [(set (match_operand:SI 0 "register_operand" "=r,r") 80 (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r") 81 (match_operand 3 "const_int_operand" "n,n")) 82 (const_int 1) 83 (match_operand 2 "const_int_operand" "n,n")))] 84 "INTVAL (operands[2]) < 16 85 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])" 86 "#" 87 "&& reload_completed" 88 [(parallel [(set (match_dup 0) 89 (zero_extract:SI (xor:SI (match_dup 1) (match_dup 3)) 90 (const_int 1) 91 (match_dup 2))) 92 (clobber (reg:CC CC_REG))])]) 93 94(define_insn "*extzv_1_r_inv_clobber_flags" 95 [(set (match_operand:SI 0 "register_operand" "=r,r") 96 (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r") 97 (match_operand 3 "const_int_operand" "n,n")) 98 (const_int 1) 99 (match_operand 2 "const_int_operand" "n,n"))) 100 (clobber (reg:CC CC_REG))] 101 "INTVAL (operands[2]) < 16 102 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])" 103{ 104 return output_simode_bld (1, operands); 105} 106 [(set_attr "length" "8,6")]) 107 108(define_expand "insv" 109 [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "") 110 (match_operand:HI 1 "general_operand" "") 111 (match_operand:HI 2 "general_operand" "")) 112 (match_operand:HI 3 "general_operand" ""))] 113 "TARGET_H8300SX" 114 { 115 if (GET_CODE (operands[1]) == CONST_INT 116 && GET_CODE (operands[2]) == CONST_INT 117 && INTVAL (operands[1]) <= 8 118 && INTVAL (operands[2]) >= 0 119 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8 120 && memory_operand (operands[0], GET_MODE (operands[0]))) 121 { 122 /* If the source operand is zero, it's better to use AND rather 123 than BFST. Likewise OR if the operand is all ones. */ 124 if (GET_CODE (operands[3]) == CONST_INT) 125 { 126 HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1; 127 if ((INTVAL (operands[3]) & mask) == 0) 128 FAIL; 129 if ((INTVAL (operands[3]) & mask) == mask) 130 FAIL; 131 } 132 if (! bit_memory_operand (operands[0], GET_MODE (operands[0]))) 133 { 134 if (!can_create_pseudo_p ()) 135 FAIL; 136 operands[0] = replace_equiv_address (operands[0], force_reg (Pmode, 137 XEXP (operands[0], 0))); 138 } 139 operands[3] = gen_lowpart (QImode, operands[3]); 140 if (! operands[3]) 141 FAIL; 142 if (! register_operand (operands[3], QImode)) 143 { 144 if (!can_create_pseudo_p ()) 145 FAIL; 146 operands[3] = force_reg (QImode, operands[3]); 147 } 148 emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0), 149 operands[3], operands[1], operands[2])); 150 DONE; 151 } 152 FAIL; 153 }) 154 155(define_insn_and_split "" 156 [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r") 157 (const_int 1) 158 (match_operand:HI 1 "immediate_operand" "n")) 159 (match_operand:HI 2 "register_operand" "r"))] 160 "" 161 "#" 162 "&& reload_completed" 163 [(parallel [(set (zero_extract:HI (match_dup 0) (const_int 1) (match_dup 1)) 164 (match_dup 2)) 165 (clobber (reg:CC CC_REG))])]) 166 167(define_insn "" 168 [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r") 169 (const_int 1) 170 (match_operand:HI 1 "immediate_operand" "n")) 171 (match_operand:HI 2 "register_operand" "r")) 172 (clobber (reg:CC CC_REG))] 173 "" 174 "bld #0,%R2\;bst %Z1,%Y0 ; i1" 175 [(set_attr "length" "4")]) 176 177(define_expand "extzv" 178 [(set (match_operand:HI 0 "register_operand" "") 179 (zero_extract:HI (match_operand:HI 1 "bit_operand" "") 180 (match_operand:HI 2 "general_operand" "") 181 (match_operand:HI 3 "general_operand" "")))] 182 "TARGET_H8300SX" 183 { 184 if (GET_CODE (operands[2]) == CONST_INT 185 && GET_CODE (operands[3]) == CONST_INT 186 && INTVAL (operands[2]) <= 8 187 && INTVAL (operands[3]) >= 0 188 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8 189 && memory_operand (operands[1], QImode)) 190 { 191 rtx temp; 192 193 /* Optimize the case where we're extracting into a paradoxical 194 subreg. It's only necessary to extend to the inner reg. */ 195 if (GET_CODE (operands[0]) == SUBREG 196 && subreg_lowpart_p (operands[0]) 197 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) 198 < GET_MODE_SIZE (GET_MODE (operands[0]))) 199 && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) 200 == MODE_INT)) 201 operands[0] = SUBREG_REG (operands[0]); 202 203 if (!can_create_pseudo_p ()) 204 temp = gen_lowpart (QImode, operands[0]); 205 else 206 temp = gen_reg_rtx (QImode); 207 if (! temp) 208 FAIL; 209 if (! bit_memory_operand (operands[1], QImode)) 210 { 211 if (!can_create_pseudo_p ()) 212 FAIL; 213 operands[1] = replace_equiv_address (operands[1], 214 force_reg (Pmode, XEXP (operands[1], 0))); 215 } 216 emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3])); 217 convert_move (operands[0], temp, 1); 218 DONE; 219 } 220 FAIL; 221 }) 222 223;; BAND, BOR, and BXOR patterns 224 225(define_insn_and_split "" 226 [(set (match_operand:HI 0 "bit_operand" "=Ur") 227 (match_operator:HI 4 "bit_operator" 228 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") 229 (const_int 1) 230 (match_operand:HI 2 "immediate_operand" "n")) 231 (match_operand:HI 3 "bit_operand" "0")]))] 232 "" 233 "#" 234 "&& reload_completed" 235 [(parallel [(set (match_dup 0) 236 (match_op_dup 4 [(zero_extract:HI (match_dup 1) 237 (const_int 1) 238 (match_dup 2)) 239 (match_dup 3)])) 240 (clobber (reg:CC CC_REG))])]) 241 242(define_insn "" 243 [(set (match_operand:HI 0 "bit_operand" "=Ur") 244 (match_operator:HI 4 "bit_operator" 245 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") 246 (const_int 1) 247 (match_operand:HI 2 "immediate_operand" "n")) 248 (match_operand:HI 3 "bit_operand" "0")])) 249 (clobber (reg:CC CC_REG))] 250 "" 251 "bld %Z2,%Y1\;b%c4 #0,%R0\;bst #0,%R0; bl1" 252 [(set_attr "length" "6")]) 253 254(define_insn_and_split "" 255 [(set (match_operand:HI 0 "bit_operand" "=Ur") 256 (match_operator:HI 5 "bit_operator" 257 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") 258 (const_int 1) 259 (match_operand:HI 2 "immediate_operand" "n")) 260 (zero_extract:HI (match_operand:HI 3 "register_operand" "r") 261 (const_int 1) 262 (match_operand:HI 4 "immediate_operand" "n"))]))] 263 "" 264 "#" 265 "&& reload_completed" 266 [(parallel [(set (match_dup 0) 267 (match_op_dup 5 [(zero_extract:HI (match_dup 1) 268 (const_int 1) 269 (match_dup 2)) 270 (zero_extract:HI (match_dup 3) 271 (const_int 1) 272 (match_dup 4))])) 273 (clobber (reg:CC CC_REG))])]) 274 275(define_insn "" 276 [(set (match_operand:HI 0 "bit_operand" "=Ur") 277 (match_operator:HI 5 "bit_operator" 278 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") 279 (const_int 1) 280 (match_operand:HI 2 "immediate_operand" "n")) 281 (zero_extract:HI (match_operand:HI 3 "register_operand" "r") 282 (const_int 1) 283 (match_operand:HI 4 "immediate_operand" "n"))])) 284 (clobber (reg:CC CC_REG))] 285 "" 286 "bld %Z2,%Y1\;b%c5 %Z4,%Y3\;bst #0,%R0; bl3" 287 [(set_attr "length" "6")]) 288 289(define_insn_and_split "bfld" 290 [(set (match_operand:QI 0 "register_operand" "=r") 291 (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU") 292 (match_operand:QI 2 "immediate_operand" "n") 293 (match_operand:QI 3 "immediate_operand" "n")))] 294 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8" 295 "#" 296 "&& reload_completed" 297 [(parallel [(set (match_dup 0) 298 (zero_extract:QI (match_dup 1) (match_dup 2) (match_dup 3))) 299 (clobber (reg:CC CC_REG))])]) 300 301(define_insn "bfld_clobber_flags" 302 [(set (match_operand:QI 0 "register_operand" "=r") 303 (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU") 304 (match_operand:QI 2 "immediate_operand" "n") 305 (match_operand:QI 3 "immediate_operand" "n"))) 306 (clobber (reg:CC CC_REG))] 307 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8" 308{ 309 operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3]))) 310 - (1 << INTVAL (operands[3]))); 311 return "bfld %2,%1,%R0"; 312} 313 [(set_attr "length_table" "bitfield")]) 314 315(define_insn_and_split "bfst" 316 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU") 317 (match_operand:QI 2 "immediate_operand" "n") 318 (match_operand:QI 3 "immediate_operand" "n")) 319 (match_operand:QI 1 "register_operand" "r"))] 320 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8" 321 "#" 322 "&& reload_completed" 323 [(parallel [(set (zero_extract:QI (match_dup 0) (match_dup 2) (match_dup 3)) 324 (match_dup 1)) 325 (clobber (reg:CC CC_REG))])]) 326 327(define_insn "bfst_clobber_flags" 328 [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU") 329 (match_operand:QI 2 "immediate_operand" "n") 330 (match_operand:QI 3 "immediate_operand" "n")) 331 (match_operand:QI 1 "register_operand" "r")) 332 (clobber (reg:CC CC_REG))] 333 "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8" 334{ 335 operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3]))) 336 - (1 << INTVAL (operands[3]))); 337 return "bfst %R1,%2,%0"; 338} 339 [(set_attr "length_table" "bitfield")]) 340 341;;(define_insn "*bstzhireg" 342;; [(set (match_operand:HI 0 "register_operand" "=r") 343;; (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))] 344;; "TARGET_H8300SX" 345;; "mulu.w #0,%T0\;b%k1 .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:") 346 347;;(define_insn_and_split "*cmpstz" 348;; [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU") 349;; (const_int 1) 350;; (match_operand:QI 1 "immediate_operand" "n,n")) 351;; (match_operator:QI 2 "eqne_operator" 352;; [(match_operand 3 "h8300_dst_operand" "r,rQ") 353;; (match_operand 4 "h8300_src_operand" "I,rQi")]))] 354;; "TARGET_H8300SX 355;; && (GET_MODE (operands[3]) == GET_MODE (operands[4]) 356;; || GET_CODE (operands[4]) == CONST_INT) 357;; && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT 358;; && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4" 359;; "#" 360;; "reload_completed" 361;; [(set (cc0) (match_dup 5)) 362;; (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1)) 363;; (match_op_dup:QI 2 [(cc0) (const_int 0)]))] 364;; { 365;; operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]); 366;; }) 367 368;;(define_insn "*bstz" 369;; [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU") 370;; (const_int 1) 371;; (match_operand:QI 1 "immediate_operand" "n")) 372;; (eq:QI (cc0) (const_int 0)))] 373;; "TARGET_H8300SX && reload_completed" 374;; "bstz %1,%0" 375;; [(set_attr "length_table" "unary")]) 376 377;;(define_insn "*bistz" 378;; [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU") 379;; (const_int 1) 380;; (match_operand:QI 1 "immediate_operand" "n")) 381;; (ne:QI (cc0) (const_int 0)))] 382;; "TARGET_H8300SX && reload_completed" 383;; "bistz %1,%0" 384;; [(set_attr "length_table" "unary")]) 385 386;;(define_insn_and_split "*cmpcondbset" 387;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU") 388;; (if_then_else:QI (match_operator 1 "eqne_operator" 389;; [(match_operand 2 "h8300_dst_operand" "r,rQ") 390;; (match_operand 3 "h8300_src_operand" "I,rQi")]) 391;; (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0") 392;; (match_operand:QI 5 "single_one_operand" "n,n")) 393;; (match_dup 4)))] 394;; "TARGET_H8300SX" 395;; "#" 396;; "reload_completed" 397;; [(set (cc0) (match_dup 6)) 398;; (set (match_dup 0) 399;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)]) 400;; (ior:QI (match_dup 4) (match_dup 5)) 401;; (match_dup 4)))] 402;; { 403;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]); 404;; }) 405 406;;(define_insn "*condbset" 407;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU") 408;; (if_then_else:QI (match_operator:QI 2 "eqne_operator" 409;; [(cc0) (const_int 0)]) 410;; (ior:QI (match_operand:QI 3 "bit_memory_operand" "0") 411;; (match_operand:QI 1 "single_one_operand" "n")) 412;; (match_dup 3)))] 413;; "TARGET_H8300SX && reload_completed" 414;; "bset/%j2\t%V1,%0" 415;; [(set_attr "length_table" "logicb")]) 416 417;;(define_insn_and_split "*cmpcondbclr" 418;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU") 419;; (if_then_else:QI (match_operator 1 "eqne_operator" 420;; [(match_operand 2 "h8300_dst_operand" "r,rQ") 421;; (match_operand 3 "h8300_src_operand" "I,rQi")]) 422;; (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0") 423;; (match_operand:QI 5 "single_zero_operand" "n,n")) 424;; (match_dup 4)))] 425;; "TARGET_H8300SX" 426;; "#" 427;; "reload_completed" 428;; [(set (cc0) (match_dup 6)) 429;; (set (match_dup 0) 430;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)]) 431;; (and:QI (match_dup 4) (match_dup 5)) 432;; (match_dup 4)))] 433;; { 434;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]); 435;; }) 436 437;;(define_insn "*condbclr" 438;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU") 439;; (if_then_else:QI (match_operator:QI 2 "eqne_operator" 440;; [(cc0) (const_int 0)]) 441;; (and:QI (match_operand:QI 3 "bit_memory_operand" "0") 442;; (match_operand:QI 1 "single_zero_operand" "n")) 443;; (match_dup 3)))] 444;; "TARGET_H8300SX && reload_completed" 445;; "bclr/%j2\t%W1,%0" 446;; [(set_attr "length_table" "logicb")]) 447 448;;(define_insn_and_split "*cmpcondbsetreg" 449;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU") 450;; (if_then_else:QI (match_operator 1 "eqne_operator" 451;; [(match_operand 2 "h8300_dst_operand" "r,rQ") 452;; (match_operand 3 "h8300_src_operand" "I,rQi")]) 453;; (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0") 454;; (ashift:QI (const_int 1) 455;; (match_operand:QI 5 "register_operand" "r,r"))) 456;; (match_dup 4)))] 457;; "TARGET_H8300SX" 458;; "#" 459;; "reload_completed" 460;; [(set (cc0) (match_dup 6)) 461;; (set (match_dup 0) 462;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)]) 463;; (ior:QI (match_dup 4) 464;; (ashift:QI (const_int 1) 465;; (match_operand:QI 5 "register_operand" "r,r"))) 466;; (match_dup 4)))] 467;; { 468;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]); 469;; }) 470 471;;(define_insn "*condbsetreg" 472;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU") 473;; (if_then_else:QI (match_operator:QI 2 "eqne_operator" 474;; [(cc0) (const_int 0)]) 475;; (ior:QI (match_operand:QI 3 "bit_memory_operand" "0") 476;; (ashift:QI (const_int 1) 477;; (match_operand:QI 1 "register_operand" "r"))) 478;; (match_dup 3)))] 479;; "TARGET_H8300SX && reload_completed" 480;; "bset/%j2\t%R1,%0" 481;; [(set_attr "length_table" "logicb")]) 482 483;;(define_insn_and_split "*cmpcondbclrreg" 484;; [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU") 485;; (if_then_else:QI (match_operator 1 "eqne_operator" 486;; [(match_operand 2 "h8300_dst_operand" "r,rQ") 487;; (match_operand 3 "h8300_src_operand" "I,rQi")]) 488;; (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0") 489;; (ashift:QI (const_int 1) 490;; (match_operand:QI 5 "register_operand" "r,r"))) 491;; (match_dup 4)))] 492;; "TARGET_H8300SX" 493;; "#" 494;; "reload_completed" 495;; [(set (cc0) (match_dup 6)) 496;; (set (match_dup 0) 497;; (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)]) 498;; (and:QI (match_dup 4) 499;; (ashift:QI (const_int 1) 500;; (match_operand:QI 5 "register_operand" "r,r"))) 501;; (match_dup 4)))] 502;; { 503;; operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]); 504;; }) 505 506;;(define_insn "*condbclrreg" 507;; [(set (match_operand:QI 0 "bit_memory_operand" "=WU") 508;; (if_then_else:QI (match_operator:QI 2 "eqne_operator" 509;; [(cc0) (const_int 0)]) 510;; (and:QI (match_operand:QI 3 "bit_memory_operand" "0") 511;; (ashift:QI (const_int 1) 512;; (match_operand:QI 1 "register_operand" "r"))) 513;; (match_dup 3)))] 514;; "TARGET_H8300SX && reload_completed" 515;; "bclr/%j2\t%R1,%0" 516;; [(set_attr "length_table" "logicb")]) 517 518