This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
S/390: zero_extend improvements
- From: "Ulrich Weigand" <Ulrich dot Weigand at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 19 Sep 2002 19:10:49 +0200
- Subject: S/390: zero_extend improvements
- Sensitivity:
Hello,
this patch improves the code generated for zero_extends on 31-bit somewhat;
instead of IC followed by AND we now use IC into a register previously
initialized to zero. While this doesn't reduce the instruction count,
it allows for better scheduling in a number of cases.
This exposed a bug in a helper routine used for scheduling; it didn't
notice that modifying a SUBREG or STRICT_LOW_PART of a register still
counts as dependency blocking future use of the register for address
generation. This is also fixed.
Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.
ChangeLog:
* config/s390/s390.c (addr_generation_dependency_p): Handle SUBREG
and STRICT_LOW_PART within SET_DEST.
* config/s390/s390.md ("*extractqi", "*extracthi"): New insns with
splitters, replacing pre-reload splitters.
("*zero_extendhisi2_31", "*zero_extendqisi2_31",
"*zero_extendqihi2_31"): New insns.
("*zero_extendqihi2_64"): Do not clobber CC.
Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.54
diff -c -p -r1.54 s390.c
*** gcc/config/s390/s390.c 18 Sep 2002 18:57:17 -0000 1.54
--- gcc/config/s390/s390.c 19 Sep 2002 16:55:59 -0000
*************** addr_generation_dependency_p (dep_rtx, i
*** 2812,2818 ****
if (GET_CODE (dep_rtx) == SET)
{
target = SET_DEST (dep_rtx);
!
if (GET_CODE (target) == REG)
{
int regno = REGNO (target);
--- 2812,2822 ----
if (GET_CODE (dep_rtx) == SET)
{
target = SET_DEST (dep_rtx);
! if (GET_CODE (target) == STRICT_LOW_PART)
! target = XEXP (target, 0);
! while (GET_CODE (target) == SUBREG)
! target = SUBREG_REG (target);
!
if (GET_CODE (target) == REG)
{
int regno = REGNO (target);
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.32
diff -c -p -r1.32 s390.md
*** gcc/config/s390/s390.md 16 Sep 2002 14:13:12 -0000 1.32
--- gcc/config/s390/s390.md 19 Sep 2002 16:56:07 -0000
***************
*** 1931,1943 ****
[(set_attr "op_type" "RS")
(set_attr "atype" "mem")])
! (define_split
! [(set (match_operand:SI 0 "register_operand" "")
! (zero_extract:SI (match_operand:QI 1 "s_operand" "")
! (match_operand 2 "const_int_operand" "")
! (const_int 0)))]
! "!TARGET_64BIT && !reload_completed
&& INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 8"
[(parallel
[(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
(clobber (reg:CC 33))])
--- 1931,1946 ----
[(set_attr "op_type" "RS")
(set_attr "atype" "mem")])
! (define_insn_and_split "*extractqi"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (zero_extract:SI (match_operand:QI 1 "s_operand" "Q")
! (match_operand 2 "const_int_operand" "n")
! (const_int 0)))
! (clobber (reg:CC 33))]
! "!TARGET_64BIT
&& INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 8"
+ "#"
+ "&& reload_completed"
[(parallel
[(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
(clobber (reg:CC 33))])
***************
*** 1946,1960 ****
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], QImode, 0);
! }")
! (define_split
! [(set (match_operand:SI 0 "register_operand" "")
! (zero_extract:SI (match_operand:QI 1 "s_operand" "")
! (match_operand 2 "const_int_operand" "")
! (const_int 0)))]
! "!TARGET_64BIT && !reload_completed
&& INTVAL (operands[2]) >= 8 && INTVAL (operands[2]) < 16"
[(parallel
[(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
(clobber (reg:CC 33))])
--- 1949,1968 ----
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], QImode, 0);
! }"
! [(set_attr "type" "o2")
! (set_attr "atype" "mem")])
! (define_insn_and_split "*extracthi"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (zero_extract:SI (match_operand:QI 1 "s_operand" "Q")
! (match_operand 2 "const_int_operand" "n")
! (const_int 0)))
! (clobber (reg:CC 33))]
! "!TARGET_64BIT
&& INTVAL (operands[2]) >= 8 && INTVAL (operands[2]) < 16"
+ "#"
+ "&& reload_completed"
[(parallel
[(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
(clobber (reg:CC 33))])
***************
*** 1963,1969 ****
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], HImode, 0);
! }")
;
; extendsidi2 instruction pattern(s).
--- 1971,1979 ----
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], HImode, 0);
! }"
! [(set_attr "type" "o2")
! (set_attr "atype" "mem")])
;
; extendsidi2 instruction pattern(s).
***************
*** 2252,2257 ****
--- 2262,2282 ----
"llgh\\t%0,%1"
[(set_attr "op_type" "RXE")
(set_attr "atype" "mem")])
+
+ (define_insn_and_split "*zero_extendhisi2_31"
+ [(set (match_operand:SI 0 "register_operand" "=&d")
+ (zero_extend:SI (match_operand:HI 1 "memory_operand" "Q")))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (const_int 0))
+ (parallel
+ [(set (strict_low_part (match_dup 2)) (match_dup 1))
+ (clobber (reg:CC 33))])]
+ "operands[2] = gen_lowpart (HImode, operands[0]);"
+ [(set_attr "type" "o2")
+ (set_attr "atype" "mem")])
;
; zero_extendqisi2 instruction pattern(s).
***************
*** 2276,2281 ****
--- 2301,2318 ----
"llgc\\t%0,%1"
[(set_attr "op_type" "RXE")
(set_attr "atype" "mem")])
+
+ (define_insn_and_split "*zero_extendqisi2_31"
+ [(set (match_operand:SI 0 "register_operand" "=&d")
+ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "!TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (const_int 0))
+ (set (strict_low_part (match_dup 2)) (match_dup 1))]
+ "operands[2] = gen_lowpart (QImode, operands[0]);"
+ [(set_attr "type" "o2")
+ (set_attr "atype" "mem")])
;
; zero_extendqihi2 instruction pattern(s).
***************
*** 2295,2306 ****
(define_insn "*zero_extendqihi2_64"
[(set (match_operand:HI 0 "register_operand" "=d")
! (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))
! (clobber (reg:CC 33))]
"TARGET_64BIT"
"llgc\\t%0,%1"
[(set_attr "op_type" "RXE")
(set_attr "atype" "mem")])
;
; fixuns_truncdfdi2 and fix_truncdfsi2 instruction pattern(s).
--- 2332,2355 ----
(define_insn "*zero_extendqihi2_64"
[(set (match_operand:HI 0 "register_operand" "=d")
! (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_64BIT"
"llgc\\t%0,%1"
[(set_attr "op_type" "RXE")
(set_attr "atype" "mem")])
+
+ (define_insn_and_split "*zero_extendqihi2_31"
+ [(set (match_operand:HI 0 "register_operand" "=&d")
+ (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
+ "!TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (const_int 0))
+ (set (strict_low_part (match_dup 2)) (match_dup 1))]
+ "operands[2] = gen_lowpart (QImode, operands[0]);"
+ [(set_attr "type" "o2")
+ (set_attr "atype" "mem")])
+
;
; fixuns_truncdfdi2 and fix_truncdfsi2 instruction pattern(s).
Mit freundlichen Gruessen / Best Regards
Ulrich Weigand
--
Dr. Ulrich Weigand
Linux for S/390 Design & Development
IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
Phone: +49-7031/16-3727 --- Email: Ulrich.Weigand@de.ibm.com