Commit 56636818 by Jeffrey A Law Committed by Jeff Law

* arm.c (output_move_double): Allocate 3 entries in otherops array.

From-SVN: r16281
parent b9ddcfac
Sun Nov 2 19:27:21 1997 Jeffrey A Law (law@cygnus.com)
* arm.c (output_move_double): Allocate 3 entries in otherops array.
Sat Nov 1 21:43:00 1997 Mike Stump (mrs@wrs.com) Sat Nov 1 21:43:00 1997 Mike Stump (mrs@wrs.com)
* except.c (expand_ex_region_start_for_decl): Emit EH_REGION_BEG * except.c (expand_ex_region_start_for_decl): Emit EH_REGION_BEG
......
...@@ -21,10 +21,10 @@ along with GNU CC; see the file COPYING. If not, write to ...@@ -21,10 +21,10 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "assert.h" #include "assert.h"
#include "config.h"
#include "rtl.h" #include "rtl.h"
#include "regs.h" #include "regs.h"
#include "hard-reg-set.h" #include "hard-reg-set.h"
...@@ -376,7 +376,8 @@ use_return_insn () ...@@ -376,7 +376,8 @@ use_return_insn ()
if (!reload_completed ||current_function_pretend_args_size if (!reload_completed ||current_function_pretend_args_size
|| current_function_anonymous_args || current_function_anonymous_args
|| (get_frame_size () && !(TARGET_APCS || frame_pointer_needed))) || ((get_frame_size () + current_function_outgoing_args_size != 0)
&& !(TARGET_APCS || frame_pointer_needed)))
return 0; return 0;
/* Can't be done if interworking with Thumb, and any registers have been /* Can't be done if interworking with Thumb, and any registers have been
...@@ -407,6 +408,13 @@ const_ok_for_arm (i) ...@@ -407,6 +408,13 @@ const_ok_for_arm (i)
{ {
unsigned HOST_WIDE_INT mask = ~0xFF; unsigned HOST_WIDE_INT mask = ~0xFF;
/* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must
be all zero, or all one. */
if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0
&& ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff)
!= (((HOST_WIDE_INT) -1) & ~(unsigned HOST_WIDE_INT) 0xffffffff)))
return FALSE;
/* Fast return for 0 and powers of 2 */ /* Fast return for 0 and powers of 2 */
if ((i & (i - 1)) == 0) if ((i & (i - 1)) == 0)
return TRUE; return TRUE;
...@@ -1501,6 +1509,17 @@ arm_rtx_costs (x, code, outer_code) ...@@ -1501,6 +1509,17 @@ arm_rtx_costs (x, code, outer_code)
+ (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
+ (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4)); + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4));
case TRUNCATE:
if (arm_fast_multiply && mode == SImode
&& GET_CODE (XEXP (x, 0)) == LSHIFTRT
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
&& (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
== GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)))
&& (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND))
return 8;
return 99;
case NEG: case NEG:
if (GET_MODE_CLASS (mode) == MODE_FLOAT) if (GET_MODE_CLASS (mode) == MODE_FLOAT)
return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6); return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6);
...@@ -2352,6 +2371,10 @@ load_multiple_sequence (operands, nops, regs, base, load_offset) ...@@ -2352,6 +2371,10 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
rtx reg; rtx reg;
rtx offset; rtx offset;
/* Convert a subreg of a mem into the mem itself. */
if (GET_CODE (operands[nops + i]) == SUBREG)
operands[nops + i] = alter_subreg(operands[nops + i]);
if (GET_CODE (operands[nops + i]) != MEM) if (GET_CODE (operands[nops + i]) != MEM)
abort (); abort ();
...@@ -2551,6 +2574,10 @@ store_multiple_sequence (operands, nops, regs, base, load_offset) ...@@ -2551,6 +2574,10 @@ store_multiple_sequence (operands, nops, regs, base, load_offset)
rtx reg; rtx reg;
rtx offset; rtx offset;
/* Convert a subreg of a mem into the mem itself. */
if (GET_CODE (operands[nops + i]) == SUBREG)
operands[nops + i] = alter_subreg(operands[nops + i]);
if (GET_CODE (operands[nops + i]) != MEM) if (GET_CODE (operands[nops + i]) != MEM)
abort (); abort ();
...@@ -2761,16 +2788,20 @@ arm_naked_function_p (func) ...@@ -2761,16 +2788,20 @@ arm_naked_function_p (func)
/* Routines for use in generating RTL */ /* Routines for use in generating RTL */
rtx rtx
arm_gen_load_multiple (base_regno, count, from, up, write_back) arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
in_struct_p)
int base_regno; int base_regno;
int count; int count;
rtx from; rtx from;
int up; int up;
int write_back; int write_back;
int unchanging_p;
int in_struct_p;
{ {
int i = 0, j; int i = 0, j;
rtx result; rtx result;
int sign = up ? 1 : -1; int sign = up ? 1 : -1;
rtx mem;
result = gen_rtx (PARALLEL, VOIDmode, result = gen_rtx (PARALLEL, VOIDmode,
rtvec_alloc (count + (write_back ? 2 : 0))); rtvec_alloc (count + (write_back ? 2 : 0)));
...@@ -2785,10 +2816,13 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back) ...@@ -2785,10 +2816,13 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back)
for (j = 0; i < count; i++, j++) for (j = 0; i < count; i++, j++)
{ {
XVECEXP (result, 0, i) mem = gen_rtx (MEM, SImode, plus_constant (from, j * 4 * sign));
= gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, base_regno + j), RTX_UNCHANGING_P (mem) = unchanging_p;
gen_rtx (MEM, SImode, MEM_IN_STRUCT_P (mem) = in_struct_p;
plus_constant (from, j * 4 * sign)));
XVECEXP (result, 0, i) = gen_rtx (SET, VOIDmode,
gen_rtx (REG, SImode, base_regno + j),
mem);
} }
if (write_back) if (write_back)
...@@ -2798,16 +2832,20 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back) ...@@ -2798,16 +2832,20 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back)
} }
rtx rtx
arm_gen_store_multiple (base_regno, count, to, up, write_back) arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
in_struct_p)
int base_regno; int base_regno;
int count; int count;
rtx to; rtx to;
int up; int up;
int write_back; int write_back;
int unchanging_p;
int in_struct_p;
{ {
int i = 0, j; int i = 0, j;
rtx result; rtx result;
int sign = up ? 1 : -1; int sign = up ? 1 : -1;
rtx mem;
result = gen_rtx (PARALLEL, VOIDmode, result = gen_rtx (PARALLEL, VOIDmode,
rtvec_alloc (count + (write_back ? 2 : 0))); rtvec_alloc (count + (write_back ? 2 : 0)));
...@@ -2822,10 +2860,12 @@ arm_gen_store_multiple (base_regno, count, to, up, write_back) ...@@ -2822,10 +2860,12 @@ arm_gen_store_multiple (base_regno, count, to, up, write_back)
for (j = 0; i < count; i++, j++) for (j = 0; i < count; i++, j++)
{ {
XVECEXP (result, 0, i) mem = gen_rtx (MEM, SImode, plus_constant (to, j * 4 * sign));
= gen_rtx (SET, VOIDmode, RTX_UNCHANGING_P (mem) = unchanging_p;
gen_rtx (MEM, SImode, plus_constant (to, j * 4 * sign)), MEM_IN_STRUCT_P (mem) = in_struct_p;
gen_rtx (REG, SImode, base_regno + j));
XVECEXP (result, 0, i) = gen_rtx (SET, VOIDmode, mem,
gen_rtx (REG, SImode, base_regno + j));
} }
if (write_back) if (write_back)
...@@ -2843,6 +2883,8 @@ arm_gen_movstrqi (operands) ...@@ -2843,6 +2883,8 @@ arm_gen_movstrqi (operands)
rtx src, dst; rtx src, dst;
rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst; rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst;
rtx part_bytes_reg = NULL; rtx part_bytes_reg = NULL;
rtx mem;
int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
extern int optimize; extern int optimize;
if (GET_CODE (operands[2]) != CONST_INT if (GET_CODE (operands[2]) != CONST_INT
...@@ -2853,6 +2895,12 @@ arm_gen_movstrqi (operands) ...@@ -2853,6 +2895,12 @@ arm_gen_movstrqi (operands)
st_dst = XEXP (operands[0], 0); st_dst = XEXP (operands[0], 0);
st_src = XEXP (operands[1], 0); st_src = XEXP (operands[1], 0);
dst_unchanging_p = RTX_UNCHANGING_P (operands[0]);
dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
src_unchanging_p = RTX_UNCHANGING_P (operands[1]);
src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
fin_dst = dst = copy_to_mode_reg (SImode, st_dst); fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
fin_src = src = copy_to_mode_reg (SImode, st_src); fin_src = src = copy_to_mode_reg (SImode, st_src);
...@@ -2866,24 +2914,32 @@ arm_gen_movstrqi (operands) ...@@ -2866,24 +2914,32 @@ arm_gen_movstrqi (operands)
for (i = 0; in_words_to_go >= 2; i+=4) for (i = 0; in_words_to_go >= 2; i+=4)
{ {
if (in_words_to_go > 4) if (in_words_to_go > 4)
emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE)); emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
src_unchanging_p, src_in_struct_p));
else else
emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,
FALSE)); FALSE, src_unchanging_p,
src_in_struct_p));
if (out_words_to_go) if (out_words_to_go)
{ {
if (out_words_to_go > 4) if (out_words_to_go > 4)
emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE)); emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
dst_unchanging_p,
dst_in_struct_p));
else if (out_words_to_go != 1) else if (out_words_to_go != 1)
emit_insn (arm_gen_store_multiple (0, out_words_to_go, emit_insn (arm_gen_store_multiple (0, out_words_to_go,
dst, TRUE, dst, TRUE,
(last_bytes == 0 (last_bytes == 0
? FALSE : TRUE))); ? FALSE : TRUE),
dst_unchanging_p,
dst_in_struct_p));
else else
{ {
emit_move_insn (gen_rtx (MEM, SImode, dst), mem = gen_rtx (MEM, SImode, dst);
gen_rtx (REG, SImode, 0)); RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
emit_move_insn (mem, gen_rtx (REG, SImode, 0));
if (last_bytes != 0) if (last_bytes != 0)
emit_insn (gen_addsi3 (dst, dst, GEN_INT (4))); emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
} }
...@@ -2898,9 +2954,16 @@ arm_gen_movstrqi (operands) ...@@ -2898,9 +2954,16 @@ arm_gen_movstrqi (operands)
{ {
rtx sreg; rtx sreg;
emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src)); mem = gen_rtx (MEM, SImode, src);
RTX_UNCHANGING_P (mem) = src_unchanging_p;
MEM_IN_STRUCT_P (mem) = src_in_struct_p;
emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4)); emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
emit_move_insn (gen_rtx (MEM, SImode, dst), sreg);
mem = gen_rtx (MEM, SImode, dst);
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
emit_move_insn (mem, sreg);
emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4)); emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
in_words_to_go--; in_words_to_go--;
...@@ -2913,7 +2976,10 @@ arm_gen_movstrqi (operands) ...@@ -2913,7 +2976,10 @@ arm_gen_movstrqi (operands)
if (in_words_to_go < 0) if (in_words_to_go < 0)
abort (); abort ();
part_bytes_reg = copy_to_mode_reg (SImode, gen_rtx (MEM, SImode, src)); mem = gen_rtx (MEM, SImode, src);
RTX_UNCHANGING_P (mem) = src_unchanging_p;
MEM_IN_STRUCT_P (mem) = src_in_struct_p;
part_bytes_reg = copy_to_mode_reg (SImode, mem);
} }
if (BYTES_BIG_ENDIAN && last_bytes) if (BYTES_BIG_ENDIAN && last_bytes)
...@@ -2930,9 +2996,10 @@ arm_gen_movstrqi (operands) ...@@ -2930,9 +2996,10 @@ arm_gen_movstrqi (operands)
while (last_bytes) while (last_bytes)
{ {
emit_move_insn (gen_rtx (MEM, QImode, mem = gen_rtx (MEM, QImode, plus_constant (dst, last_bytes - 1));
plus_constant (dst, last_bytes - 1)), RTX_UNCHANGING_P (mem) = dst_unchanging_p;
gen_rtx (SUBREG, QImode, part_bytes_reg, 0)); MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
emit_move_insn (mem, gen_rtx (SUBREG, QImode, part_bytes_reg, 0));
if (--last_bytes) if (--last_bytes)
{ {
tmp = gen_reg_rtx (SImode); tmp = gen_reg_rtx (SImode);
...@@ -2949,8 +3016,10 @@ arm_gen_movstrqi (operands) ...@@ -2949,8 +3016,10 @@ arm_gen_movstrqi (operands)
if (part_bytes_reg == NULL) if (part_bytes_reg == NULL)
abort (); abort ();
emit_move_insn (gen_rtx (MEM, QImode, dst), mem = gen_rtx (MEM, QImode, dst);
gen_rtx (SUBREG, QImode, part_bytes_reg, 0)); RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
emit_move_insn (mem, gen_rtx (SUBREG, QImode, part_bytes_reg, 0));
if (--last_bytes) if (--last_bytes)
{ {
rtx tmp = gen_reg_rtx (SImode); rtx tmp = gen_reg_rtx (SImode);
...@@ -3913,7 +3982,7 @@ output_move_double (operands) ...@@ -3913,7 +3982,7 @@ output_move_double (operands)
{ {
enum rtx_code code0 = GET_CODE (operands[0]); enum rtx_code code0 = GET_CODE (operands[0]);
enum rtx_code code1 = GET_CODE (operands[1]); enum rtx_code code1 = GET_CODE (operands[1]);
rtx otherops[2]; rtx otherops[3];
if (code0 == REG) if (code0 == REG)
{ {
...@@ -3964,7 +4033,21 @@ output_move_double (operands) ...@@ -3964,7 +4033,21 @@ output_move_double (operands)
} }
else if (code1 == CONST_INT) else if (code1 == CONST_INT)
{ {
/* sign extend the intval into the high-order word */ #if HOST_BITS_PER_WIDE_INT > 32
/* If HOST_WIDE_INT is more than 32 bits, the intval tells us
what the upper word is. */
if (WORDS_BIG_ENDIAN)
{
otherops[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
operands[1] = GEN_INT (INTVAL (operands[1]) >> 32);
}
else
{
otherops[1] = GEN_INT (INTVAL (operands[1]) >> 32);
operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
}
#else
/* Sign extend the intval into the high-order word */
if (WORDS_BIG_ENDIAN) if (WORDS_BIG_ENDIAN)
{ {
otherops[1] = operands[1]; otherops[1] = operands[1];
...@@ -3973,6 +4056,7 @@ output_move_double (operands) ...@@ -3973,6 +4056,7 @@ output_move_double (operands)
} }
else else
otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx; otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
#endif
output_mov_immediate (otherops); output_mov_immediate (otherops);
output_mov_immediate (operands); output_mov_immediate (operands);
} }
...@@ -4762,10 +4846,9 @@ output_func_epilogue (f, frame_size) ...@@ -4762,10 +4846,9 @@ output_func_epilogue (f, frame_size)
if (use_return_insn() && return_used_this_function) if (use_return_insn() && return_used_this_function)
{ {
if (frame_size && !(frame_pointer_needed || TARGET_APCS)) if ((frame_size + current_function_outgoing_args_size) != 0
{ && !(frame_pointer_needed || TARGET_APCS))
abort (); abort ();
}
goto epilogue_done; goto epilogue_done;
} }
...@@ -4853,10 +4936,11 @@ output_func_epilogue (f, frame_size) ...@@ -4853,10 +4936,11 @@ output_func_epilogue (f, frame_size)
else else
{ {
/* Restore stack pointer if necessary. */ /* Restore stack pointer if necessary. */
if (frame_size) if (frame_size + current_function_outgoing_args_size != 0)
{ {
operands[0] = operands[1] = stack_pointer_rtx; operands[0] = operands[1] = stack_pointer_rtx;
operands[2] = gen_rtx (CONST_INT, VOIDmode, frame_size); operands[2] = GEN_INT (frame_size
+ current_function_outgoing_args_size);
output_add_immediate (operands); output_add_immediate (operands);
} }
...@@ -5028,7 +5112,8 @@ void ...@@ -5028,7 +5112,8 @@ void
arm_expand_prologue () arm_expand_prologue ()
{ {
int reg; int reg;
rtx amount = GEN_INT (- get_frame_size ()); rtx amount = GEN_INT (-(get_frame_size ()
+ current_function_outgoing_args_size));
rtx push_insn; rtx push_insn;
int num_regs; int num_regs;
int live_regs_mask = 0; int live_regs_mask = 0;
...@@ -5295,34 +5380,6 @@ arm_print_operand (stream, x, code) ...@@ -5295,34 +5380,6 @@ arm_print_operand (stream, x, code)
} }
} }
/* Output a label definition. */
void
arm_asm_output_label (stream, name)
FILE *stream;
char *name;
{
ARM_OUTPUT_LABEL (stream, name);
}
/* Output code resembling an .lcomm directive. /bin/as doesn't have this
directive hence this hack, which works by reserving some `.space' in the
bss segment directly.
XXX This is a severe hack, which is guaranteed NOT to work since it doesn't
define STATIC COMMON space but merely STATIC BSS space. */
void
output_lcomm_directive (stream, name, size, align)
FILE *stream;
char *name;
int size, align;
{
bss_section ();
ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
ARM_OUTPUT_LABEL (stream, name);
fprintf (stream, "\t.space\t%d\n", size);
}
/* A finite state machine takes care of noticing whether or not instructions /* A finite state machine takes care of noticing whether or not instructions
can be conditionally executed, and thus decrease execution time and code can be conditionally executed, and thus decrease execution time and code
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment