c-decl.c (init_decl_processing): Provide proper fallback symbol for __builtin_memset.
* c-decl.c (init_decl_processing): Provide proper fallback symbol for __builtin_memset. * expr.c (expand_builtin) [MEMSET]: Arg 3 type code is INTEGER_TYPE not INTEGER_CST. Assert arg 3 is a constant. * alpha.c (mode_width_operand): Accept 64-bit modes. (mode_mask_operand): Likewise. (print_operand): Likewise for 'M' and 'U' codes. (alpha_expand_unaligned_load): New function. (alpha_expand_unaligned_store): Likewise. (alpha_expand_unaligned_load_words): Likewise. (alpha_expand_unaligned_store_words): Likewise. (alpha_expand_block_move): Likewise. (alpha_expand_block_clear): Likewise. * alpha.h (MOVE_RATIO): New define. * alpha.md (extxl, ext*h, ins*l, mskxl): Name them. (insql, insxh, mskxh, extv, extzv, insv, movstrqi, clrstrqi): New. * alpha.h (ASM_OUTPUT_LOOP_ALIGN, ASM_OUTPUT_ALIGN_CODE): Set to 3. (CONSTANT_ALIGNMENT, DATA_ALIGNMENT): Disable. From-SVN: r17278
This commit is contained in:
parent
8fbf199e91
commit
6c174fc0e6
|
@ -1,3 +1,26 @@
|
|||
Fri Jan 2 04:34:14 1998 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* c-decl.c (init_decl_processing): Provide proper fallback symbol
|
||||
for __builtin_memset.
|
||||
* expr.c (expand_builtin) [MEMSET]: Arg 3 type code is INTEGER_TYPE
|
||||
not INTEGER_CST. Assert arg 3 is a constant.
|
||||
|
||||
* alpha.c (mode_width_operand): Accept 64-bit modes.
|
||||
(mode_mask_operand): Likewise.
|
||||
(print_operand): Likewise for 'M' and 'U' codes.
|
||||
(alpha_expand_unaligned_load): New function.
|
||||
(alpha_expand_unaligned_store): Likewise.
|
||||
(alpha_expand_unaligned_load_words): Likewise.
|
||||
(alpha_expand_unaligned_store_words): Likewise.
|
||||
(alpha_expand_block_move): Likewise.
|
||||
(alpha_expand_block_clear): Likewise.
|
||||
* alpha.h (MOVE_RATIO): New define.
|
||||
* alpha.md (extxl, ext*h, ins*l, mskxl): Name them.
|
||||
(insql, insxh, mskxh, extv, extzv, insv, movstrqi, clrstrqi): New.
|
||||
|
||||
* alpha.h (ASM_OUTPUT_LOOP_ALIGN, ASM_OUTPUT_ALIGN_CODE): Set to 3.
|
||||
(CONSTANT_ALIGNMENT, DATA_ALIGNMENT): Disable.
|
||||
|
||||
Thu Jan 1 15:40:15 1998 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* configure.in: Put parenthesis around TARGET_CPU_DEFAULT's value.
|
||||
|
|
|
@ -3353,7 +3353,7 @@ init_decl_processing ()
|
|||
builtin_function ("__builtin_memcmp", int_ftype_cptr_cptr_sizet,
|
||||
BUILT_IN_MEMCMP, "memcmp");
|
||||
builtin_function ("__builtin_memset", memset_ftype,
|
||||
BUILT_IN_MEMSET, NULL_PTR);
|
||||
BUILT_IN_MEMSET, "memset");
|
||||
builtin_function ("__builtin_strcmp", int_ftype_string_string,
|
||||
BUILT_IN_STRCMP, "strcmp");
|
||||
builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr,
|
||||
|
@ -3450,8 +3450,6 @@ init_decl_processing ()
|
|||
BUILT_IN_FMOD, NULL_PTR);
|
||||
builtin_function ("__builtin_frem", double_ftype_double_double,
|
||||
BUILT_IN_FREM, NULL_PTR);
|
||||
builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int,
|
||||
BUILT_IN_MEMSET, NULL_PTR);
|
||||
builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP,
|
||||
NULL_PTR);
|
||||
builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN,
|
||||
|
|
|
@ -450,7 +450,8 @@ mode_width_operand (op, mode)
|
|||
enum machine_mode mode;
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
|
||||
&& (INTVAL (op) == 8 || INTVAL (op) == 16
|
||||
|| INTVAL (op) == 32 || INTVAL (op) == 64));
|
||||
}
|
||||
|
||||
/* Return 1 if OP is a constant that is the width of an integral machine mode
|
||||
|
@ -463,7 +464,12 @@ mode_mask_operand (op, mode)
|
|||
{
|
||||
#if HOST_BITS_PER_WIDE_INT == 32
|
||||
if (GET_CODE (op) == CONST_DOUBLE)
|
||||
return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
|
||||
return (CONST_DOUBLE_LOW (op) == -1
|
||||
&& (CONST_DOUBLE_HIGH (op) == -1
|
||||
|| CONST_DOUBLE_HIGH (op) == 0));
|
||||
#else
|
||||
if (GET_CODE (op) == CONST_DOUBLE)
|
||||
return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
|
||||
#endif
|
||||
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
|
@ -471,6 +477,7 @@ mode_mask_operand (op, mode)
|
|||
|| INTVAL (op) == 0xffff
|
||||
#if HOST_BITS_PER_WIDE_INT == 64
|
||||
|| INTVAL (op) == 0xffffffff
|
||||
|| INTVAL (op) == 0xffffffffffffffff
|
||||
#endif
|
||||
));
|
||||
}
|
||||
|
@ -1262,6 +1269,587 @@ alpha_emit_conditional_move (cmp, mode)
|
|||
emit_move_insn (tem, gen_rtx (code, cmp_op_mode, op0, op1));
|
||||
return gen_rtx (cmov_code, VOIDmode, tem, CONST0_RTX (cmp_op_mode));
|
||||
}
|
||||
|
||||
/* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
|
||||
unaligned data:
|
||||
|
||||
unsigned: signed:
|
||||
word: ldq_u r1,X(r11) ldq_u r1,X(r11)
|
||||
ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
|
||||
lda r3,X(r11) lda r3,X+2(r11)
|
||||
extwl r1,r3,r1 extql r1,r3,r1
|
||||
extwh r2,r3,r2 extqh r2,r3,r2
|
||||
or r1.r2.r1 or r1,r2,r1
|
||||
sra r1,48,r1
|
||||
|
||||
long: ldq_u r1,X(r11) ldq_u r1,X(r11)
|
||||
ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
|
||||
lda r3,X(r11) lda r3,X(r11)
|
||||
extll r1,r3,r1 extll r1,r3,r1
|
||||
extlh r2,r3,r2 extlh r2,r3,r2
|
||||
or r1.r2.r1 addl r1,r2,r1
|
||||
|
||||
quad: ldq_u r1,X(r11)
|
||||
ldq_u r2,X+7(r11)
|
||||
lda r3,X(r11)
|
||||
extql r1,r3,r1
|
||||
extqh r2,r3,r2
|
||||
or r1.r2.r1
|
||||
*/
|
||||
|
||||
void
|
||||
alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
|
||||
rtx tgt, mem;
|
||||
HOST_WIDE_INT size, ofs;
|
||||
int sign;
|
||||
{
|
||||
rtx meml, memh, addr, extl, exth;
|
||||
|
||||
meml = gen_reg_rtx (DImode);
|
||||
memh = gen_reg_rtx (DImode);
|
||||
addr = gen_reg_rtx (DImode);
|
||||
extl = gen_reg_rtx (DImode);
|
||||
exth = gen_reg_rtx (DImode);
|
||||
|
||||
emit_move_insn (meml,
|
||||
change_address (mem, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant (XEXP (mem, 0), ofs),
|
||||
GEN_INT (-8))));
|
||||
|
||||
emit_move_insn (memh,
|
||||
change_address (mem, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant (XEXP (mem, 0),
|
||||
ofs + size - 1),
|
||||
GEN_INT (-8))));
|
||||
|
||||
if (sign && size == 2)
|
||||
{
|
||||
emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
|
||||
|
||||
emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
|
||||
emit_insn (gen_extqh (exth, memh, addr));
|
||||
|
||||
expand_binop (DImode, ior_optab, extl, exth, addr, 1, OPTAB_WIDEN);
|
||||
expand_binop (DImode, ashr_optab, addr, GEN_INT (48), addr,
|
||||
1, OPTAB_WIDEN);
|
||||
emit_move_insn (tgt, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
|
||||
emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
emit_insn (gen_extwh (exth, memh, addr));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
emit_insn (gen_extlh (exth, memh, addr));
|
||||
break;
|
||||
|
||||
case 8:
|
||||
emit_insn (gen_extqh (exth, memh, addr));
|
||||
break;
|
||||
}
|
||||
|
||||
expand_binop (DImode, ior_optab, extl, exth, tgt, sign, OPTAB_WIDEN);
|
||||
}
|
||||
|
||||
/* Similarly, use ins and msk instructions to perform unaligned stores. */
|
||||
|
||||
void
|
||||
alpha_expand_unaligned_store (dst, src, size, ofs)
|
||||
rtx dst, src;
|
||||
HOST_WIDE_INT size, ofs;
|
||||
{
|
||||
rtx dstl, dsth, addr, insl, insh, meml, memh;
|
||||
|
||||
dstl = gen_reg_rtx (DImode);
|
||||
dsth = gen_reg_rtx (DImode);
|
||||
insl = gen_reg_rtx (DImode);
|
||||
insh = gen_reg_rtx (DImode);
|
||||
|
||||
meml = change_address (dst, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant (XEXP (dst, 0), ofs),
|
||||
GEN_INT (-8)));
|
||||
memh = change_address (dst, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant (XEXP (dst, 0), ofs+size-1),
|
||||
GEN_INT (-8)));
|
||||
|
||||
emit_move_insn (dsth, memh);
|
||||
emit_move_insn (dstl, meml);
|
||||
addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
|
||||
|
||||
if (src != const0_rtx)
|
||||
{
|
||||
emit_insn (gen_insxh (insh, src, GEN_INT (size*8), addr));
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
|
||||
break;
|
||||
case 4:
|
||||
emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
|
||||
break;
|
||||
case 8:
|
||||
emit_insn (gen_insql (insl, src, addr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
|
||||
break;
|
||||
case 4:
|
||||
emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
|
||||
break;
|
||||
case 8:
|
||||
{
|
||||
#if HOST_BITS_PER_WIDE_INT == 32
|
||||
rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
|
||||
#else
|
||||
rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
|
||||
#endif
|
||||
emit_insn (gen_mskxl (dstl, dstl, msk, addr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (src != const0_rtx)
|
||||
{
|
||||
expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
|
||||
expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
|
||||
}
|
||||
|
||||
/* Must store high before low for degenerate case of aligned. */
|
||||
emit_move_insn (memh, dsth);
|
||||
emit_move_insn (meml, dstl);
|
||||
}
|
||||
|
||||
/* Load an integral number of consecutive unaligned quadwords. */
|
||||
|
||||
#define MAX_MOVE_WORDS 4
|
||||
|
||||
static void
|
||||
alpha_expand_unaligned_load_words (data_regs, src_addr, words)
|
||||
rtx data_regs[MAX_MOVE_WORDS+1];
|
||||
rtx src_addr;
|
||||
HOST_WIDE_INT words;
|
||||
{
|
||||
rtx const im8 = GEN_INT (-8);
|
||||
rtx const i64 = GEN_INT (64);
|
||||
rtx ext_tmps[MAX_MOVE_WORDS];
|
||||
rtx src_reg, and_reg;
|
||||
HOST_WIDE_INT i;
|
||||
|
||||
/* Generate all the tmp registers we need. */
|
||||
for (i = 0; i < words; ++i)
|
||||
ext_tmps[i] = gen_reg_rtx(DImode);
|
||||
|
||||
/* Load up all of the source data. */
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_move_insn (data_regs[i],
|
||||
change_address (src_addr, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant (XEXP(src_addr,0),
|
||||
8*i),
|
||||
im8)));
|
||||
}
|
||||
emit_move_insn (data_regs[words],
|
||||
change_address (src_addr, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant (XEXP(src_addr,0),
|
||||
8*words - 1),
|
||||
im8)));
|
||||
|
||||
/* Extract the half-word fragments. Unfortunately DEC decided to make
|
||||
extxh with offset zero a noop instead of zeroing the register, so
|
||||
we must take care of that edge condition ourselves with cmov. */
|
||||
|
||||
src_reg = copy_addr_to_reg (XEXP (src_addr, 0));
|
||||
and_reg = expand_binop (DImode, and_optab, src_reg, GEN_INT (7), NULL,
|
||||
1, OPTAB_WIDEN);
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, src_reg));
|
||||
|
||||
emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], src_reg));
|
||||
emit_insn (gen_rtx (SET, VOIDmode, ext_tmps[i],
|
||||
gen_rtx (IF_THEN_ELSE, DImode,
|
||||
gen_rtx (EQ, DImode, and_reg, const0_rtx),
|
||||
const0_rtx, ext_tmps[i])));
|
||||
}
|
||||
|
||||
/* Merge the half-words into whole words. */
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
expand_binop (DImode, ior_optab, data_regs[i], ext_tmps[i],
|
||||
data_regs[i], 1, OPTAB_WIDEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store an integral number of consecutive unaligned quadwords. DATA_REGS
|
||||
may be NULL to store zeros. */
|
||||
|
||||
static void
|
||||
alpha_expand_unaligned_store_words (data_regs, dst_addr, words)
|
||||
rtx *data_regs;
|
||||
rtx dst_addr;
|
||||
HOST_WIDE_INT words;
|
||||
{
|
||||
rtx const im8 = GEN_INT (-8);
|
||||
rtx const i64 = GEN_INT (64);
|
||||
#if HOST_BITS_PER_WIDE_INT == 32
|
||||
rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
|
||||
#else
|
||||
rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
|
||||
#endif
|
||||
rtx ins_tmps[MAX_MOVE_WORDS];
|
||||
rtx st_tmp_1, st_tmp_2, dst_reg;
|
||||
rtx st_addr_1, st_addr_2;
|
||||
HOST_WIDE_INT i;
|
||||
|
||||
/* Generate all the tmp registers we need. */
|
||||
if (data_regs != NULL)
|
||||
for (i = 0; i < words; ++i)
|
||||
ins_tmps[i] = gen_reg_rtx(DImode);
|
||||
st_tmp_1 = gen_reg_rtx(DImode);
|
||||
st_tmp_2 = gen_reg_rtx(DImode);
|
||||
|
||||
st_addr_2 = change_address (dst_addr, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant (XEXP(dst_addr,0),
|
||||
words*8 - 1),
|
||||
im8));
|
||||
st_addr_1 = change_address (dst_addr, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
XEXP (dst_addr, 0),
|
||||
im8));
|
||||
|
||||
/* Load up the destination end bits. */
|
||||
emit_move_insn (st_tmp_2, st_addr_2);
|
||||
emit_move_insn (st_tmp_1, st_addr_1);
|
||||
|
||||
/* Shift the input data into place. */
|
||||
dst_reg = copy_addr_to_reg (XEXP (dst_addr, 0));
|
||||
|
||||
if (data_regs != NULL)
|
||||
{
|
||||
for (i = words-1; i >= 0; --i)
|
||||
{
|
||||
emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dst_reg));
|
||||
emit_insn (gen_insql (data_regs[i], data_regs[i], dst_reg));
|
||||
}
|
||||
|
||||
for (i = words-1; i > 0; --i)
|
||||
{
|
||||
expand_binop (DImode, ior_optab, data_regs[i], ins_tmps[i-1],
|
||||
ins_tmps[i-1], 1, OPTAB_WIDEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* Split and merge the ends with the destination data. */
|
||||
emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dst_reg));
|
||||
emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dst_reg));
|
||||
|
||||
if (data_regs != NULL)
|
||||
{
|
||||
expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
|
||||
st_tmp_2, 1, OPTAB_WIDEN);
|
||||
expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
|
||||
st_tmp_1, 1, OPTAB_WIDEN);
|
||||
}
|
||||
|
||||
/* Store it all. */
|
||||
emit_move_insn (st_addr_2, st_tmp_2);
|
||||
for (i = words-1; i > 0; --i)
|
||||
{
|
||||
emit_move_insn (change_address (dst_addr, DImode,
|
||||
gen_rtx (AND, DImode,
|
||||
plus_constant(XEXP (dst_addr,0),
|
||||
i*8),
|
||||
im8)),
|
||||
data_regs ? ins_tmps[i-1] : const0_rtx);
|
||||
}
|
||||
emit_move_insn (st_addr_1, st_tmp_1);
|
||||
}
|
||||
|
||||
|
||||
/* Expand string/block move operations.
|
||||
|
||||
operands[0] is the pointer to the destination.
|
||||
operands[1] is the pointer to the source.
|
||||
operands[2] is the number of bytes to move.
|
||||
operands[3] is the alignment. */
|
||||
|
||||
int
|
||||
alpha_expand_block_move (operands)
|
||||
rtx operands[];
|
||||
{
|
||||
rtx bytes_rtx = operands[2];
|
||||
rtx align_rtx = operands[3];
|
||||
HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
|
||||
HOST_WIDE_INT align = INTVAL (align_rtx);
|
||||
rtx orig_src = operands[1];
|
||||
rtx orig_dst = operands[0];
|
||||
rtx tmp = NULL_RTX;
|
||||
rtx data_regs[2*MAX_MOVE_WORDS];
|
||||
HOST_WIDE_INT i, words, ofs = 0;
|
||||
|
||||
if (bytes <= 0)
|
||||
return 1;
|
||||
if (bytes > MAX_MOVE_WORDS*8)
|
||||
return 0;
|
||||
|
||||
/* Handle a block of contiguous words first. */
|
||||
|
||||
if (align >= 8 && bytes >= 8)
|
||||
{
|
||||
words = bytes / 8;
|
||||
|
||||
/* Make some data registers. */
|
||||
for (i = 0; i < words; ++i)
|
||||
data_regs[i] = gen_reg_rtx(DImode);
|
||||
|
||||
/* Move in aligned hunks. */
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_move_insn (data_regs[i],
|
||||
change_address(orig_src, DImode,
|
||||
plus_constant (XEXP (orig_src, 0),
|
||||
i*8)));
|
||||
}
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_move_insn (change_address(orig_dst, DImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
i*8)),
|
||||
data_regs[i]);
|
||||
}
|
||||
|
||||
bytes -= words * 8;
|
||||
ofs = words * 8;
|
||||
}
|
||||
if (align >= 4 && bytes >= 4)
|
||||
{
|
||||
words = bytes / 4;
|
||||
|
||||
/* Make some data registers. */
|
||||
for (i = 0; i < words; ++i)
|
||||
data_regs[i] = gen_reg_rtx(SImode);
|
||||
|
||||
/* Move in aligned hunks. */
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_move_insn (data_regs[i],
|
||||
change_address(orig_src, SImode,
|
||||
plus_constant (XEXP (orig_src, 0),
|
||||
i*4)));
|
||||
}
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_move_insn (change_address(orig_dst, SImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
i*4)),
|
||||
data_regs[i]);
|
||||
}
|
||||
|
||||
bytes -= words * 4;
|
||||
ofs = words * 4;
|
||||
}
|
||||
if (bytes >= 16)
|
||||
{
|
||||
words = bytes / 8;
|
||||
|
||||
/* Make some data registers. */
|
||||
for (i = 0; i < words+1; ++i)
|
||||
data_regs[i] = gen_reg_rtx(DImode);
|
||||
|
||||
/* Move in unaligned hunks. */
|
||||
alpha_expand_unaligned_load_words (data_regs, orig_src, words);
|
||||
alpha_expand_unaligned_store_words (data_regs, orig_dst, words);
|
||||
|
||||
bytes -= words * 8;
|
||||
ofs = words * 8;
|
||||
}
|
||||
|
||||
/* Next clean up any trailing pieces. We know from the contiguous
|
||||
block move that there are no aligned SImode or DImode hunks left. */
|
||||
|
||||
if (!TARGET_BWX && bytes >= 8)
|
||||
{
|
||||
tmp = gen_reg_rtx (DImode);
|
||||
alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
|
||||
alpha_expand_unaligned_store (orig_dst, tmp, 8, ofs);
|
||||
|
||||
bytes -= 8;
|
||||
ofs += 8;
|
||||
}
|
||||
if (!TARGET_BWX && bytes >= 4)
|
||||
{
|
||||
tmp = gen_reg_rtx (DImode);
|
||||
alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
|
||||
alpha_expand_unaligned_store (orig_dst, tmp, 4, ofs);
|
||||
|
||||
bytes -= 4;
|
||||
ofs += 4;
|
||||
}
|
||||
if (bytes >= 2)
|
||||
{
|
||||
if (align >= 2)
|
||||
{
|
||||
do {
|
||||
emit_move_insn (change_address (orig_dst, HImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
ofs)),
|
||||
change_address (orig_src, HImode,
|
||||
plus_constant (XEXP (orig_src, 0),
|
||||
ofs)));
|
||||
bytes -= 2;
|
||||
ofs += 2;
|
||||
} while (bytes >= 2);
|
||||
}
|
||||
else if (!TARGET_BWX)
|
||||
{
|
||||
tmp = gen_reg_rtx (DImode);
|
||||
alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
|
||||
alpha_expand_unaligned_store (orig_dst, tmp, 2, ofs);
|
||||
bytes -= 2;
|
||||
ofs += 2;
|
||||
}
|
||||
}
|
||||
while (bytes > 0)
|
||||
{
|
||||
emit_move_insn (change_address (orig_dst, QImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
ofs)),
|
||||
change_address (orig_src, QImode,
|
||||
plus_constant (XEXP (orig_src, 0),
|
||||
ofs)));
|
||||
bytes -= 1;
|
||||
ofs += 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
alpha_expand_block_clear (operands)
|
||||
rtx operands[];
|
||||
{
|
||||
rtx bytes_rtx = operands[1];
|
||||
rtx align_rtx = operands[2];
|
||||
HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
|
||||
HOST_WIDE_INT align = INTVAL (align_rtx);
|
||||
rtx orig_dst = operands[0];
|
||||
HOST_WIDE_INT i, words, ofs = 0;
|
||||
|
||||
if (bytes <= 0)
|
||||
return 1;
|
||||
if (bytes > MAX_MOVE_WORDS*8)
|
||||
return 0;
|
||||
|
||||
/* Handle a block of contiguous words first. */
|
||||
|
||||
if (align >= 8 && bytes >= 8)
|
||||
{
|
||||
words = bytes / 8;
|
||||
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_move_insn (change_address(orig_dst, DImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
i*8)),
|
||||
const0_rtx);
|
||||
}
|
||||
|
||||
bytes -= words * 8;
|
||||
ofs = words * 8;
|
||||
}
|
||||
else if (align >= 4 && bytes >= 4)
|
||||
{
|
||||
words = bytes / 4;
|
||||
|
||||
for (i = 0; i < words; ++i)
|
||||
{
|
||||
emit_move_insn (change_address(orig_dst, SImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
i*4)),
|
||||
const0_rtx);
|
||||
}
|
||||
|
||||
bytes -= words * 4;
|
||||
ofs = words * 4;
|
||||
}
|
||||
else if (bytes >= 16)
|
||||
{
|
||||
words = bytes / 8;
|
||||
|
||||
alpha_expand_unaligned_store_words (NULL, orig_dst, words);
|
||||
|
||||
bytes -= words * 8;
|
||||
ofs = words * 8;
|
||||
}
|
||||
|
||||
/* Next clean up any trailing pieces. We know from the contiguous
|
||||
block move that there are no aligned SImode or DImode hunks left. */
|
||||
|
||||
if (!TARGET_BWX && bytes >= 8)
|
||||
{
|
||||
alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
|
||||
bytes -= 8;
|
||||
ofs += 8;
|
||||
}
|
||||
if (!TARGET_BWX && bytes >= 4)
|
||||
{
|
||||
alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
|
||||
bytes -= 4;
|
||||
ofs += 4;
|
||||
}
|
||||
if (bytes >= 2)
|
||||
{
|
||||
if (align >= 2)
|
||||
{
|
||||
do {
|
||||
emit_move_insn (change_address (orig_dst, HImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
ofs)),
|
||||
const0_rtx);
|
||||
bytes -= 2;
|
||||
ofs += 2;
|
||||
} while (bytes >= 2);
|
||||
}
|
||||
else if (!TARGET_BWX)
|
||||
{
|
||||
alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
|
||||
bytes -= 2;
|
||||
ofs += 2;
|
||||
}
|
||||
}
|
||||
while (bytes > 0)
|
||||
{
|
||||
emit_move_insn (change_address (orig_dst, QImode,
|
||||
plus_constant (XEXP (orig_dst, 0),
|
||||
ofs)),
|
||||
const0_rtx);
|
||||
bytes -= 1;
|
||||
ofs += 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Adjust the cost of a scheduling dependency. Return the new cost of
|
||||
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
|
||||
|
@ -1667,13 +2255,17 @@ print_operand (file, x, code)
|
|||
break;
|
||||
|
||||
case 'M':
|
||||
/* 'b', 'w', or 'l' as the value of the constant. */
|
||||
/* 'b', 'w', 'l', or 'q' as the value of the constant. */
|
||||
if (GET_CODE (x) != CONST_INT
|
||||
|| (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
|
||||
|| (INTVAL (x) != 8 && INTVAL (x) != 16
|
||||
&& INTVAL (x) != 32 && INTVAL (x) != 64))
|
||||
output_operand_lossage ("invalid %%M value");
|
||||
|
||||
fprintf (file, "%s",
|
||||
INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
|
||||
(INTVAL (x) == 8 ? "b"
|
||||
: INTVAL (x) == 16 ? "w"
|
||||
: INTVAL (x) == 32 ? "l"
|
||||
: "q"));
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
|
@ -1687,9 +2279,19 @@ print_operand (file, x, code)
|
|||
&& CONST_DOUBLE_HIGH (x) == 0
|
||||
&& CONST_DOUBLE_LOW (x) == -1)
|
||||
fprintf (file, "l");
|
||||
else if (GET_CODE (x) == CONST_DOUBLE
|
||||
&& CONST_DOUBLE_HIGH (x) == -1
|
||||
&& CONST_DOUBLE_LOW (x) == -1)
|
||||
fprintf (file, "q");
|
||||
#else
|
||||
else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
|
||||
fprintf (file, "l");
|
||||
else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
|
||||
fprintf (file, "q");
|
||||
else if (GET_CODE (x) == CONST_DOUBLE
|
||||
&& CONST_DOUBLE_HIGH (x) == 0
|
||||
&& CONST_DOUBLE_LOW (x) == -1)
|
||||
fprintf (file, "q");
|
||||
#endif
|
||||
else
|
||||
output_operand_lossage ("invalid %%U value");
|
||||
|
|
|
@ -384,18 +384,22 @@ extern void override_options ();
|
|||
??? Kludge this and the next macro for the moment by not doing anything if
|
||||
we don't optimize and also if we are writing ECOFF symbols to work around
|
||||
a bug in DEC's assembler. */
|
||||
/* Aligning past 2**3 wastes insn cache lines, and doesn't buy much
|
||||
issue-wise on average anyway. */
|
||||
|
||||
#define ASM_OUTPUT_LOOP_ALIGN(FILE) \
|
||||
if (optimize > 0 && write_symbols != SDB_DEBUG) \
|
||||
ASM_OUTPUT_ALIGN (FILE, 5)
|
||||
ASM_OUTPUT_ALIGN (FILE, 3)
|
||||
|
||||
/* This is how to align an instruction for optimal branching.
|
||||
On Alpha we'll get better performance by aligning on a quadword
|
||||
boundary. */
|
||||
/* Aligning past 2**3 wastes insn cache lines, and doesn't buy much
|
||||
issue-wise on average anyway. */
|
||||
|
||||
#define ASM_OUTPUT_ALIGN_CODE(FILE) \
|
||||
if (optimize > 0 && write_symbols != SDB_DEBUG) \
|
||||
ASM_OUTPUT_ALIGN ((FILE), 4)
|
||||
ASM_OUTPUT_ALIGN ((FILE), 3)
|
||||
|
||||
/* No data type wants to be aligned rounder than this. */
|
||||
#define BIGGEST_ALIGNMENT 64
|
||||
|
@ -406,8 +410,12 @@ extern void override_options ();
|
|||
|
||||
/* Align all constants and variables to at least a word boundary so
|
||||
we can pick up pieces of them faster. */
|
||||
/* ??? Only if block-move stuff knows about different source/destination
|
||||
alignment. */
|
||||
#if 0
|
||||
#define CONSTANT_ALIGNMENT(EXP, ALIGN) MAX ((ALIGN), BITS_PER_WORD)
|
||||
#define DATA_ALIGNMENT(EXP, ALIGN) MAX ((ALIGN), BITS_PER_WORD)
|
||||
#endif
|
||||
|
||||
/* Set this non-zero if move instructions will actually fail to work
|
||||
when given unaligned data.
|
||||
|
@ -1509,6 +1517,12 @@ extern void alpha_init_expanders ();
|
|||
|
||||
#define MOVE_MAX 8
|
||||
|
||||
/* Controls how many units are moved by expr.c before resorting to movstr.
|
||||
Without byte/word accesses, we want no more than one; with, several single
|
||||
byte accesses are better. */
|
||||
|
||||
#define MOVE_RATIO (TARGET_BWX ? 7 : 2)
|
||||
|
||||
/* Largest number of bytes of an object that can be placed in a register.
|
||||
On the Alpha we have plenty of registers, so use TImode. */
|
||||
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode)
|
||||
|
|
|
@ -1431,7 +1431,7 @@
|
|||
"ext%M2l %r1,%s3,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "extxl"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
||||
(match_operand:DI 2 "mode_width_operand" "n")
|
||||
|
@ -1441,7 +1441,7 @@
|
|||
"ext%M2l %r1,%3,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "extqh"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(ashift:DI
|
||||
(match_operand:DI 1 "reg_or_0_operand" "rJ")
|
||||
|
@ -1456,7 +1456,7 @@
|
|||
"extqh %r1,%2,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "extlh"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(ashift:DI
|
||||
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
||||
|
@ -1472,7 +1472,7 @@
|
|||
"extlh %r1,%2,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "extwh"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(ashift:DI
|
||||
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
|
||||
|
@ -1538,7 +1538,7 @@
|
|||
"insll %1,%s2,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "insbl"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
|
||||
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
||||
|
@ -1547,7 +1547,7 @@
|
|||
"insbl %1,%2,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "inswl"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
|
||||
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
||||
|
@ -1556,7 +1556,7 @@
|
|||
"inswl %1,%2,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "insll"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
|
||||
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
||||
|
@ -1565,10 +1565,30 @@
|
|||
"insll %1,%2,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn "insql"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(ashift:DI (match_operand:DI 1 "register_operand" "r")
|
||||
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
|
||||
(const_int 3))))]
|
||||
""
|
||||
"insql %1,%2,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
;; We do not include the insXh insns because they are complex to express
|
||||
;; and it does not appear that we would ever want to generate them.
|
||||
;;
|
||||
;; Since we need them for block moves, though, cop out and use unspec.
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "insxh"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(unspec [(match_operand:DI 1 "register_operand" "r")
|
||||
(match_operand:DI 2 "mode_width_operand" "n")
|
||||
(match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
|
||||
""
|
||||
"ins%M2h %1,%3,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
(define_insn "mskxl"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(and:DI (not:DI (ashift:DI
|
||||
(match_operand:DI 2 "mode_mask_operand" "n")
|
||||
|
@ -1580,8 +1600,19 @@
|
|||
"msk%U2l %r1,%3,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
;; We do not include the mskXh insns because it does not appear we would ever
|
||||
;; generate one.
|
||||
;; We do not include the mskXh insns because it does not appear we would
|
||||
;; ever generate one.
|
||||
;;
|
||||
;; Again, we do for block moves and we use unspec again.
|
||||
|
||||
(define_insn "mskxh"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(unspec [(match_operand:DI 1 "register_operand" "r")
|
||||
(match_operand:DI 2 "mode_width_operand" "n")
|
||||
(match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
|
||||
""
|
||||
"msk%M2h %1,%3,%0"
|
||||
[(set_attr "type" "shift")])
|
||||
|
||||
;; Floating-point operations. All the double-precision insns can extend
|
||||
;; from single, so indicate that. The exception are the ones that simply
|
||||
|
@ -4781,6 +4812,122 @@
|
|||
DONE;
|
||||
}")
|
||||
|
||||
;; Bit field extract patterns which use ext[wlq][lh]
|
||||
|
||||
(define_expand "extv"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(sign_extract:DI (match_operand:QI 1 "memory_operand" "")
|
||||
(match_operand:DI 2 "immediate_operand" "")
|
||||
(match_operand:DI 3 "immediate_operand" "")))]
|
||||
""
|
||||
"
|
||||
{
|
||||
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
||||
if (INTVAL (operands[3]) % 8 != 0
|
||||
|| (INTVAL (operands[2]) != 16
|
||||
&& INTVAL (operands[2]) != 32
|
||||
&& INTVAL (operands[2]) != 64))
|
||||
FAIL;
|
||||
|
||||
/* From mips.md: extract_bit_field doesn't verify that our source
|
||||
matches the predicate, so we force it to be a MEM here. */
|
||||
if (GET_CODE (operands[1]) != MEM)
|
||||
FAIL;
|
||||
|
||||
alpha_expand_unaligned_load (operands[0], operands[1],
|
||||
INTVAL (operands[2]) / 8,
|
||||
INTVAL (operands[3]) / 8, 1);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "extzv"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(zero_extract:DI (match_operand:QI 1 "memory_operand" "")
|
||||
(match_operand:DI 2 "immediate_operand" "")
|
||||
(match_operand:DI 3 "immediate_operand" "")))]
|
||||
""
|
||||
"
|
||||
{
|
||||
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
||||
if (INTVAL (operands[3]) % 8 != 0
|
||||
|| (INTVAL (operands[2]) != 16
|
||||
&& INTVAL (operands[2]) != 32
|
||||
&& INTVAL (operands[2]) != 64))
|
||||
FAIL;
|
||||
|
||||
/* From mips.md: extract_bit_field doesn't verify that our source
|
||||
matches the predicate, so we force it to be a MEM here. */
|
||||
if (GET_CODE (operands[1]) != MEM)
|
||||
FAIL;
|
||||
|
||||
alpha_expand_unaligned_load (operands[0], operands[1],
|
||||
INTVAL (operands[2]) / 8,
|
||||
INTVAL (operands[3]) / 8, 0);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_expand "insv"
|
||||
[(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
|
||||
(match_operand:DI 1 "immediate_operand" "")
|
||||
(match_operand:DI 2 "immediate_operand" ""))
|
||||
(match_operand:DI 3 "register_operand" ""))]
|
||||
""
|
||||
"
|
||||
{
|
||||
/* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
|
||||
if (INTVAL (operands[2]) % 8 != 0
|
||||
|| (INTVAL (operands[1]) != 16
|
||||
&& INTVAL (operands[1]) != 32
|
||||
&& INTVAL (operands[1]) != 64))
|
||||
FAIL;
|
||||
|
||||
/* From mips.md: store_bit_field doesn't verify that our source
|
||||
matches the predicate, so we force it to be a MEM here. */
|
||||
if (GET_CODE (operands[0]) != MEM)
|
||||
FAIL;
|
||||
|
||||
alpha_expand_unaligned_store (operands[0], operands[3],
|
||||
INTVAL (operands[1]) / 8,
|
||||
INTVAL (operands[2]) / 8);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
|
||||
|
||||
;; Block move/clear, see alpha.c for more details.
|
||||
;; Argument 0 is the destination
|
||||
;; Argument 1 is the source
|
||||
;; Argument 2 is the length
|
||||
;; Argument 3 is the alignment
|
||||
|
||||
(define_expand "movstrqi"
|
||||
[(parallel [(set (match_operand:BLK 0 "general_operand" "")
|
||||
(match_operand:BLK 1 "general_operand" ""))
|
||||
(use (match_operand:DI 2 "immediate_operand" ""))
|
||||
(use (match_operand:DI 3 "immediate_operand" ""))])]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (alpha_expand_block_move (operands))
|
||||
DONE;
|
||||
else
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
(define_expand "clrstrqi"
|
||||
[(parallel [(set (match_operand:BLK 0 "general_operand" "")
|
||||
(const_int 0))
|
||||
(use (match_operand:DI 1 "immediate_operand" ""))
|
||||
(use (match_operand:DI 2 "immediate_operand" ""))])]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (alpha_expand_block_clear (operands))
|
||||
DONE;
|
||||
else
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
;; Subroutine of stack space allocation. Perform a stack probe.
|
||||
(define_expand "probe_stack"
|
||||
[(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
|
||||
|
|
12
gcc/expr.c
12
gcc/expr.c
|
@ -9036,7 +9036,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
|||
|| (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
|
||||
!= INTEGER_TYPE)
|
||||
|| TREE_CHAIN (TREE_CHAIN (arglist)) == 0
|
||||
|| (INTEGER_CST
|
||||
|| (INTEGER_TYPE
|
||||
!= (TREE_CODE (TREE_TYPE
|
||||
(TREE_VALUE
|
||||
(TREE_CHAIN (TREE_CHAIN (arglist))))))))
|
||||
|
@ -9061,11 +9061,16 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
|||
if (expand_expr (val, NULL_RTX, VOIDmode, 0) != const0_rtx)
|
||||
break;
|
||||
|
||||
/* If LEN does not expand to a constant, don't do this
|
||||
operation in-line. */
|
||||
len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
|
||||
if (GET_CODE (len_rtx) != CONST_INT)
|
||||
break;
|
||||
|
||||
dest_rtx = expand_expr (dest, NULL_RTX, ptr_mode, EXPAND_SUM);
|
||||
dest_mem = gen_rtx (MEM, BLKmode,
|
||||
memory_address (BLKmode, dest_rtx));
|
||||
len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
|
||||
/* Just check DST is writable and mark it as readable. */
|
||||
if (flag_check_memory_usage)
|
||||
emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
|
||||
|
@ -9074,7 +9079,6 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
|||
GEN_INT (MEMORY_USE_WO),
|
||||
TYPE_MODE (integer_type_node));
|
||||
|
||||
|
||||
/* There could be a void* cast on top of the object. */
|
||||
while (TREE_CODE (dest) == NOP_EXPR)
|
||||
dest = TREE_OPERAND (dest, 0);
|
||||
|
|
Loading…
Reference in New Issue