diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2006-09-07 08:19:32 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2006-09-07 08:19:32 +0000 |
commit | 62bf45a5a0f1b981fa078386e6ee7caf5a7f612b (patch) | |
tree | 70f7311db08529d0e47267026c9db75ed5f3eca7 /gcc | |
parent | e8288489d9bf76261674e5b2cac70d954bfd83ea (diff) | |
download | gcc-62bf45a5a0f1b981fa078386e6ee7caf5a7f612b.zip gcc-62bf45a5a0f1b981fa078386e6ee7caf5a7f612b.tar.gz gcc-62bf45a5a0f1b981fa078386e6ee7caf5a7f612b.tar.bz2 |
re PR target/27117 (SH backend cheats to reload -- disables indexed addressing but uses it internally)
2006-09-07 Paolo Bonzini <bonzini@gnu.org>
PR target/27117
* config/sh/sh.md (divsi_inv_qitable, divsi_inv_hitable): New patterns.
(divsi_inv_m1): Use them.
(UNSPEC_DIV_INV_TABLE): New constant.
From-SVN: r116746
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 35 |
2 files changed, 38 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 580bf89..f3d086b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-09-07 Paolo Bonzini <bonzini@gnu.org> + + PR target/27117 + * config/sh/sh.md (divsi_inv_qitable, divsi_inv_hitable): New patterns. + (divsi_inv_m1): Use them. + (UNSPEC_DIV_INV_TABLE): New constant. + 2006-09-06 James E Wilson <wilson@specifix.com> PR rtl-opt/27883 diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 41e0644..97aa698 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -148,6 +148,7 @@ (UNSPEC_DIV_INV_M2 32) (UNSPEC_DIV_INV_M3 33) (UNSPEC_DIV_INV20 34) + (UNSPEC_DIV_INV_TABLE 37) (UNSPEC_ASHIFTRT 35) (UNSPEC_THUNK 36) (UNSPEC_SP_SET 40) @@ -2244,6 +2245,34 @@ DONE; }") +;; operands: scratch, tab_base, tab_ix +;; These are unspecs because we could generate an indexed addressing mode +;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would +;; confuse reload. See PR27117. + +(define_insn "divsi_inv_qitable" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "register_operand" "r")] + UNSPEC_DIV_INV_TABLE)))] + "TARGET_SHMEDIA" + "@ + ldx.ub %1, %2, %0" + [(set_attr "type" "load_media") + (set_attr "highpart" "user")]) + +;; operands: scratch, tab_base, tab_ix +(define_insn "divsi_inv_hitable" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "register_operand" "r")] + UNSPEC_DIV_INV_TABLE)))] + "TARGET_SHMEDIA" + "@ + ldx.w %1, %2, %0" + [(set_attr "type" "load_media") + (set_attr "highpart" "user")]) + ;; operands: inv0, tab_base, tab_ix, norm32 ;; scratch equiv in sdivsi3_2: r19, r21 (define_expand "divsi_inv_m0" @@ -2278,12 +2307,10 @@ norm32: r25 rtx scratch1 = operands[5]; rtx mem; - mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix)); - emit_insn (gen_zero_extendqidi2 (scratch0, mem)); + emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix)); emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1))); emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si)); - mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1)); - emit_insn (gen_extendhidi2 (scratch1, mem)); + emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1)); emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24))); emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0)); DONE; |