dslinux/toolchain/8bit 101-arm-swp.patch
amadeus
dslinux_amadeus at user.in-berlin.de
Sun Oct 29 15:26:10 CET 2006
Update of /cvsroot/dslinux/dslinux/toolchain/8bit
In directory antilope:/tmp/cvs-serv31292/toolchain/8bit
Added Files:
101-arm-swp.patch
Log Message:
swp as patch, save for later use
--- NEW FILE: 101-arm-swp.patch ---
diff -uprN gcc-4.0.2-101/gcc/config/arm/arm.h gcc-4.0.2/gcc/config/arm/arm.h
--- gcc-4.0.2-101/gcc/config/arm/arm.h 2005-08-25 12:37:19.000000000 +0200
+++ gcc-4.0.2/gcc/config/arm/arm.h 2006-10-29 14:36:23.000000000 +0100
@@ -214,7 +214,11 @@ extern GTY(()) rtx aof_pic_label;
#define ARM_FLAG_APCS_REENT (1 << 6)
/* FLAG 0x0080 now spare (used to be alignment traps). */
- /* FLAG (1 << 8) is now spare (used to be soft-float). */
+
+/* Nonzero if swpb instructions should be generated instead of strb.
+ This allows to generate code for 16bit busses without byte write strobes,
+ if the ARM9 writeback cache is enabled. (Nintendo DS). */
+#define ARM_FLAG_SWP_BYTE_WRITES (1 << 8)
/* Nonzero if we should compile with BYTES_BIG_ENDIAN set to 1. */
#define ARM_FLAG_BIG_END (1 << 9)
@@ -267,6 +271,7 @@ extern GTY(()) rtx aof_pic_label;
#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)
+#define TARGET_SWP_BYTE_WRITES (target_flags & ARM_FLAG_SWP_BYTE_WRITES)
#define TARGET_SOFT_FLOAT (arm_float_abi == ARM_FLOAT_ABI_SOFT)
/* Use hardware floating point instructions. */
#define TARGET_HARD_FLOAT (arm_float_abi != ARM_FLOAT_ABI_SOFT)
@@ -329,6 +334,9 @@ extern GTY(()) rtx aof_pic_label;
{"apcs-reentrant", ARM_FLAG_APCS_REENT, \
N_("Generate re-entrant, PIC code") }, \
{"no-apcs-reentrant", -ARM_FLAG_APCS_REENT, "" }, \
+ {"swp-byte-writes", ARM_FLAG_SWP_BYTE_WRITES, \
+ N_("Use swpb instead of strb for 8 bit writes") }, \
+ {"no-swp-byte-writes", -ARM_FLAG_SWP_BYTE_WRITES, "" }, \
{"big-endian", ARM_FLAG_BIG_END, \
N_("Assume target CPU is configured as big endian") }, \
{"little-endian", -ARM_FLAG_BIG_END, \
@@ -1389,6 +1397,8 @@ enum reg_class
? vfp_secondary_reload_class (MODE, X) \
: TARGET_ARM \
? (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \
+ || ((MODE) == QImode && TARGET_ARM && TARGET_SWP_BYTE_WRITES \
+ && true_regnum (X) == -1) \
? GENERAL_REGS : NO_REGS) \
: THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X))
@@ -2493,12 +2503,14 @@ extern int making_const_table;
: 0))))
/* Output the address of an operand. */
+/* SWP_BYTE_WRITES: for REG operands, use [REG] instead of [REG,#0].
+ This is also applicable for swp */
#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \
{ \
int is_minus = GET_CODE (X) == MINUS; \
\
if (GET_CODE (X) == REG) \
- asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \
+ asm_fprintf (STREAM, "[%r]", REGNO (X)); \
else if (GET_CODE (X) == PLUS || is_minus) \
{ \
rtx base = XEXP (X, 0); \
diff -uprN gcc-4.0.2-101/gcc/config/arm/arm.md gcc-4.0.2/gcc/config/arm/arm.md
--- gcc-4.0.2-101/gcc/config/arm/arm.md 2005-08-25 12:37:19.000000000 +0200
+++ gcc-4.0.2/gcc/config/arm/arm.md 2006-08-22 17:07:06.000000000 +0200
@@ -4931,7 +4931,7 @@
"@
mov%?\\t%0, %1\\t%@ movhi
mvn%?\\t%0, #%B1\\t%@ movhi
- str%?h\\t%1, %0\\t%@ movhi
+ str%?h\\t%1, %0\\t%@ movhi
ldr%?h\\t%0, %1\\t%@ movhi"
[(set_attr "type" "*,*,store1,load1")
(set_attr "predicable" "yes")
@@ -5013,7 +5013,17 @@
operands[1] = gen_lowpart (QImode, reg);
}
if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (QImode, operands[1]);
+ operands[1] = force_reg (QImode, operands[1]);
+ if (TARGET_SWP_BYTE_WRITES)
+ {
+ /* Ensure that operands[0] is (mem(reg ...)) if a memory operand. */
+ if (MEM_P (operands[0]) && !REG_P (XEXP(operands[0], 0)))
+ operands[0]
+ = replace_equiv_address(operands[0],
+ copy_to_reg (XEXP (operands[0], 0)));
+ emit_insn (gen__arm_movqi_insn_swp(operands[0], operands[1]));
+ DONE;
+ }
}
}
else /* TARGET_THUMB */
@@ -5061,11 +5071,11 @@
"
)
-
+;; Original arm movqi pattern
(define_insn "*arm_movqi_insn"
[(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
(match_operand:QI 1 "general_operand" "rI,K,m,r"))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& ( register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode))"
"@
@@ -5077,6 +5087,89 @@
(set_attr "predicable" "yes")]
)
+;; This is primarily a hack for the Nintendo DS external RAM.
+(define_insn "_arm_movqi_insn_swp"
+ [(set (match_operand:QI 0 "reg_or_Qmem_operand" "=r,r,r,Q,Q")
+ (match_operand:QI 1 "general_operand" "rI,K,m,r,r"))
+ (clobber (match_scratch:QI 2 "=X,X,X,&r,1"))]
+ "TARGET_ARM && TARGET_SWP_BYTE_WRITES
+ && ( register_operand (operands[0], QImode)
+ || register_operand (operands[1], QImode))"
+ "@
+ mov%?\\t%0, %1
+ mvn%?\\t%0, #%B1
+ ldr%?b\\t%0, %1
+ swp%?b\\t%2, %1, %0
+ swp%?b\\t%1, %1, %0"
+ [(set_attr "type" "*,*,load1,store1,store1")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "_arm_movqi_insn_noswp"
+ [(set (match_operand:QI 0 "register_operand" "=r,r,r")
+ (match_operand:QI 1 "general_operand" "rI,K,m"))]
+ "TARGET_ARM && TARGET_SWP_BYTE_WRITES
+ && ( register_operand (operands[0], QImode))"
+ "@
+ mov%?\\t%0, %1
+ mvn%?\\t%0, #%B1
+ ldr%?b\\t%0, %1"
+ [(set_attr "type" "*,*,load1")
+ (set_attr "predicable" "yes")]
+)
+
+;; The earlyclobber is required by default_secondary_reload() in targhooks.c.
+;; We may be asked to generate reg->stack moves from what was reg->reg moves.
+;; This requires both a QImode scratch register to trash and a SImode scratch
+;; register to hold the address. Since we can get only one scratch register,
+;; we ask for a DImode scratch register and split it up.
+(define_expand "reload_outqi"
+ [(clobber (match_operand:QI 0 "memory_operand" "=Q"))
+ (clobber (match_operand:DI 2 "register_operand" "=&r"))
+ (set (match_dup 4) (match_dup 5))
+ (parallel [
+ (set (match_dup 6)
+ (match_operand:QI 1 "register_operand" "r"))
+ (clobber (match_dup 3))]
+ )]
+ "TARGET_ARM && TARGET_SWP_BYTE_WRITES"
+{
+ operands[3] = gen_rtx_REG (QImode, REGNO (operands[2]));
+ /* operands[3] = simplify_gen_subreg (QImode, operands[2], DImode, 0); */
+ operands[4] = simplify_gen_subreg (Pmode, operands[2], DImode, 4);
+ /* If necessary, reload the address. */
+ if (REG_P (XEXP (operands[0], 0)))
+ {
+ operands[5] = operands[4];
+ operands[6] = operands[0];
+ }
+ else
+ {
+ operands[5] = XEXP (operands[0], 0);
+ operands[6] = gen_rtx_MEM (QImode, operands[4]);
+ }
+})
+
+;; The register allocator is often stupid. Try to change
+;; mov r2, r1
+;; swpb r2, r2, [r0]
+;; into
+;; swpb r2, r1, [r0]
+;; (and pretend it is just another way of allocating a scratch register).
+(define_peephole2
+ [(parallel
+ [(set (match_operand:QI 2 "register_operand")
+ (match_operand:QI 1 "register_operand"))
+ (clobber (match_scratch:QI 3))])
+ (parallel [
+ (set (match_operand:QI 0 "memory_operand") (match_dup 2))
+ (clobber (match_dup 2))])]
+ "TARGET_ARM && TARGET_SWP_BYTE_WRITES"
+ [(parallel
+ [(set (match_dup 0) (match_dup 1))
+ (clobber (match_dup 2))])]
+)
+
(define_insn "*thumb_movqi_insn"
[(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
(match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
@@ -9406,7 +9499,7 @@
(match_operand:QI 3 "s_register_operand" "r"))
(set (match_operand:SI 0 "s_register_operand" "=r")
(plus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& (GET_CODE (operands[2]) != REG
@@ -9422,7 +9515,7 @@
(match_operand:QI 3 "s_register_operand" "r"))
(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (match_dup 1) (match_dup 2)))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& (GET_CODE (operands[2]) != REG
@@ -9571,7 +9664,7 @@
(set (match_operand:SI 0 "s_register_operand" "=r")
(plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
(match_dup 1)))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
@@ -9589,7 +9682,7 @@
(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
(match_dup 4)])))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& REGNO (operands[0]) != FRAME_POINTER_REGNUM
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
@@ -9721,7 +9814,7 @@
(match_operand:QI 2 "s_register_operand" "r"))
(set (match_dup 0)
(plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& (REGNO (operands[2]) != REGNO (operands[0]))
&& (GET_CODE (operands[1]) != REG
|| (REGNO (operands[1]) != REGNO (operands[0])))"
@@ -9769,7 +9862,7 @@
(match_operand:SI 1 "index_operand" "rJ")))
(match_operand:QI 2 "s_register_operand" "r"))
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& (REGNO (operands[2]) != REGNO (operands[0]))
&& (GET_CODE (operands[1]) != REG
|| (REGNO (operands[1]) != REGNO (operands[0])))"
@@ -9784,7 +9877,7 @@
(match_operand:QI 3 "s_register_operand" "r"))
(set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
(match_dup 2)))]
- "TARGET_ARM
+ "TARGET_ARM && !TARGET_SWP_BYTE_WRITES
&& (REGNO (operands[3]) != REGNO (operands[2]))
&& (REGNO (operands[0]) != REGNO (operands[2]))"
"str%?b\\t%3, [%2, %0%S4]!"
diff -uprN gcc-4.0.2-101/gcc/config/arm/predicates.md gcc-4.0.2/gcc/config/arm/predicates.md
--- gcc-4.0.2-101/gcc/config/arm/predicates.md 2004-09-10 13:55:13.000000000 +0200
+++ gcc-4.0.2/gcc/config/arm/predicates.md 2006-08-14 19:53:45.000000000 +0200
@@ -467,4 +467,14 @@
(and (match_code "const_int")
(match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64")))
-
+;;-------------------------------------------------------------------------
+;;
+;; Nintendo DS predicates
+;;
+;; Match register operands or memory operands of the form (mem (reg ...)),
+;; as permitted by the "Q" memory constraint.
+(define_predicate "reg_or_Qmem_operand"
+ (ior (match_operand 0 "register_operand")
+ (and (match_code "mem")
+ (match_test "GET_CODE (XEXP (op, 0)) == REG")))
+)
diff -uprN gcc-4.0.2-101/gcc/config/arm/t-linux gcc-4.0.2/gcc/config/arm/t-linux
--- gcc-4.0.2-101/gcc/config/arm/t-linux 2004-05-15 14:41:35.000000000 +0200
+++ gcc-4.0.2/gcc/config/arm/t-linux 2006-10-29 14:54:22.000000000 +0100
@@ -9,7 +9,23 @@ LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3
# MULTILIB_OPTIONS = mhard-float/msoft-float
# MULTILIB_DIRNAMES = hard-float soft-float
-# EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
+# EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
# LIBGCC = stmp-multilib
# INSTALL_LIBGCC = install-multilib
+
+# This is special for the different versions of DSLINUX
+
+MULTILIB_OPTIONS = fpic/fno-pic
+MULTILIB_DIRNAMES = pic npic
+
+MULTILIB_OPTIONS += msingle-pic-base/mno-single-pic-base
+MULTILIB_DIRNAMES += sb mb
+
+MULTILIB_OPTIONS += mswp-byte-writes/mno-swp-byte-writes
+MULTILIB_DIRNAMES += swpb strb
+
+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
More information about the dslinux-commit
mailing list