re PR target/58314 (SH4 error: 'asm' operand requires impossible reload)
2013-09-13 Christian Bruel <christian.bruel@st.com> PR target/58314 * config/sh/sh.md (mov<mode>_reg_reg): Allow memory reloads. From-SVN: r202557
This commit is contained in:
parent
740f2bf37a
commit
c0ecf7f1cb
@ -1,3 +1,8 @@
|
||||
2013-09-13 Christian Bruel <christian.bruel@st.com>
|
||||
|
||||
PR target/58314
|
||||
* config/sh/sh.md (mov<mode>_reg_reg): Allow memory reloads.
|
||||
|
||||
2013-09-13 Kai Tietz <ktietz@redhat.com>
|
||||
|
||||
* config.gcc: Separate cases for mingw and cygwin targets,
|
||||
|
@ -6878,10 +6878,11 @@ label:
|
||||
;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
|
||||
;; selected to copy QImode regs. If one of them happens to be allocated
|
||||
;; on the stack, reload will stick to movqi insn and generate wrong
|
||||
;; displacement addressing because of the generic m alternatives.
|
||||
;; With the movqi_reg_reg being specified before movqi it will be initially
|
||||
;; picked to load/store regs. If the regs regs are on the stack reload will
|
||||
;; try other insns and not stick to movqi_reg_reg.
|
||||
;; displacement addressing because of the generic m alternatives.
|
||||
;; With the movqi_reg_reg being specified before movqi it will be initially
|
||||
;; picked to load/store regs. If the regs regs are on the stack reload
|
||||
;; try other insns and not stick to movqi_reg_reg, unless there were spilled
|
||||
;; pseudos in which case 'm' constraints pertain.
|
||||
;; The same applies to the movhi variants.
|
||||
;;
|
||||
;; Notice, that T bit is not allowed as a mov src operand here. This is to
|
||||
@ -6893,11 +6894,14 @@ label:
|
||||
;; reloading MAC subregs otherwise. For that probably special patterns
|
||||
;; would be required.
|
||||
(define_insn "*mov<mode>_reg_reg"
|
||||
[(set (match_operand:QIHI 0 "arith_reg_dest" "=r")
|
||||
(match_operand:QIHI 1 "register_operand" "r"))]
|
||||
[(set (match_operand:QIHI 0 "arith_reg_dest" "=r,m,*z")
|
||||
(match_operand:QIHI 1 "register_operand" "r,*z,m"))]
|
||||
"TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)"
|
||||
"mov %1,%0"
|
||||
[(set_attr "type" "move")])
|
||||
"@
|
||||
mov %1,%0
|
||||
mov.<bw> %1,%0
|
||||
mov.<bw> %1,%0"
|
||||
[(set_attr "type" "move,store,load")])
|
||||
|
||||
;; FIXME: The non-SH2A and SH2A variants should be combined by adding
|
||||
;; "enabled" attribute as it is done in other targets.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2013-09-13 Christian Bruel <christian.bruel@st.com>
|
||||
|
||||
PR target/58314
|
||||
* gcc.target/sh/torture/pr58314.c: New test.
|
||||
|
||||
2013-09-12 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* g++.dg/torture/pr58380.C: Suppress warnings with "-w".
|
||||
|
102
gcc/testsuite/gcc.target/sh/torture/pr58314.c
Normal file
102
gcc/testsuite/gcc.target/sh/torture/pr58314.c
Normal file
@ -0,0 +1,102 @@
|
||||
/* { dg-do compile { target "sh*-*-*" } } */
|
||||
/* { dg-options "-Os" } */
|
||||
|
||||
typedef unsigned short __u16;
|
||||
typedef unsigned int __u32;
|
||||
|
||||
typedef signed short s16;
|
||||
|
||||
|
||||
static inline __attribute__((always_inline)) __attribute__((__const__)) __u16 __arch_swab16(__u16 x)
|
||||
{
|
||||
__asm__(
|
||||
"swap.b %1, %0"
|
||||
: "=r" (x)
|
||||
: "r" (x));
|
||||
return x;
|
||||
}
|
||||
|
||||
void u16_add_cpu(__u16 *var)
|
||||
{
|
||||
*var = __arch_swab16(*var);
|
||||
}
|
||||
|
||||
typedef struct xfs_mount {
|
||||
int m_attr_magicpct;
|
||||
} xfs_mount_t;
|
||||
|
||||
typedef struct xfs_da_args {
|
||||
struct xfs_mount *t_mountp;
|
||||
int index;
|
||||
} xfs_da_args_t;
|
||||
|
||||
typedef struct xfs_dabuf {
|
||||
void *data;
|
||||
} xfs_dabuf_t;
|
||||
|
||||
typedef struct xfs_attr_leaf_map {
|
||||
__u16 base;
|
||||
__u16 size;
|
||||
} xfs_attr_leaf_map_t;
|
||||
typedef struct xfs_attr_leaf_hdr {
|
||||
__u16 count;
|
||||
xfs_attr_leaf_map_t freemap[3];
|
||||
} xfs_attr_leaf_hdr_t;
|
||||
|
||||
typedef struct xfs_attr_leaf_entry {
|
||||
__u16 nameidx;
|
||||
} xfs_attr_leaf_entry_t;
|
||||
|
||||
typedef struct xfs_attr_leafblock {
|
||||
xfs_attr_leaf_hdr_t hdr;
|
||||
xfs_attr_leaf_entry_t entries[1];
|
||||
} xfs_attr_leafblock_t;
|
||||
|
||||
int
|
||||
xfs_attr_leaf_remove(xfs_attr_leafblock_t *leaf, xfs_da_args_t *args)
|
||||
{
|
||||
xfs_attr_leaf_hdr_t *hdr;
|
||||
xfs_attr_leaf_map_t *map;
|
||||
xfs_attr_leaf_entry_t *entry;
|
||||
int before, after, smallest, entsize;
|
||||
int tablesize, tmp, i;
|
||||
xfs_mount_t *mp;
|
||||
hdr = &leaf->hdr;
|
||||
mp = args->t_mountp;
|
||||
|
||||
entry = &leaf->entries[args->index];
|
||||
|
||||
tablesize = __arch_swab16(hdr->count);
|
||||
|
||||
map = &hdr->freemap[0];
|
||||
tmp = map->size;
|
||||
before = after = -1;
|
||||
smallest = 3 - 1;
|
||||
entsize = xfs_attr_leaf_entsize(leaf, args->index);
|
||||
|
||||
for (i = 0; i < 2; map++, i++) {
|
||||
|
||||
if (map->base == tablesize)
|
||||
u16_add_cpu(&map->base);
|
||||
|
||||
if (__arch_swab16(map->base) + __arch_swab16(map->size) == __arch_swab16(entry->nameidx))
|
||||
before = i;
|
||||
else if (map->base == entsize)
|
||||
after = i;
|
||||
else if (__arch_swab16(map->size) < tmp)
|
||||
smallest = i;
|
||||
}
|
||||
|
||||
if (before >= 0)
|
||||
{
|
||||
map = &hdr->freemap[after];
|
||||
map->base = entry->nameidx;
|
||||
|
||||
}
|
||||
|
||||
map = &hdr->freemap[smallest];
|
||||
|
||||
map->base = __arch_swab16(entry->nameidx);
|
||||
|
||||
return(tmp < mp->m_attr_magicpct);
|
||||
}
|
Loading…
Reference in New Issue
Block a user