aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@cygnus.com>1999-02-25 10:20:21 +0000
committerNick Clifton <nickc@gcc.gnu.org>1999-02-25 10:20:21 +0000
commit6cc8c0b3b5da0b9c48cd95d596cc8ba2f205d460 (patch)
tree44cefa946a96e91677979018199462ae4fdf24ba
parent592e5d21b1994911eee8c785222ac9ca217453e2 (diff)
downloadgcc-6cc8c0b3b5da0b9c48cd95d596cc8ba2f205d460.zip
gcc-6cc8c0b3b5da0b9c48cd95d596cc8ba2f205d460.tar.gz
gcc-6cc8c0b3b5da0b9c48cd95d596cc8ba2f205d460.tar.bz2
Tidy up previous delta
From-SVN: r25431
-rw-r--r--gcc/ChangeLog28
-rw-r--r--gcc/config/arm/arm.c30
-rw-r--r--gcc/config/arm/arm.h22
-rw-r--r--gcc/config/arm/arm.md58
-rw-r--r--gcc/config/arm/riscix.h5
-rw-r--r--gcc/config/arm/riscix1-1.h6
6 files changed, 117 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c66e69..8a40b45 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,31 @@
+Thu Feb 25 10:17:32 1999 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.c (return_in_memory): Float fields in unions
+ force a return in memory.
+ (load_multiple_sequence): Add comment explaining why two LDR
+ instructions can be better than an LDMIA instruction.
+
+ * config/arm/arm.h (TARGET_SHORT_BY_BYTES): Add comment
+ describing the real meaning of this option.
+ (FIXED_REGISTERS): Default r10 to not-fixed.
+ (CALL_USED_REGISTERS): Default r10 to not-call-used.
+ (SUBTARGET_CONDITIONAL_REGISTER_USAGE): If not defined, define
+ as empty.
+ (CONDITIONAL_REGISTER_USAGE): Fix r10 if TARGET_APCS_STACK is
+ true. Invoke SUBTARGET_CONDITIONAL_REGISTER_USAGE after
+ performing other checks.
+
+ * config/arm/arm.md (zero_extendhisi2): Undo previous change.
+ (extendhisi2): Undo previous change.
+ Also add comments describing why TARGET_SHORT_BY_BYTES can be
+ ignored for armv4(t) architectures.
+
+ * config/arm/riscix.h (SUBTARGET_CONDITIONAL_REGISTER_USAGE):
+ Define to fix r10.
+
+ * config/arm/riscix1-1.h
+ (SUBTARGET_CONDITIONAL_REGISTER_USAGE): Define to fix r10.
+
Thu Feb 25 12:09:04 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* cse.c (dump_class): Make the function definition static to match
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6866da5..54607b7 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1328,6 +1328,9 @@ arm_return_in_memory (type)
if (TREE_CODE (field) != FIELD_DECL)
continue;
+ if (FLOAT_TYPE_P (TREE_TYPE (field)))
+ return 1;
+
if (RETURN_IN_MEMORY (TREE_TYPE (field)))
return 1;
}
@@ -2700,7 +2703,32 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
return 4; /* ldmdb */
/* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if
- the offset isn't small enough */
+ the offset isn't small enough. The reason 2 ldrs are faster is because
+ these ARMs are able to do more than one cache access in a single cycle.
+ The ARM9 and StrongARM have Harvard caches, whilst the ARM8 has a double
+ bandwidth cache. This means that these cores can do both an instruction
+ fetch and a data fetch in a single cycle, so the trick of calculating the
+ address into a scratch register (one of the result regs) and then doing a
+ load multiple actually becomes slower (and no smaller in code size). That
+ is the transformation
+
+ ldr rd1, [rbase + offset]
+ ldr rd2, [rbase + offset + 4]
+
+ to
+
+ add rd1, rbase, offset
+ ldmia rd1, {rd1, rd2}
+
+ produces worse code -- '3 cycles + any stalls on rd2' instead of '2 cycles
+ + any stalls on rd2'. On ARMs with only one cache access per cycle, the
+ first sequence could never complete in less than 6 cycles, whereas the ldm
+ sequence would only take 5 and would make better use of sequential accesses
+ if not hitting the cache.
+
+ We cheat here and test 'arm_ld_sched' which we currently know to only be
+ true for the ARM8, ARM9 and StrongARM. If this ever changes, then the test
+ below needs to be reworked. */
if (nops == 2 && arm_ld_sched)
return 0;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 15ac18b..685a267 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -337,6 +337,13 @@ function tries to return. */
#define TARGET_APCS_STACK (target_flags & ARM_FLAG_APCS_STACK)
#define TARGET_APCS_FLOAT (target_flags & ARM_FLAG_APCS_FLOAT)
#define TARGET_APCS_REENT (target_flags & ARM_FLAG_APCS_REENT)
+/* Note: TARGET_SHORT_BY_BYTES is really a misnomer. What it means is
+ that short values sould not be accessed using word load instructions
+ as there is a possibility that they may not be word aligned and this
+ would generate an MMU fault. On processors which do not have a 16 bit
+ load instruction therefore, short values must be loaded by individual
+ byte accesses rather than loading a word and then shifting the desired
+ value into place. */
#define TARGET_SHORT_BY_BYTES (target_flags & ARM_FLAG_SHORT_BYTE)
#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
@@ -677,7 +684,7 @@ extern char * structure_size_string;
#define FIXED_REGISTERS \
{ \
0,0,0,0,0,0,0,0, \
- 0,0,1,1,0,1,0,1, \
+ 0,0,0,1,0,1,0,1, \
0,0,0,0,0,0,0,0, \
1,1,1 \
}
@@ -693,11 +700,15 @@ extern char * structure_size_string;
#define CALL_USED_REGISTERS \
{ \
1,1,1,1,0,0,0,0, \
- 0,0,1,1,1,1,1,1, \
+ 0,0,0,1,1,1,1,1, \
1,1,1,1,0,0,0,0, \
1,1,1 \
}
+#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE
+#endif
+
/* If doing stupid life analysis, avoid a bug causing a return value r0 to be
trampled. This effectively reduces the number of available registers by 1.
XXX It is a hack, I know.
@@ -717,11 +728,12 @@ extern char * structure_size_string;
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; \
} \
- else if (! TARGET_APCS_STACK) \
+ else if (TARGET_APCS_STACK) \
{ \
- fixed_regs[10] = 0; \
- call_used_regs[10] = 0; \
+ fixed_regs[10] = 1; \
+ call_used_regs[10] = 1; \
} \
+ SUBTARGET_CONDITIONAL_REGISTER_USAGE \
}
/* Return number of consecutive hard regs needed starting at reg REGNO
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index a87932e..23dcbcd 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2167,20 +2167,20 @@
""
"
{
- if (GET_CODE (operands[1]) == MEM)
+ if (arm_arch4 && GET_CODE (operands[1]) == MEM)
+ {
+ /* Note: We do not have to worry about TARGET_SHORT_BY_BYTES
+ here because the insn below will generate an LDRH instruction
+ rather than an LDR instruction, so we cannot get an unaligned
+ word access. */
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_ZERO_EXTEND (SImode, operands[1])));
+ DONE;
+ }
+ if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
{
- if (TARGET_SHORT_BY_BYTES)
- {
- emit_insn (gen_movhi_bytes (operands[0], operands[1]));
- DONE;
- }
- else if (arm_arch4)
- {
- emit_insn (gen_rtx_SET (VOIDmode,
- operands[0],
- gen_rtx_ZERO_EXTEND (SImode, operands[1])));
- DONE;
- }
+ emit_insn (gen_movhi_bytes (operands[0], operands[1]));
+ DONE;
}
if (! s_register_operand (operands[1], HImode))
operands[1] = copy_to_mode_reg (HImode, operands[1]);
@@ -2273,20 +2273,22 @@
""
"
{
- if (GET_CODE (operands[1]) == MEM)
+ if (arm_arch4 && GET_CODE (operands[1]) == MEM)
{
- if (TARGET_SHORT_BY_BYTES)
- {
- emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
- DONE;
- }
- else if (arm_arch4)
- {
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_SIGN_EXTEND (SImode, operands[1])));
- DONE;
- }
- }
+ /* Note: We do not have to worry about TARGET_SHORT_BY_BYTES
+ here because the insn below will generate an LDRH instruction
+ rather than an LDR instruction, so we cannot get an unaligned
+ word access. */
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_SIGN_EXTEND (SImode, operands[1])));
+ DONE;
+ }
+
+ if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
+ {
+ emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
+ DONE;
+ }
if (! s_register_operand (operands[1], HImode))
operands[1] = copy_to_mode_reg (HImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
@@ -2894,6 +2896,10 @@
}
else if (! arm_arch4)
{
+ /* Note: We do not have to worry about TARGET_SHORT_BY_BYTES
+ for v4 and up architectures because LDRH instructions will
+ be used to access the HI values, and these cannot generate
+ unaligned word access faults in the MMU. */
if (GET_CODE (operands[1]) == MEM)
{
if (TARGET_SHORT_BY_BYTES)
diff --git a/gcc/config/arm/riscix.h b/gcc/config/arm/riscix.h
index 5ccb213..7c5f1ce 100644
--- a/gcc/config/arm/riscix.h
+++ b/gcc/config/arm/riscix.h
@@ -120,6 +120,11 @@ Boston, MA 02111-1307, USA. */
/* Override the normal default CPU */
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm2
+/* r10 is reserved by RISCiX */
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
+ fixed_regs[10] = 1; \
+ call_used_regs[10] = 1;
+
#include "arm/aout.h"
/* The RISCiX assembler does not understand .set */
diff --git a/gcc/config/arm/riscix1-1.h b/gcc/config/arm/riscix1-1.h
index 3718635..7311067 100644
--- a/gcc/config/arm/riscix1-1.h
+++ b/gcc/config/arm/riscix1-1.h
@@ -80,6 +80,12 @@ Boston, MA 02111-1307, USA. */
/* Override the normal default CPU */
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm2
+/* r10 is reserved by RISCiX */
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
+ fixed_regs[10] = 1; \
+ call_used_regs[10] = 1;
+
+
#include "arm/aout.h"
#undef CPP_SPEC