From 75ca1b39e545c4d48669f540282b2e004a91e395 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Dec 2012 10:04:41 -0800 Subject: [PATCH] s390: Constraints, predicates, and op letters for contiguous bitmasks * config/s390/constraints.md (NxxDq, NxxSq): New. * config/s390/predicates.md (contiguous_bitmask_operand): New. * config/s390/s390.c (print_operand) ['e', 'f', 's', 't']: New operand letters. * config/s390/s390.md (bfstart, bfend): New mode attrs. (*insv_zEC12_noshift): Use them. (*insv_z10_noshift): Likewise. (*insv_or_z10_noshift): Likewise. Co-Authored-By: Andreas Krebbel From-SVN: r194640 --- gcc/ChangeLog | 12 +++++ gcc/config/s390/constraints.md | 11 +++- gcc/config/s390/predicates.md | 6 +++ gcc/config/s390/s390.c | 92 +++++++++++++++++++++++----------- gcc/config/s390/s390.md | 74 ++++++--------------------- 5 files changed, 106 insertions(+), 89 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8708f8325d8..e4aeb8996fd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2012-12-20 Richard Henderson + Andreas Krebbel + + * config/s390/constraints.md (NxxDq, NxxSq): New. + * config/s390/predicates.md (contiguous_bitmask_operand): New. + * config/s390/s390.c (print_operand) ['e', 'f', 's', 't']: New + operand letters. + * config/s390/s390.md (bfstart, bfend): New mode attrs. + (*insv_zEC12_noshift): Use them. + (*insv_z10_noshift): Likewise. + (*insv_or_z10_noshift): Likewise. + 2012-12-20 Thomas Schwinge PR bootstrap/55202 diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md index 8564b6619a5..9d416adb165 100644 --- a/gcc/config/s390/constraints.md +++ b/gcc/config/s390/constraints.md @@ -45,6 +45,8 @@ ;; H,Q: mode of the part ;; D,S,H: mode of the containing operand ;; 0,F: value of the other parts (F - all bits set) +;; -- +;; xx[DS]q satisfies s390_contiguous_bitmask_p for DImode or SImode ;; ;; The constraint matches if the specified part of a constant ;; has a value different from its other parts. If the letter x @@ -330,8 +332,15 @@ (and (match_code "const_int") (match_test "s390_N_constraint_str (\"xQH0\", ival)"))) +(define_constraint "NxxDq" + "@internal" + (and (match_code "const_int") + (match_test "s390_contiguous_bitmask_p (ival, 64, NULL, NULL)"))) - +(define_constraint "NxxSq" + "@internal" + (and (match_code "const_int") + (match_test "s390_contiguous_bitmask_p (ival, 32, NULL, NULL)"))) ;; ;; Double-letter constraints starting with O follow. diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index 9ba85bf387c..b9524ecc664 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -154,6 +154,12 @@ return false; }) +(define_predicate "contiguous_bitmask_operand" + (match_code "const_int") +{ + return s390_contiguous_bitmask_p (INTVAL (op), GET_MODE_BITSIZE (mode), NULL, NULL); +}) + ;; operators -------------------------------------------------------------- ;; Return nonzero if OP is a valid comparison operator diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 441d9c1fe5c..d38ba7f79fb 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -5368,28 +5368,35 @@ print_operand_address (FILE *file, rtx addr) 'C': print opcode suffix for branch condition. 'D': print opcode suffix for inverse branch condition. 'E': print opcode suffix for branch on index instruction. - 'J': print tls_load/tls_gdcall/tls_ldcall suffix 'G': print the size of the operand in bytes. + 'J': print tls_load/tls_gdcall/tls_ldcall suffix + 'M': print the second word of a TImode operand. + 'N': print the second word of a DImode operand. 'O': print only the displacement of a memory reference. 'R': print only the base register of a memory reference. 'S': print S-type memory reference (base+displacement). - 'N': print the second word of a DImode operand. - 'M': print the second word of a TImode operand. 'Y': print shift count operand. 'b': print integer X as if it's an unsigned byte. 'c': print integer X as if it's an signed byte. - 'x': print integer X as if it's an unsigned halfword. + 'e': "end" of DImode contiguous bitmask X. + 'f': "end" of SImode contiguous bitmask X. 'h': print integer X as if it's a signed halfword. 'i': print the first nonzero HImode part of X. 'j': print the first HImode part unequal to -1 of X. 'k': print the first nonzero SImode part of X. 'm': print the first SImode part unequal to -1 of X. - 'o': print integer X as if it's an unsigned 32bit word. */ + 'o': print integer X as if it's an unsigned 32bit word. + 's': "start" of DImode contiguous bitmask X. + 't': "start" of SImode contiguous bitmask X. + 'x': print integer X as if it's an unsigned halfword. +*/ void print_operand (FILE *file, rtx x, int code) { + HOST_WIDE_INT ival; + switch (code) { case 'C': @@ -5568,30 +5575,57 @@ print_operand (FILE *file, rtx x, int code) break; case CONST_INT: - if (code == 'b') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff); - else if (code == 'c') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xff) ^ 0x80) - 0x80); - else if (code == 'x') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff); - else if (code == 'h') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000); - else if (code == 'i') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - s390_extract_part (x, HImode, 0)); - else if (code == 'j') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - s390_extract_part (x, HImode, -1)); - else if (code == 'k') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - s390_extract_part (x, SImode, 0)); - else if (code == 'm') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - s390_extract_part (x, SImode, -1)); - else if (code == 'o') - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffffffff); - else - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); + ival = INTVAL (x); + switch (code) + { + case 0: + break; + case 'b': + ival &= 0xff; + break; + case 'c': + ival = ((ival & 0xff) ^ 0x80) - 0x80; + break; + case 'x': + ival &= 0xffff; + break; + case 'h': + ival = ((ival & 0xffff) ^ 0x8000) - 0x8000; + break; + case 'i': + ival = s390_extract_part (x, HImode, 0); + break; + case 'j': + ival = s390_extract_part (x, HImode, -1); + break; + case 'k': + ival = s390_extract_part (x, SImode, 0); + break; + case 'm': + ival = s390_extract_part (x, SImode, -1); + break; + case 'o': + ival &= 0xffffffff; + break; + case 'e': case 'f': + case 's': case 't': + { + int pos, len; + bool ok; + + len = (code == 's' || code == 'e' ? 64 : 32); + ok = s390_contiguous_bitmask_p (ival, len, &pos, &len); + gcc_assert (ok); + if (code == 's' || code == 't') + ival = 64 - pos - len; + else + ival = 64 - 1 - pos; + } + break; + default: + output_operand_lossage ("invalid constant for output modifier '%c'", code); + } + fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival); break; case CONST_DOUBLE: diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index bea58cd7a83..ee030ba43a4 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -527,6 +527,10 @@ ;; Maximum unsigned integer that fits in MODE. (define_mode_attr max_uint [(HI "65535") (QI "255")]) +;; Start and end field computations for RISBG et al. +(define_mode_attr bfstart [(DI "s") (SI "t")]) +(define_mode_attr bfend [(DI "e") (SI "f")]) + ;; ;;- Compare instructions. ;; @@ -3420,56 +3424,22 @@ (define_insn "*insv_zEC12_noshift" [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d") - (match_operand 2 "const_int_operand" "n")) + (match_operand:GPR 2 "contiguous_bitmask_operand" "")) (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0") - (match_operand 4 "const_int_operand" "n"))))] - "TARGET_ZEC12 - && s390_contiguous_bitmask_p (INTVAL (operands[2]), - GET_MODE_BITSIZE (mode), NULL, NULL) - && INTVAL (operands[2]) == ~(INTVAL (operands[4]))" - -{ - int start; - int size; - - s390_contiguous_bitmask_p (INTVAL (operands[2]), - GET_MODE_BITSIZE (mode), &start, &size); - - operands[5] = GEN_INT (64 - start - size); /* start bit position */ - operands[6] = GEN_INT (64 - 1 - start); /* end bit position */ - operands[7] = const0_rtx; /* left shift count */ - - return "risbgn\t%0,%1,%b5,%b6,%b7"; -} + (match_operand:GPR 4 "const_int_operand" ""))))] + "TARGET_ZEC12 && INTVAL (operands[2]) == ~INTVAL (operands[4])" + "risbgn\t%0,%1,%2,%2,0" [(set_attr "op_type" "RIE")]) -; and op1 with a mask being 1 for the selected bits and 0 for the rest -; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest (define_insn "*insv_z10_noshift" [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d") - (match_operand 2 "const_int_operand" "n")) + (match_operand:GPR 2 "contiguous_bitmask_operand" "")) (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0") - (match_operand 4 "const_int_operand" "n")))) + (match_operand:GPR 4 "const_int_operand" "")))) (clobber (reg:CC CC_REGNUM))] - "TARGET_Z10 - && s390_contiguous_bitmask_p (INTVAL (operands[2]), - GET_MODE_BITSIZE (mode), NULL, NULL) - && INTVAL (operands[2]) == ~(INTVAL (operands[4]))" - -{ - int start; - int size; - - s390_contiguous_bitmask_p (INTVAL (operands[2]), - GET_MODE_BITSIZE (mode), &start, &size); - - operands[5] = GEN_INT (64 - start - size); /* start bit position */ - operands[6] = GEN_INT (64 - 1 - start); /* end bit position */ - operands[7] = const0_rtx; /* left shift count */ - - return "risbg\t%0,%1,%b5,%b6,%b7"; -} + "TARGET_Z10 && INTVAL (operands[2]) == ~INTVAL (operands[4])" + "risbg\t%0,%1,%2,%2,0" [(set_attr "op_type" "RIE") (set_attr "z10prop" "z10_super_E1")]) @@ -3477,25 +3447,11 @@ (define_insn "*insv_or_z10_noshift" [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d") - (match_operand 2 "const_int_operand" "n")) + (match_operand:GPR 2 "contiguous_bitmask_operand" "")) (match_operand:GPR 3 "nonimmediate_operand" "0"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_Z10 - && s390_contiguous_bitmask_p (INTVAL (operands[2]), - GET_MODE_BITSIZE (mode), NULL, NULL)" -{ - int start; - int size; - - s390_contiguous_bitmask_p (INTVAL (operands[2]), - GET_MODE_BITSIZE (mode), &start, &size); - - operands[4] = GEN_INT (64 - start - size); /* start bit position */ - operands[5] = GEN_INT (64 - 1 - start); /* end bit position */ - operands[6] = const0_rtx; /* left shift count */ - - return "rosbg\t%0,%1,%b4,%b5,%b6"; -} + "TARGET_Z10" + "rosbg\t%0,%1,%2,%2,0" [(set_attr "op_type" "RIE")]) (define_insn "*insv_mem_reg" -- 2.30.2