[committed] Make mips.md use seb/seh where available
Richard Sandiford
rsandifo@redhat.com
Sat Sep 4 08:03:00 GMT 2004
At the moment, mips.md provides three define_insns for sign-extension:
- one for register source operands (split after reload)
- one for memory source operands
- one for register source operands if ISA_HAS_SEB_SEH ({QI,HI}->SI only)
Unfortunately, the seb/seh version came after the non-seb/seh version
(and its define_split), so was never actually used. Fixed with the
patch below.
I was also never too happy with having separate register and memory
patterns. My understanding is that reload and post-reload passes are
more likely to do a good job if the alternatives are described by a
single define_insn. For example, a register source operand that gets
spilled to the stack can then be replaced by its stack slot (rather
than being reloaded into another register). I didn't find any examples
in gcc.c-torture or gcc.dg at -O2 for this particular patch, but I did
for the follow-on patch for zero_extend.
The patch also takes the opportunity to macroise the patterns. As a
side-effect, this gives us {QI,HI}->DI seb/seh patterns "for free",
and although they aren't used yet, they should just work once
ISA_HAS_SEB_SEH is extended to include 64-bit archs. (I don't
normally like adding patterns that aren't used yet, but in this case,
it's easier to define them than not.)
Bootstrapped & regression tested on mips-sgi-irix6.5. I compared the
before and after output of gcc.c-torture and gcc.dg for:
{-mips16,-mips64,-mips3}{-mabi=32,-mabi=eabi}
using a mipsisa64-elf configuration. There were no changes. I also did
the same for -mips32r2/-mabi=32, and as expected, there were lots of new
uses of seb and seh. Applied to mainline.
Richard
* config/mips/mips.md (SHORT): New mode macro.
(size): New mode attribute.
(extend[qh]i[sd]i2): Redefine using :GPR and :SHORT.
(*extend[qh]i[sd]i2): New define_insn_and_split, combining previous
*extend[qh]i[sd]i2 and *extend[qh]i[sd]i2_mem patterns. Use only if
!ISA_HAS_SEB_SEH.
(*extend[qh]i[sd]i2_se[bh]): New pattern, combining previous
*extend[qh]isi2_hw patterns and extending them to di.
(extendqihi2): Implement as define_insn_and_split that produces
extendqisi2 after reload.
Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.302
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.302 mips.md
*** config/mips/mips.md 3 Sep 2004 20:12:28 -0000 1.302
--- config/mips/mips.md 4 Sep 2004 07:24:42 -0000
*************** (define_mode_macro P [(SI "Pmode == SImo
*** 324,329 ****
--- 324,333 ----
;; conditional-move-type condition is needed.
(define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
+ ;; This mode macro allows the QI and HI extension patterns to be defined from
+ ;; the same template.
+ (define_mode_macro SHORT [QI HI])
+
;; This mode macro allows :ANYF to be used wherever a scalar or vector
;; floating-point mode is allowed.
(define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
*************** (define_mode_macro SCALARF [(SF "TARGET_
*** 338,343 ****
--- 342,351 ----
;; 32-bit version and "dsubu" in the 64-bit version.
(define_mode_attr d [(SI "") (DI "d")])
+ ;; This attribute gives the length suffix for a sign- or zero-extension
+ ;; instruction.
+ (define_mode_attr size [(QI "b") (HI "h")])
+
;; Mode attributes for GPR loads and stores.
(define_mode_attr load [(SI "lw") (DI "ld")])
(define_mode_attr store [(SI "sw") (DI "sd")])
*************** (define_insn_and_split "extendsidi2"
*** 2479,2672 ****
[(set_attr "type" "arith,load")
(set_attr "mode" "DI")])
! ;; These patterns originally accepted general_operands, however, slightly
! ;; better code is generated by only accepting register_operands, and then
! ;; letting combine generate the lh and lb insns.
!
! ;; These expanders originally put values in registers first. We split
! ;; all non-mem patterns after reload.
!
! (define_expand "extendhidi2"
! [(set (match_operand:DI 0 "register_operand")
! (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
! "TARGET_64BIT"
"")
! (define_insn "*extendhidi2"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
! "TARGET_64BIT"
! "#")
!
! (define_split
! [(set (match_operand:DI 0 "register_operand")
! (sign_extend:DI (match_operand:HI 1 "register_operand")))]
! "TARGET_64BIT && reload_completed"
! [(set (match_dup 0)
! (ashift:DI (match_dup 1) (const_int 48)))
! (set (match_dup 0)
! (ashiftrt:DI (match_dup 0) (const_int 48)))]
! "operands[1] = gen_lowpart (DImode, operands[1]);")
!
! (define_insn "*extendhidi2_mem"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
! "TARGET_64BIT"
! "lh\t%0,%1"
! [(set_attr "type" "load")
! (set_attr "mode" "DI")])
!
! (define_expand "extendhisi2"
! [(set (match_operand:SI 0 "register_operand")
! (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
! ""
! {
! if (ISA_HAS_SEB_SEH)
! {
! emit_insn (gen_extendhisi2_hw (operands[0],
! force_reg (HImode, operands[1])));
! DONE;
! }
! })
!
! (define_insn "*extendhisi2"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
! ""
! "#")
!
! (define_split
! [(set (match_operand:SI 0 "register_operand")
! (sign_extend:SI (match_operand:HI 1 "register_operand")))]
! "reload_completed"
! [(set (match_dup 0)
! (ashift:SI (match_dup 1) (const_int 16)))
! (set (match_dup 0)
! (ashiftrt:SI (match_dup 0) (const_int 16)))]
! "operands[1] = gen_lowpart (SImode, operands[1]);")
!
! (define_insn "extendhisi2_mem"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
! ""
! "lh\t%0,%1"
! [(set_attr "type" "load")
! (set_attr "mode" "SI")])
! (define_insn "extendhisi2_hw"
! [(set (match_operand:SI 0 "register_operand" "=r")
! (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
"ISA_HAS_SEB_SEH"
! "seh\t%0,%1"
! [(set_attr "type" "arith")
! (set_attr "mode" "SI")])
!
! (define_expand "extendqihi2"
! [(set (match_operand:HI 0 "register_operand")
! (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
! ""
! "")
!
! (define_insn "*extendqihi2"
! [(set (match_operand:HI 0 "register_operand" "=d")
! (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
! ""
! "#")
!
! (define_split
! [(set (match_operand:HI 0 "register_operand")
! (sign_extend:HI (match_operand:QI 1 "register_operand")))]
! "reload_completed"
! [(set (match_dup 0)
! (ashift:SI (match_dup 1) (const_int 24)))
! (set (match_dup 0)
! (ashiftrt:SI (match_dup 0) (const_int 24)))]
! "operands[0] = gen_lowpart (SImode, operands[0]);
! operands[1] = gen_lowpart (SImode, operands[1]);")
!
! (define_insn "*extendqihi2_internal_mem"
! [(set (match_operand:HI 0 "register_operand" "=d")
! (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
! ""
! "lb\t%0,%1"
! [(set_attr "type" "load")
! (set_attr "mode" "SI")])
!
!
! (define_expand "extendqisi2"
! [(set (match_operand:SI 0 "register_operand")
! (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
! ""
! {
! if (ISA_HAS_SEB_SEH)
! {
! emit_insn (gen_extendqisi2_hw (operands[0],
! force_reg (QImode, operands[1])));
! DONE;
! }
! })
! (define_insn "*extendqisi2"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
""
! "#")
!
! (define_split
! [(set (match_operand:SI 0 "register_operand")
! (sign_extend:SI (match_operand:QI 1 "register_operand")))]
"reload_completed"
! [(set (match_dup 0)
! (ashift:SI (match_dup 1) (const_int 24)))
! (set (match_dup 0)
! (ashiftrt:SI (match_dup 0) (const_int 24)))]
! "operands[1] = gen_lowpart (SImode, operands[1]);")
!
! (define_insn "*extendqisi2_mem"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
! ""
! "lb\t%0,%1"
! [(set_attr "type" "load")
! (set_attr "mode" "SI")])
!
! (define_insn "extendqisi2_hw"
! [(set (match_operand:SI 0 "register_operand" "=r")
! (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
! "ISA_HAS_SEB_SEH"
! "seb\t%0,%1"
! [(set_attr "type" "arith")
! (set_attr "mode" "SI")])
!
! (define_expand "extendqidi2"
! [(set (match_operand:DI 0 "register_operand")
! (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
! "TARGET_64BIT"
! "")
!
! (define_insn "*extendqidi2"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
! "TARGET_64BIT"
! "#")
!
! (define_split
! [(set (match_operand:DI 0 "register_operand")
! (sign_extend:DI (match_operand:QI 1 "register_operand")))]
! "TARGET_64BIT && reload_completed"
! [(set (match_dup 0)
! (ashift:DI (match_dup 1) (const_int 56)))
! (set (match_dup 0)
! (ashiftrt:DI (match_dup 0) (const_int 56)))]
! "operands[1] = gen_lowpart (DImode, operands[1]);")
!
! (define_insn "*extendqidi2_mem"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
! "TARGET_64BIT"
! "lb\t%0,%1"
! [(set_attr "type" "load")
! (set_attr "mode" "DI")])
(define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
--- 2487,2541 ----
[(set_attr "type" "arith,load")
(set_attr "mode" "DI")])
! (define_expand "extend<SHORT:mode><GPR:mode>2"
! [(set (match_operand:GPR 0 "register_operand")
! (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
"")
! (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
! [(set (match_operand:GPR 0 "register_operand" "=d,d")
! (sign_extend:GPR
! (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
! "!ISA_HAS_SEB_SEH"
! "@
! #
! l<SHORT:size>\t%0,%1"
! "&& reload_completed && REG_P (operands[1])"
! [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
! (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
! {
! operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
! operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
! - GET_MODE_BITSIZE (<SHORT:MODE>mode));
! }
! [(set_attr "type" "arith,load")
! (set_attr "mode" "<GPR:MODE>")
! (set_attr "length" "8,*")])
! (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
! [(set (match_operand:GPR 0 "register_operand" "=d,d")
! (sign_extend:GPR
! (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
"ISA_HAS_SEB_SEH"
! "@
! se<SHORT:size>\t%0,%1
! l<SHORT:size>\t%0,%1"
! [(set_attr "type" "arith,load")
! (set_attr "mode" "<GPR:MODE>")])
! ;; This pattern generates the same code as extendqisi2; split it into
! ;; that form after reload.
! (define_insn_and_split "extendqihi2"
! [(set (match_operand:HI 0 "register_operand" "=d,d")
! (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
""
! "#"
"reload_completed"
! [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
! { operands[0] = gen_lowpart (SImode, operands[0]); }
! [(set_attr "type" "arith,load")
! (set_attr "mode" "SI")
! (set_attr "length" "8,*")])
(define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
More information about the Gcc-patches
mailing list