1;; Generic for binary logicals across the supported integer modes 2(define_expand "<code><mode>3" 3 [(set (match_operand:QHSI 0 "register_operand" "") 4 (logicals:QHSI (match_operand:QHSI 1 "register_operand" "") 5 (match_operand:QHSI 2 "h8300_src_operand" "")))] 6 "" 7 " 8 { 9 enum machine_mode mode = GET_MODE (operands[0]); 10 /* DImodes are not considered tieable, as a result operations involving 11 subregs of DImode objects are considered expensive which can prevent 12 CSE from doing obvious simplifications. 13 14 We may ultimately change what is tieable, but this is an immediate 15 workaround while we evaluate changes to tieable modes. 16 17 The key in terms of what we want to handle is then the result of 18 the operation is not a constant. */ 19 if ((<CODE> == AND && operands[2] == CONSTM1_RTX (mode)) 20 || (<CODE> == IOR && operands[2] == CONST0_RTX (mode)) 21 || (<CODE> == XOR && operands[2] == CONST0_RTX (mode)) 22 || ((<CODE> == AND || <CODE> == IOR) && operands[1] == operands[2])) 23 { 24 emit_move_insn (operands[0], operands[1]); 25 DONE; 26 } 27 }") 28 29;; There's a ton of cleanup to do from here below. 30;; ---------------------------------------------------------------------- 31;; AND INSTRUCTIONS 32;; ---------------------------------------------------------------------- 33 34(define_insn "bclr<mode>_msx" 35 [(set (match_operand:QHI 0 "bit_register_indirect_operand" "=WU") 36 (and:QHI (match_operand:QHI 1 "bit_register_indirect_operand" "%0") 37 (match_operand:QHI 2 "single_zero_operand" "Y0")))] 38 "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])" 39 "bclr\\t%W2,%0" 40 [(set_attr "length" "8")]) 41 42(define_split 43 [(set (match_operand:HI 0 "bit_register_indirect_operand") 44 (and:HI (match_operand:HI 1 "bit_register_indirect_operand") 45 (match_operand:HI 2 "single_zero_operand")))] 46 "TARGET_H8300SX && abs (INTVAL (operands[2])) > 0xff" 47 [(set (match_dup 0) 48 (and:QI (match_dup 1) 49 (match_dup 2)))] 50 { 51 operands[0] = adjust_address (operands[0], QImode, 0); 52 operands[1] = adjust_address (operands[1], QImode, 0); 53 operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8); 54 }) 55 56(define_insn_and_split "*andqi3_2" 57 [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r") 58 (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU") 59 (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))] 60 "TARGET_H8300SX" 61 "#" 62 "&& reload_completed" 63 [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2))) 64 (clobber (reg:CC CC_REG))])]) 65 66(define_insn "*andqi3_2_clobber_flags" 67 [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r") 68 (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU") 69 (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X"))) 70 (clobber (reg:CC CC_REG))] 71 "TARGET_H8300SX" 72 "@ 73 bclr\\t %W2,%R0 74 and %X2,%X0 75 bfld %2,%1,%R0" 76 [(set_attr "length" "8,*,8") 77 (set_attr "length_table" "*,logicb,*")]) 78 79(define_insn_and_split "andqi3_1" 80 [(set (match_operand:QI 0 "bit_operand" "=U,r") 81 (and:QI (match_operand:QI 1 "bit_operand" "%0,0") 82 (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))] 83 "register_operand (operands[0], QImode) 84 || single_zero_operand (operands[2], QImode)" 85 "bclr %W2,%R0" 86 "&& reload_completed && !single_zero_operand (operands[2], QImode)" 87 [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2))) 88 (clobber (reg:CC CC_REG))])] 89 "" 90 [(set_attr "length" "8,2")]) 91 92 93(define_insn_and_split "*andor<mode>3" 94 [(set (match_operand:QHSI 0 "register_operand" "=r") 95 (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r") 96 (match_operand:QHSI 3 "single_one_operand" "n")) 97 (match_operand:QHSI 1 "register_operand" "0")))] 98 "(<MODE>mode == QImode 99 || <MODE>mode == HImode 100 || (<MODE>mode == SImode 101 && (INTVAL (operands[3]) & 0xffff) != 0))" 102 "#" 103 "&& reload_completed" 104 [(parallel [(set (match_dup 0) (ior:QHSI (and:QHSI (match_dup 2) 105 (match_dup 3)) 106 (match_dup 1))) 107 (clobber (reg:CC CC_REG))])]) 108 109(define_insn "*andor<mode>3_clobber_flags" 110 [(set (match_operand:QHSI 0 "register_operand" "=r") 111 (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r") 112 (match_operand:QHSI 3 "single_one_operand" "n")) 113 (match_operand:QHSI 1 "register_operand" "0"))) 114 (clobber (reg:CC CC_REG))] 115 "(<MODE>mode == QImode 116 || <MODE>mode == HImode 117 || (<MODE>mode == SImode 118 && (INTVAL (operands[3]) & 0xffff) != 0))" 119 { 120 if (<MODE>mode == QImode) 121 return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"; 122 123 if (<MODE>mode == HImode) 124 { 125 operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); 126 if (INTVAL (operands[3]) > 128) 127 { 128 operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); 129 return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0"; 130 } 131 return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0"; 132 } 133 134 if (<MODE>mode == SImode) 135 { 136 operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); 137 if (INTVAL (operands[3]) > 128) 138 { 139 operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); 140 return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0"; 141 } 142 return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0"; 143 } 144 145 gcc_unreachable (); 146 147 } 148 [(set_attr "length" "6")]) 149 150(define_insn_and_split "*andorsi3_shift_8" 151 [(set (match_operand:SI 0 "register_operand" "=r") 152 (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") 153 (const_int 8)) 154 (const_int 65280)) 155 (match_operand:SI 1 "register_operand" "0")))] 156 "" 157 "#" 158 "&& reload_completed" 159 [(parallel [(set (match_dup 0) (ior:SI (and:SI (ashift:SI (match_dup 2) 160 (const_int 8)) 161 (const_int 65280)) 162 (match_dup 1))) 163 (clobber (reg:CC CC_REG))])]) 164 165(define_insn "*andorsi3_shift_8_clobber_flags" 166 [(set (match_operand:SI 0 "register_operand" "=r") 167 (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") 168 (const_int 8)) 169 (const_int 65280)) 170 (match_operand:SI 1 "register_operand" "0"))) 171 (clobber (reg:CC CC_REG))] 172 "" 173 "or.b\\t%w2,%x0" 174 [(set_attr "length" "2")]) 175 176;; ---------------------------------------------------------------------- 177;; OR/XOR INSTRUCTIONS 178;; ---------------------------------------------------------------------- 179 180(define_insn "b<code><mode>_msx" 181 [(set (match_operand:QHI 0 "bit_register_indirect_operand" "=WU") 182 (ors:QHI (match_operand:QHI 1 "bit_register_indirect_operand" "%0") 183 (match_operand:QHI 2 "single_one_operand" "Y2")))] 184 "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])" 185 { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; } 186 [(set_attr "length" "8")]) 187 188(define_insn_and_split "<code>qi3_1" 189 [(set (match_operand:QI 0 "bit_operand" "=U,rQ") 190 (ors:QI (match_operand:QI 1 "bit_operand" "%0,0") 191 (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))] 192 "TARGET_H8300SX || register_operand (operands[0], QImode) 193 || single_one_operand (operands[2], QImode)" 194 { return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0"; } 195 "&& reload_completed && !single_one_operand (operands[2], QImode)" 196 [(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2))) 197 (clobber (reg:CC CC_REG))])] 198 "" 199 [(set_attr "length" "8")]) 200 201(define_insn "*<code>qi3_1<cczn>" 202 [(set (match_operand:QI 0 "bit_operand" "=rQ") 203 (ors:QI (match_operand:QI 1 "bit_operand" "%0") 204 (match_operand:QI 2 "h8300_src_operand" "rQi"))) 205 (clobber (reg:CC CC_REG))] 206 "TARGET_H8300SX" 207 { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; } 208 [(set_attr "length" "*") 209 (set_attr "length_table" "logicb")]) 210 211(define_insn "*<code>qi3_1<cczn>" 212 [(set (match_operand:QI 0 "register_operand" "=r") 213 (ors:QI (match_operand:QI 1 "register_operand" "%0") 214 (match_operand:QI 2 "h8300_src_operand" "ri"))) 215 (clobber (reg:CC CC_REG))] 216 "TARGET_H8300SX" 217 { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; } 218 [(set_attr "length" "*") 219 (set_attr "length_table" "logicb")]) 220 221(define_insn "*<code>qi3_1<cczn>" 222 [(set (match_operand:QI 0 "register_operand" "=r") 223 (logicals:QI (match_operand:QI 1 "register_operand" "%0") 224 (match_operand:QI 2 "h8300_src_operand" "rn"))) 225 (clobber (reg:CC CC_REG))] 226 "" 227 { 228 if (<CODE> == IOR) 229 return "or\\t%X2,%X0"; 230 else if (<CODE> == XOR) 231 return "xor\\t%X2,%X0"; 232 else if (<CODE> == AND) 233 return "and\\t%X2,%X0"; 234 gcc_unreachable (); 235 } 236 [(set_attr "length" "2")]) 237 238;; ---------------------------------------------------------------------- 239;; {AND,IOR,XOR}{HI3,SI3} PATTERNS 240;; ---------------------------------------------------------------------- 241 242(define_insn_and_split "*logical<mode>3" 243 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ") 244 (logicals:QHSI 245 (match_operand:QHSI 1 "h8300_dst_operand" "%0") 246 (match_operand:QHSI 2 "h8300_src_operand" "rQi")))] 247 "h8300_operands_match_p (operands)" 248 "#" 249 "&& reload_completed" 250 [(parallel [(set (match_dup 0) 251 (logicals:QHSI (match_dup 1) (match_dup 2))) 252 (clobber (reg:CC CC_REG))])]) 253 254(define_insn "*<code><mode>3<cczn>" 255 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ") 256 (logicals:QHSI 257 (match_operand:QHSI 1 "h8300_dst_operand" "%0") 258 (match_operand:QHSI 2 "h8300_src_operand" "rQi"))) 259 (clobber (reg:CC CC_REG))] 260 "h8300_operands_match_p (operands)" 261 { return output_logical_op (<MODE>mode, <CODE>, operands, insn); } 262 [(set (attr "length") 263 (symbol_ref "compute_logical_op_length (<MODE>mode, <CODE>, operands, insn)"))]) 264 265;; ---------------------------------------------------------------------- 266;; NOT INSTRUCTIONS 267;; ---------------------------------------------------------------------- 268 269(define_insn_and_split "one_cmpl<mode>2" 270 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ") 271 (not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))] 272 "" 273 "#" 274 "&& reload_completed" 275 [(parallel [(set (match_dup 0) (not:QHSI (match_dup 1))) 276 (clobber (reg:CC CC_REG))])]) 277 278(define_insn "one_cmpl<mode>2_<cczn>" 279 [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ") 280 (not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0"))) 281 (clobber (reg:CC CC_REG))] 282 "" 283 { 284 if (<MODE>mode == E_QImode) 285 return "not %X0"; 286 if (<MODE>mode == E_HImode) 287 return "not.w %T0"; 288 if (<MODE>mode == E_SImode) 289 return "not.l %S0"; 290 gcc_unreachable (); 291 } 292 [(set_attr "length_table" "unary")]) 293 294;; The next four peephole2's will try to transform 295;; 296;; mov.b A,r0l (or mov.l A,er0) 297;; and.l #CST,er0 298;; 299;; into 300;; 301;; sub.l er0 302;; mov.b A,r0l 303;; and.b #CST,r0l (if CST is not 255) 304 305(define_peephole2 306 [(parallel [(set (match_operand:QI 0 "register_operand" "") 307 (match_operand:QI 1 "general_operand" "")) 308 (clobber (reg:CC CC_REG))]) 309 (parallel [(set (match_operand:SI 2 "register_operand" "") 310 (and:SI (match_dup 2) (const_int 255))) 311 (clobber (reg:CC CC_REG))])] 312 "!reg_overlap_mentioned_p (operands[2], operands[1]) 313 && REGNO (operands[0]) == REGNO (operands[2])" 314 [(parallel [(set (match_dup 2) (const_int 0)) 315 (clobber (reg:CC CC_REG))]) 316 (parallel [(set (strict_low_part (match_dup 0)) (match_dup 1)) 317 (clobber (reg:CC CC_REG))])]) 318 319(define_peephole2 320 [(parallel [(set (match_operand:SI 0 "register_operand" "") 321 (match_operand:SI 1 "nonimmediate_operand" "")) 322 (clobber (reg:CC CC_REG))]) 323 (parallel [(set (match_dup 0) 324 (and:SI (match_dup 0) (const_int 255))) 325 (clobber (reg:CC CC_REG))])] 326 "!reg_overlap_mentioned_p (operands[0], operands[1]) 327 && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1])) 328 && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))" 329 [(parallel [(set (match_dup 0) (const_int 0)) 330 (clobber (reg:CC CC_REG))]) 331 (parallel [(set (strict_low_part (match_dup 2)) (match_dup 3)) 332 (clobber (reg:CC CC_REG))])] 333 { 334 operands[2] = gen_lowpart (QImode, operands[0]); 335 operands[3] = gen_lowpart (QImode, operands[1]); 336 }) 337 338(define_peephole2 339 [(parallel [(set (match_operand 0 "register_operand" "") 340 (match_operand 1 "nonimmediate_operand" "")) 341 (clobber (reg:CC CC_REG))]) 342 (parallel [(set (match_operand:SI 2 "register_operand" "") 343 (and:SI (match_dup 2) 344 (match_operand:SI 3 "const_int_qi_operand" ""))) 345 (clobber (reg:CC CC_REG))])] 346 "(GET_MODE (operands[0]) == QImode 347 || GET_MODE (operands[0]) == HImode 348 || GET_MODE (operands[0]) == SImode) 349 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 350 && REGNO (operands[0]) == REGNO (operands[2]) 351 && !reg_overlap_mentioned_p (operands[2], operands[1]) 352 && !(GET_MODE (operands[1]) != QImode 353 && GET_CODE (operands[1]) == MEM 354 && !offsettable_memref_p (operands[1])) 355 && !(GET_MODE (operands[1]) != QImode 356 && GET_CODE (operands[1]) == MEM 357 && MEM_VOLATILE_P (operands[1]))" 358 [(parallel [(set (match_dup 2) (const_int 0)) 359 (clobber (reg:CC CC_REG))]) 360 (parallel [(set (strict_low_part (match_dup 4)) (match_dup 5)) 361 (clobber (reg:CC CC_REG))]) 362 (parallel [(set (match_dup 2) (and:SI (match_dup 2) (match_dup 6))) 363 (clobber (reg:CC CC_REG))])] 364 { 365 operands[4] = gen_lowpart (QImode, operands[0]); 366 operands[5] = gen_lowpart (QImode, operands[1]); 367 operands[6] = GEN_INT (~0xff | INTVAL (operands[3])); 368 }) 369 370(define_peephole2 371 [(parallel [(set (match_operand:SI 0 "register_operand" "") 372 (match_operand:SI 1 "register_operand" "")) 373 (clobber (reg:CC CC_REG))]) 374 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65280))) 375 (clobber (reg:CC CC_REG))])] 376 "!reg_overlap_mentioned_p (operands[0], operands[1])" 377 [(parallel [(set (match_dup 0) (const_int 0)) 378 (clobber (reg:CC CC_REG))]) 379 (parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 380 (lshiftrt:SI (match_dup 1) (const_int 8))) 381 (clobber (reg:CC CC_REG))])]) 382