--- /gcc/config/h8300/h8300.h.orig 2007-11-23 10:20:34.000000000 +0530 +++ /gcc/config/h8300/h8300.h 2007-11-23 10:21:48.000000000 +0530 @@ -848,10 +848,7 @@ struct cum_arg /* Multi-letter constraints starting with W are to be used for operands that require a memory operand, i.e,. that are never used - along with register constraints (see EXTRA_MEMORY_CONSTRAINTS). - For operands that require a memory operand (or not) but that always - accept a register, a multi-letter constraint starting with Y should - be used instead. */ + along with register constraints (see EXTRA_MEMORY_CONSTRAINTS). */ #define OK_FOR_WU(OP) \ (GET_CODE (OP) == MEM && OK_FOR_U (OP)) @@ -864,15 +861,25 @@ struct cum_arg ((STR)[1] == 'U' ? 2 \ : 0) -/* We don't have any constraint starting with Y yet, but before - someone uses it for a one-letter constraint and we're left without - any upper-case constraints left, we reserve it for extensions - here. */ -#define OK_FOR_Y(OP, STR) \ - (0) +/* Multi-letter constraints starting with Y are to be used for operands + that are constant immediates and have single 1 or 0 in their binary + representation. */ + +#define OK_FOR_Y2(OP) \ + ((GET_CODE (OP) == CONST_INT) && (exact_log2(INTVAL (OP) & 0xff) != -1)) + +#define OK_FOR_Y0(OP) \ + ((GET_CODE (OP) == CONST_INT) && (exact_log2(~INTVAL (OP) & 0xff) != -1)) + +#define OK_FOR_Y(OP, STR) \ + ((STR)[1] == '2' ? OK_FOR_Y2 (OP) \ + : (STR)[1] == '0' ? OK_FOR_Y0 (OP) \ + : 0) #define CONSTRAINT_LEN_FOR_Y(STR) \ - (0) + ((STR)[1] == '2' ? 2 \ + : (STR)[1] == '0' ? 2 \ + : 0) #define OK_FOR_Z(OP) \ (TARGET_H8300SX \ --- /gcc/config/h8300/h8300.md.orig 2007-11-23 10:20:37.000000000 +0530 +++ /gcc/config/h8300/h8300.md 2007-11-23 10:21:51.000000000 +0530 @@ -1736,28 +1736,29 @@ ;; ---------------------------------------------------------------------- (define_insn "*andqi3_2" - [(set (match_operand:QI 0 "bit_operand" "=rQ,r") - (and:QI (match_operand:QI 1 "bit_operand" "%0,WU") - (match_operand:QI 2 "h8300_src_operand" "rQi,IP1>X")))] + [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r") + (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU") + (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))] "TARGET_H8300SX" "@ + bclr\\t %W2,%R0 and %X2,%X0 bfld %2,%1,%R0" - [(set_attr "length" "*,8") - (set_attr "length_table" "logicb,*") - (set_attr "cc" "set_znv,none_0hit")]) + [(set_attr "length" "8,*,8") + (set_attr "length_table" "*,logicb,*") + (set_attr "cc" "none_0hit,set_znv,none_0hit")]) (define_insn "andqi3_1" - [(set (match_operand:QI 0 "bit_operand" "=r,U") + [(set (match_operand:QI 0 "bit_operand" "=U,r") (and:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "rn,n")))] + (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))] "register_operand (operands[0], QImode) || single_zero_operand (operands[2], QImode)" "@ - and %X2,%X0 - bclr %W2,%R0" - [(set_attr "length" "2,8") - (set_attr "cc" "set_znv,none_0hit")]) + bclr %W2,%R0 + and %X2,%X0" + [(set_attr "length" "8,2") + (set_attr "cc" "none_0hit,set_znv")]) (define_expand "andqi3" [(set (match_operand:QI 0 "register_operand" "") @@ -1840,17 +1841,17 @@ ;; ---------------------------------------------------------------------- (define_insn "iorqi3_1" - [(set (match_operand:QI 0 "bit_operand" "=rQ,U") + [(set (match_operand:QI 0 "bit_operand" "=U,rQ") (ior:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "rQi,n")))] + (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))] "TARGET_H8300SX || register_operand (operands[0], QImode) || single_one_operand (operands[2], QImode)" "@ - or\\t%X2,%X0 - bset\\t%V2,%R0" - [(set_attr "length" "*,8") - (set_attr "length_table" "logicb,*") - (set_attr "cc" "set_znv,none_0hit")]) + bset\\t%V2,%R0 + or\\t%X2,%X0" + [(set_attr "length" "8,*") + (set_attr "length_table" "*,logicb") + (set_attr "cc" "none_0hit,set_znv")]) (define_expand "iorqi3" [(set (match_operand:QI 0 "register_operand" "") @@ -1878,17 +1879,17 @@ ;; ---------------------------------------------------------------------- (define_insn "xorqi3_1" - [(set (match_operand:QI 0 "bit_operand" "=r,U") + [(set (match_operand:QI 0 "bit_operand" "=U,r") (xor:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "rQi,n")))] + (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))] "TARGET_H8300SX || register_operand (operands[0], QImode) || single_one_operand (operands[2], QImode)" "@ - xor\\t%X2,%X0 - bnot\\t%V2,%R0" - [(set_attr "length" "*,8") - (set_attr "length_table" "logicb,*") - (set_attr "cc" "set_znv,none_0hit")]) + bnot\\t%V2,%R0 + xor\\t%X2,%X0" + [(set_attr "length" "8,*") + (set_attr "length_table" "*,logicb") + (set_attr "cc" "none_0hit,set_znv")]) (define_expand "xorqi3" [(set (match_operand:QI 0 "register_operand" "") --- /gcc/testsuite/gcc.c-torture/execute/20071123-1.c 1970-01-01 05:30:00.000000000 +0530 +++ /gcc/testsuite/gcc.c-torture/execute/20071123-1.c 2007-11-23 17:42:21.000000000 +0530 @@ -0,0 +1,28 @@ +/* Testcase to check generation of bnot and bset instructions. */ + +/* { dg-do assemble {target h8300*-*-*}} */ +/* { dg-options "" } */ +/* { dg-skip-if "" { "h8300*-*-*" } "*" "*" } */ +/* { dg-final { scan-assembler "bset"} } */ +/* { dg-final { scan-assembler "bclr"} } */ + +volatile union un_test +{ + unsigned char BYTE; + struct + { + unsigned char B2:6; + unsigned char B1:1; + unsigned char B0:1; + } + BIT; +} +un_obj; + +int +main () +{ + un_obj.BIT.B0 = 1; //should generate BSET + un_obj.BIT.B1 = 0; //should generate BCLR + return 0; +}