re PR target/28623 (ICE in extract_insn, at recog.c:2077 (nrecognizable insn) [alpha])

PR target/28623
        * config/alpha/alpha.c (get_unaligned_address): Remove extra_offset
        argument; update all callers.
        (get_unaligned_offset): New.
        * config/alpha/alpha.md (extendqidi2, extendhidi2): Don't use
        get_unaligned_address, just pass on the address directly.
        (unaligned_extendqidi): Use gen_lowpart instead of open-coding
        the subreg in the helper patterns.
        (unaligned_extendqidi_le): Use get_unaligned_offset.
        (unaligned_extendqidi_be, unaligned_extendhidi_le): Likewise.
        (unaligned_extendhidi_be): Likewise.
        (unaligned_extendhidi): Tidy.
        * config/alpha/alpha-protos.h: Update.

From-SVN: r124002
This commit is contained in:
Richard Henderson 2007-04-20 12:35:55 -07:00 committed by Richard Henderson
parent f326fd7a03
commit 60e9352519
4 changed files with 70 additions and 56 deletions

View File

@ -1,3 +1,19 @@
2007-04-20 Richard Henderson <rth@redhat.com>
PR target/28623
* config/alpha/alpha.c (get_unaligned_address): Remove extra_offset
argument; update all callers.
(get_unaligned_offset): New.
* config/alpha/alpha.md (extendqidi2, extendhidi2): Don't use
get_unaligned_address, just pass on the address directly.
(unaligned_extendqidi): Use gen_lowpart instead of open-coding
the subreg in the helper patterns.
(unaligned_extendqidi_le): Use get_unaligned_offset.
(unaligned_extendqidi_be, unaligned_extendhidi_le): Likewise.
(unaligned_extendhidi_be): Likewise.
(unaligned_extendhidi): Tidy.
* config/alpha/alpha-protos.h: Update.
2007-04-20 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.h (CPP_SPEC, CPP_SUBTARGET_SPEC): Remove.

View File

@ -47,7 +47,8 @@ extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
extern rtx split_small_symbolic_operand (rtx);
extern void get_aligned_mem (rtx, rtx *, rtx *);
extern rtx get_unaligned_address (rtx, int);
extern rtx get_unaligned_address (rtx);
extern rtx get_unaligned_offset (rtx, HOST_WIDE_INT);
extern enum reg_class alpha_preferred_reload_class (rtx, enum reg_class);
extern enum reg_class alpha_secondary_reload_class (enum reg_class,
enum machine_mode, rtx,

View File

@ -1461,7 +1461,7 @@ get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
Add EXTRA_OFFSET to the address we return. */
rtx
get_unaligned_address (rtx ref, int extra_offset)
get_unaligned_address (rtx ref)
{
rtx base;
HOST_WIDE_INT offset = 0;
@ -1481,7 +1481,23 @@ get_unaligned_address (rtx ref, int extra_offset)
if (GET_CODE (base) == PLUS)
offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
return plus_constant (base, offset + extra_offset);
return plus_constant (base, offset);
}
/* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
X is always returned in a register. */
rtx
get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs)
{
if (GET_CODE (addr) == PLUS)
{
ofs += INTVAL (XEXP (addr, 1));
addr = XEXP (addr, 0);
}
return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
}
/* On the Alpha, all (non-symbolic) constants except zero go into
@ -2230,7 +2246,7 @@ alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
seq = ((mode == QImode
? gen_unaligned_loadqi
: gen_unaligned_loadhi)
(subtarget, get_unaligned_address (operands[1], 0),
(subtarget, get_unaligned_address (operands[1]),
temp1, temp2));
alpha_set_memflags (seq, operands[1]);
emit_insn (seq);
@ -2269,7 +2285,7 @@ alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
rtx seq = ((mode == QImode
? gen_unaligned_storeqi
: gen_unaligned_storehi)
(get_unaligned_address (operands[0], 0),
(get_unaligned_address (operands[0]),
operands[1], temp1, temp2, temp3));
alpha_set_memflags (seq, operands[0]);

View File

@ -1664,10 +1664,7 @@
if (unaligned_memory_operand (operands[1], QImode))
{
rtx seq
= gen_unaligned_extendqidi (operands[0],
get_unaligned_address (operands[1], 1));
rtx seq = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
alpha_set_memflags (seq, operands[1]);
emit_insn (seq);
DONE;
@ -1727,9 +1724,7 @@
if (unaligned_memory_operand (operands[1], HImode))
{
rtx seq
= gen_unaligned_extendhidi (operands[0],
get_unaligned_address (operands[1], 2));
rtx seq = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
alpha_set_memflags (seq, operands[1]);
emit_insn (seq);
@ -1744,12 +1739,13 @@
;; as a pattern saves one instruction. The code is similar to that for
;; the unaligned loads (see below).
;;
;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
;; Operand 1 is the address, operand 0 is the result.
(define_expand "unaligned_extendqidi"
[(use (match_operand:QI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))]
""
{
operands[0] = gen_lowpart (DImode, operands[0]);
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
else
@ -1758,48 +1754,40 @@
})
(define_expand "unaligned_extendqidi_le"
[(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3)
(mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
(const_int -8))))
[(set (match_dup 3)
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
(ashift:DI
(and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_dup 4) (const_int 56)))]
"! WORDS_BIG_ENDIAN"
{
operands[2] = gen_reg_rtx (DImode);
operands[2] = get_unaligned_offset (operands[1], 1);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
})
(define_expand "unaligned_extendqidi_be"
[(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3) (plus:DI (match_dup 2) (const_int -1)))
[(set (match_dup 3)
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
(set (match_dup 4)
(mem:DI (and:DI (match_dup 3)
(const_int -8))))
(set (match_dup 5) (plus:DI (match_dup 2) (const_int -2)))
(set (match_dup 6)
(ashift:DI (match_dup 4)
(ashift:DI (match_dup 3)
(ashift:DI
(and:DI
(plus:DI (match_dup 5) (const_int 1))
(plus:DI (match_dup 2) (const_int 1))
(const_int 7))
(const_int 3))))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(ashiftrt:DI (match_dup 6) (const_int 56)))]
(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_dup 4) (const_int 56)))]
"WORDS_BIG_ENDIAN"
{
operands[2] = gen_reg_rtx (DImode);
operands[2] = get_unaligned_offset (operands[1], -1);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
operands[5] = gen_reg_rtx (DImode);
operands[6] = gen_reg_rtx (DImode);
})
(define_expand "unaligned_extendhidi"
@ -1808,17 +1796,16 @@
""
{
operands[0] = gen_lowpart (DImode, operands[0]);
emit_insn ((WORDS_BIG_ENDIAN
? gen_unaligned_extendhidi_be
: gen_unaligned_extendhidi_le) (operands[0], operands[1]));
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1]));
else
emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1]));
DONE;
})
(define_expand "unaligned_extendhidi_le"
[(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3)
(mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
(const_int -8))))
[(set (match_dup 3)
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
@ -1829,34 +1816,28 @@
(ashiftrt:DI (match_dup 4) (const_int 48)))]
"! WORDS_BIG_ENDIAN"
{
operands[2] = gen_reg_rtx (DImode);
operands[2] = get_unaligned_offset (operands[1], 2);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
})
(define_expand "unaligned_extendhidi_be"
[(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3) (plus:DI (match_dup 2) (const_int -2)))
[(set (match_dup 3)
(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
(set (match_dup 4)
(mem:DI (and:DI (match_dup 3)
(const_int -8))))
(set (match_dup 5) (plus:DI (match_dup 2) (const_int -3)))
(set (match_dup 6)
(ashift:DI (match_dup 4)
(ashift:DI (match_dup 3)
(ashift:DI
(and:DI
(plus:DI (match_dup 5) (const_int 1))
(plus:DI (match_dup 2) (const_int 1))
(const_int 7))
(const_int 3))))
(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_dup 6) (const_int 48)))]
(ashiftrt:DI (match_dup 4) (const_int 48)))]
"WORDS_BIG_ENDIAN"
{
operands[2] = gen_reg_rtx (DImode);
operands[2] = get_unaligned_offset (operands[1], -1);
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
operands[5] = gen_reg_rtx (DImode);
operands[6] = gen_reg_rtx (DImode);
})
(define_insn "*extxl_const"
@ -6133,7 +6114,7 @@
else
scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
addr = get_unaligned_address (operands[1], 0);
addr = get_unaligned_address (operands[1]);
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
seq = gen_unaligned_loadqi (operands[0], addr, scratch, operands[0]);
alpha_set_memflags (seq, operands[1]);
@ -6167,7 +6148,7 @@
else
scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
addr = get_unaligned_address (operands[1], 0);
addr = get_unaligned_address (operands[1]);
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
seq = gen_unaligned_loadhi (operands[0], addr, scratch, operands[0]);
alpha_set_memflags (seq, operands[1]);
@ -6191,7 +6172,7 @@
}
else
{
rtx addr = get_unaligned_address (operands[0], 0);
rtx addr = get_unaligned_address (operands[0]);
rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
rtx scratch3 = scratch1;
@ -6223,7 +6204,7 @@
}
else
{
rtx addr = get_unaligned_address (operands[0], 0);
rtx addr = get_unaligned_address (operands[0]);
rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
rtx scratch3 = scratch1;