The H8/SX has some extended capabilities for bit-and, bit-ior and bit-xor compared to earlier processors in the H8 family and thus there's some special patterns to handle them.
THe instructions work on byte sized chunks, but GCC is exposing them in HImode as well. It looks like someone tried to handle the big endian correction issues for the bit-and instruction and there's some chance that splitter might work. But the ior/xor pattern is clearly broken. I tried to fix the ior/xor pattern in a similar manner, but doing so highlighted that these insns don't allow reg+d addressing modes. It seems safest to limit when they apply. If someone cares enough they can always go back and try to handle the address adjustments (allocating a scratch as needed) and add support for SImode as well. So this patch restricts the existing splitter to cases where no address adjustment is needed. It removes bclrhi_msx and turns b<ior,xor>hi_msx into a splitter. Committing to the trunk. Jeff
commit f04f2fcd3d40f944f29189b1f995aa35ea04a379 Author: Jeff Law <l...@redhat.com> Date: Thu May 28 12:28:56 2020 -0600 Fix incorrect code generation with bit insns on H8/SX. * config/h8300/logical.md (HImode H8/SX bit-and splitter): Don't make a nonzero adjustment to the memory offset. (b<ior,xor>hi_msx): Turn into a splitter. diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md index 9dd863cdd8c..a099bbb4f5f 100644 --- a/gcc/config/h8300/logical.md +++ b/gcc/config/h8300/logical.md @@ -14,22 +14,14 @@ [(set (match_operand:HI 0 "bit_register_indirect_operand") (and:HI (match_operand:HI 1 "bit_register_indirect_operand") (match_operand:HI 2 "single_zero_operand")))] - "TARGET_H8300SX" + "TARGET_H8300SX && abs (INTVAL (operands[2])) > 0xff" [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))] { - if (abs (INTVAL (operands[2])) > 0xFF) - { - operands[0] = adjust_address (operands[0], QImode, 0); - operands[1] = adjust_address (operands[1], QImode, 0); - operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8); - } - else - { - operands[0] = adjust_address (operands[0], QImode, 1); - operands[1] = adjust_address (operands[1], QImode, 1); - } + operands[0] = adjust_address (operands[0], QImode, 0); + operands[1] = adjust_address (operands[1], QImode, 0); + operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8); }) (define_insn "bclrhi_msx" @@ -134,13 +126,19 @@ { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; } [(set_attr "length" "8")]) -(define_insn "b<code>hi_msx" - [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m") - (ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0") - (match_operand:HI 2 "single_one_operand" "Y2")))] - "TARGET_H8300SX" - { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; } - [(set_attr "length" "8")]) +(define_split + [(set (match_operand:HI 0 "bit_register_indirect_operand") + (ors:HI (match_operand:HI 1 "bit_register_indirect_operand") + (match_operand:HI 2 "single_one_operand")))] + "TARGET_H8300SX && abs (INTVAL (operands[2])) > 0xff" + [(set (match_dup 0) + (and:QI (match_dup 1) + (match_dup 2)))] + { + operands[0] = adjust_address (operands[0], QImode, 0); + operands[1] = adjust_address (operands[1], QImode, 0); + operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8); + }) (define_insn "<code>qi3_1" [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
commit ccf4e86dc01d8c89a8d56b228757a689d1fcc564 Author: Jeff Law <l...@redhat.com> Date: Thu May 28 12:37:08 2020 -0600 Finish prior patch * config/h8300/logical.md (bclrhi_msx): Remove pattern. diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md index a099bbb4f5f..7d24fad360a 100644 --- a/gcc/config/h8300/logical.md +++ b/gcc/config/h8300/logical.md @@ -24,14 +24,6 @@ operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8); }) -(define_insn "bclrhi_msx" - [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m") - (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0") - (match_operand:HI 2 "single_zero_operand" "Y0")))] - "TARGET_H8300SX" - "bclr\\t%W2,%0" - [(set_attr "length" "8")]) - (define_insn "*andqi3_2" [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r") (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")