Commit 75ca1b39 by Richard Henderson Committed by Richard Henderson

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<GPR>_zEC12_noshift): Use them.
        (*insv<GPR>_z10_noshift): Likewise.
        (*insv<GPR>_or_z10_noshift): Likewise.

Co-Authored-By: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>

From-SVN: r194640
parent 00155043
2012-12-20 Richard Henderson <rth@redhat.com>
Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* 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<GPR>_zEC12_noshift): Use them.
(*insv<GPR>_z10_noshift): Likewise.
(*insv<GPR>_or_z10_noshift): Likewise.
2012-12-20 Thomas Schwinge <thomas@codesourcery.com> 2012-12-20 Thomas Schwinge <thomas@codesourcery.com>
PR bootstrap/55202 PR bootstrap/55202
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
;; H,Q: mode of the part ;; H,Q: mode of the part
;; D,S,H: mode of the containing operand ;; D,S,H: mode of the containing operand
;; 0,F: value of the other parts (F - all bits set) ;; 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 ;; The constraint matches if the specified part of a constant
;; has a value different from its other parts. If the letter x ;; has a value different from its other parts. If the letter x
...@@ -330,8 +332,15 @@ ...@@ -330,8 +332,15 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "s390_N_constraint_str (\"xQH0\", ival)"))) (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. ;; Double-letter constraints starting with O follow.
......
...@@ -154,6 +154,12 @@ ...@@ -154,6 +154,12 @@
return false; 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 -------------------------------------------------------------- ;; operators --------------------------------------------------------------
;; Return nonzero if OP is a valid comparison operator ;; Return nonzero if OP is a valid comparison operator
......
...@@ -5368,28 +5368,35 @@ print_operand_address (FILE *file, rtx addr) ...@@ -5368,28 +5368,35 @@ print_operand_address (FILE *file, rtx addr)
'C': print opcode suffix for branch condition. 'C': print opcode suffix for branch condition.
'D': print opcode suffix for inverse branch condition. 'D': print opcode suffix for inverse branch condition.
'E': print opcode suffix for branch on index instruction. '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. '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. 'O': print only the displacement of a memory reference.
'R': print only the base register of a memory reference. 'R': print only the base register of a memory reference.
'S': print S-type memory reference (base+displacement). '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. 'Y': print shift count operand.
'b': print integer X as if it's an unsigned byte. 'b': print integer X as if it's an unsigned byte.
'c': print integer X as if it's an signed 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. 'h': print integer X as if it's a signed halfword.
'i': print the first nonzero HImode part of X. 'i': print the first nonzero HImode part of X.
'j': print the first HImode part unequal to -1 of X. 'j': print the first HImode part unequal to -1 of X.
'k': print the first nonzero SImode part of X. 'k': print the first nonzero SImode part of X.
'm': print the first SImode part unequal to -1 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 void
print_operand (FILE *file, rtx x, int code) print_operand (FILE *file, rtx x, int code)
{ {
HOST_WIDE_INT ival;
switch (code) switch (code)
{ {
case 'C': case 'C':
...@@ -5568,30 +5575,57 @@ print_operand (FILE *file, rtx x, int code) ...@@ -5568,30 +5575,57 @@ print_operand (FILE *file, rtx x, int code)
break; break;
case CONST_INT: case CONST_INT:
if (code == 'b') ival = INTVAL (x);
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff); switch (code)
else if (code == 'c') {
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xff) ^ 0x80) - 0x80); case 0:
else if (code == 'x') break;
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff); case 'b':
else if (code == 'h') ival &= 0xff;
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000); break;
else if (code == 'i') case 'c':
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival = ((ival & 0xff) ^ 0x80) - 0x80;
s390_extract_part (x, HImode, 0)); break;
else if (code == 'j') case 'x':
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival &= 0xffff;
s390_extract_part (x, HImode, -1)); break;
else if (code == 'k') case 'h':
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival = ((ival & 0xffff) ^ 0x8000) - 0x8000;
s390_extract_part (x, SImode, 0)); break;
else if (code == 'm') case 'i':
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival = s390_extract_part (x, HImode, 0);
s390_extract_part (x, SImode, -1)); break;
else if (code == 'o') case 'j':
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffffffff); ival = s390_extract_part (x, HImode, -1);
else break;
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); 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; break;
case CONST_DOUBLE: case CONST_DOUBLE:
......
...@@ -527,6 +527,10 @@ ...@@ -527,6 +527,10 @@
;; Maximum unsigned integer that fits in MODE. ;; Maximum unsigned integer that fits in MODE.
(define_mode_attr max_uint [(HI "65535") (QI "255")]) (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. ;;- Compare instructions.
;; ;;
...@@ -3420,56 +3424,22 @@ ...@@ -3420,56 +3424,22 @@
(define_insn "*insv<mode>_zEC12_noshift" (define_insn "*insv<mode>_zEC12_noshift"
[(set (match_operand:GPR 0 "nonimmediate_operand" "=d") [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
(ior:GPR (and:GPR (match_operand:GPR 1 "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") (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
(match_operand 4 "const_int_operand" "n"))))] (match_operand:GPR 4 "const_int_operand" ""))))]
"TARGET_ZEC12 "TARGET_ZEC12 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
&& s390_contiguous_bitmask_p (INTVAL (operands[2]), "risbgn\t%0,%1,%<bfstart>2,%<bfend>2,0"
GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)
&& INTVAL (operands[2]) == ~(INTVAL (operands[4]))"
{
int start;
int size;
s390_contiguous_bitmask_p (INTVAL (operands[2]),
GET_MODE_BITSIZE (<MODE>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";
}
[(set_attr "op_type" "RIE")]) [(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<mode>_z10_noshift" (define_insn "*insv<mode>_z10_noshift"
[(set (match_operand:GPR 0 "nonimmediate_operand" "=d") [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
(ior:GPR (and:GPR (match_operand:GPR 1 "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") (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))] (clobber (reg:CC CC_REGNUM))]
"TARGET_Z10 "TARGET_Z10 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
&& s390_contiguous_bitmask_p (INTVAL (operands[2]), "risbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)
&& INTVAL (operands[2]) == ~(INTVAL (operands[4]))"
{
int start;
int size;
s390_contiguous_bitmask_p (INTVAL (operands[2]),
GET_MODE_BITSIZE (<MODE>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";
}
[(set_attr "op_type" "RIE") [(set_attr "op_type" "RIE")
(set_attr "z10prop" "z10_super_E1")]) (set_attr "z10prop" "z10_super_E1")])
...@@ -3477,25 +3447,11 @@ ...@@ -3477,25 +3447,11 @@
(define_insn "*insv<mode>_or_z10_noshift" (define_insn "*insv<mode>_or_z10_noshift"
[(set (match_operand:GPR 0 "nonimmediate_operand" "=d") [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
(ior:GPR (and:GPR (match_operand:GPR 1 "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"))) (match_operand:GPR 3 "nonimmediate_operand" "0")))
(clobber (reg:CC CC_REGNUM))] (clobber (reg:CC CC_REGNUM))]
"TARGET_Z10 "TARGET_Z10"
&& s390_contiguous_bitmask_p (INTVAL (operands[2]), "rosbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)"
{
int start;
int size;
s390_contiguous_bitmask_p (INTVAL (operands[2]),
GET_MODE_BITSIZE (<MODE>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";
}
[(set_attr "op_type" "RIE")]) [(set_attr "op_type" "RIE")])
(define_insn "*insv<mode>_mem_reg" (define_insn "*insv<mode>_mem_reg"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment