aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2001-01-08 15:33:06 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2001-01-08 15:33:06 +0000
commitb15bca310fdefc699d81f7800253b71a795166cf (patch)
tree8fdd1745cb42de0b76eac3ae4edfe74943f9c6f8
parent261efdefd067fbb10979f662f9fe0a3da986d2b5 (diff)
downloadgcc-b15bca310fdefc699d81f7800253b71a795166cf.zip
gcc-b15bca310fdefc699d81f7800253b71a795166cf.tar.gz
gcc-b15bca310fdefc699d81f7800253b71a795166cf.tar.bz2
arm.c (arm_arch5e): New variable.
* arm.c (arm_arch5e): New variable. (all_cores): XScale is a 5TE device. (arm_override_options): Set arm_arch5e. (arm_init_builtins): __builtin_prefetch is in arch5e. * arm.h (arm_arch5e): Declare it. * arm.h (PREDICATE_CODES): Add arm_hard_register_operand. * arm.md (define_constants): Add defines for UNSPEC and UNSPEC_VOLATILE insns. Update all users. (define_constants): Add constants for IP_REGNUM, SP_REGNUM, PC_REGNUM. * arm.c (multi_register_push, note_invalid_constants) (emit_multi_reg_push, emit_sfm, expand_prologue): Use constants. * arm.h (SP_REGNUM, IP_REGNUM, PC_REGNUM): Delete defines. (STACK_POINTER_REGNUM): Define in terms of SP_REGNUM. From-SVN: r38803
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/config/arm/arm.c25
-rw-r--r--gcc/config/arm/arm.h29
-rw-r--r--gcc/config/arm/arm.md185
4 files changed, 173 insertions, 84 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 721b1c7..363513a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2001-01-08 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_arch5e): New variable.
+ (all_cores): XScale is a 5TE device.
+ (arm_override_options): Set arm_arch5e.
+ (arm_init_builtins): __builtin_prefetch is in arch5e.
+ * arm.h (arm_arch5e): Declare it.
+
+ * arm.h (PREDICATE_CODES): Add arm_hard_register_operand.
+
+ * arm.md (define_constants): Add defines for UNSPEC and
+ UNSPEC_VOLATILE insns. Update all users.
+ (define_constants): Add constants for IP_REGNUM, SP_REGNUM, PC_REGNUM.
+ * arm.c (multi_register_push, note_invalid_constants)
+ (emit_multi_reg_push, emit_sfm, expand_prologue): Use constants.
+ * arm.h (SP_REGNUM, IP_REGNUM, PC_REGNUM): Delete defines.
+ (STACK_POINTER_REGNUM): Define in terms of SP_REGNUM.
+
Mon Jan 8 16:14:56 MET 2001 Jan Hubicka <jh@suse.cz>
* jump.c (jump_optimize_1): Use reversed_comparison_code
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 16479d4..5401773 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -151,7 +151,7 @@ int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
#define FL_THUMB (1 << 6) /* Thumb aware */
#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */
#define FL_STRONG (1 << 8) /* StrongARM */
-#define FL_ARCH5E (1 << 9) /* El Segundo extenstions to v5 */
+#define FL_ARCH5E (1 << 9) /* DSP extenstions to v5 */
#define FL_XSCALE (1 << 10) /* XScale */
/* The bits in this mask specify which instructions we are
@@ -176,6 +176,9 @@ int arm_arch4 = 0;
/* Nonzero if this chip supports the ARM Architecture 5 extensions. */
int arm_arch5 = 0;
+/* Nonzero if this chip supports the ARM Architecture 5E extensions. */
+int arm_arch5e = 0;
+
/* Nonzero if this chip can benefit from load scheduling. */
int arm_ld_sched = 0;
@@ -279,7 +282,7 @@ static struct processors all_cores[] =
{"strongarm", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm1100", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
- {"xscale", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_ARCH5 },
+ {"xscale", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_ARCH5 | FL_ARCH5E },
{NULL, 0}
};
@@ -586,6 +589,7 @@ arm_override_options ()
arm_fast_multiply = (insn_flags & FL_FAST_MULT) != 0;
arm_arch4 = (insn_flags & FL_ARCH4) != 0;
arm_arch5 = (insn_flags & FL_ARCH5) != 0;
+ arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
arm_is_xscale = (insn_flags & FL_XSCALE) != 0;
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
@@ -4054,7 +4058,7 @@ multi_register_push (op, mode)
if (GET_CODE (op) != PARALLEL
|| (GET_CODE (XVECEXP (op, 0, 0)) != SET)
|| (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
- || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != 2))
+ || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
return 0;
return 1;
@@ -5888,7 +5892,7 @@ note_invalid_constants (insn, address)
this shouldn't be needed any more. */
#ifndef AOF_ASSEMBLER
/* XXX Is this still needed? */
- else if (GET_CODE (op) == UNSPEC && XINT (op, 1) == 3)
+ else if (GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_PIC_SYM)
push_minipool_fix (insn, address, recog_data.operand_loc[opno],
recog_data.operand_mode[opno],
XVECEXP (op, 0, 0));
@@ -7593,7 +7597,8 @@ emit_multi_reg_push (mask)
something like this:
(parallel [
- (set (mem:BLK (pre_dec:BLK (reg:SI sp))) (unspec:BLK [(reg:SI r4)] 2))
+ (set (mem:BLK (pre_dec:BLK (reg:SI sp)))
+ (unspec:BLK [(reg:SI r4)] UNSPEC_PUSH_MULT))
(use (reg:SI 11 fp))
(use (reg:SI 12 ip))
(use (reg:SI 14 lr))
@@ -7708,7 +7713,7 @@ emit_sfm (base_reg, count)
gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
gen_rtx_UNSPEC (BLKmode,
gen_rtvec (1, reg),
- 2));
+ UNSPEC_PUSH_MULT));
tmp
= gen_rtx_SET (VOIDmode,
gen_rtx_MEM (XFmode,
@@ -7941,7 +7946,8 @@ arm_expand_prologue ()
{
rtx unspec = gen_rtx_UNSPEC (SImode,
gen_rtvec (2, stack_pointer_rtx,
- hard_frame_pointer_rtx), 4);
+ hard_frame_pointer_rtx),
+ UNSPEC_PRLG_STK);
insn = emit_insn (gen_rtx_CLOBBER (VOIDmode,
gen_rtx_MEM (BLKmode, unspec)));
@@ -8801,6 +8807,11 @@ arm_init_builtins ()
if (arm_arch5)
{
def_builtin ("__builtin_clz", int_ftype_int, ARM_BUILTIN_CLZ);
+ }
+
+ /* Initialize arm V5E builtins. */
+ if (arm_arch5e)
+ {
def_builtin ("__builtin_prefetch", void_ftype_pchar,
ARM_BUILTIN_PREFETCH);
}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 2701e24..c1abdb2 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -561,6 +561,9 @@ extern int arm_arch4;
/* Nonzero if this chip supports the ARM Architecture 5 extensions */
extern int arm_arch5;
+/* Nonzero if this chip supports the ARM Architecture 5E extensions */
+extern int arm_arch5e;
+
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
@@ -931,32 +934,21 @@ extern const char * structure_size_string;
pointer. */
#define ARM_HARD_FRAME_POINTER_REGNUM 11
#define THUMB_HARD_FRAME_POINTER_REGNUM 7
-#define HARD_FRAME_POINTER_REGNUM (TARGET_ARM ? ARM_HARD_FRAME_POINTER_REGNUM : THUMB_HARD_FRAME_POINTER_REGNUM)
-#define FP_REGNUM HARD_FRAME_POINTER_REGNUM
-
-/* Scratch register - used in all kinds of places, eg trampolines. */
-#define IP_REGNUM 12
-
-/* Register to use for pushing function arguments. */
-#define STACK_POINTER_REGNUM 13
-#define SP_REGNUM STACK_POINTER_REGNUM
-/* Register which holds return address from a subroutine call. */
-#define LR_REGNUM 14
+#define HARD_FRAME_POINTER_REGNUM \
+ (TARGET_ARM \
+ ? ARM_HARD_FRAME_POINTER_REGNUM \
+ : THUMB_HARD_FRAME_POINTER_REGNUM)
-/* Define this if the program counter is overloaded on a register. */
-#define PC_REGNUM 15
+#define FP_REGNUM HARD_FRAME_POINTER_REGNUM
-/* The number of the last ARM (integer) register. */
-#define LAST_ARM_REGNUM 15
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM SP_REGNUM
/* ARM floating pointer registers. */
#define FIRST_ARM_FP_REGNUM 16
#define LAST_ARM_FP_REGNUM 23
-/* Internal, so that we don't need to refer to a raw number */
-#define CC_REGNUM 24
-
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 25
@@ -2949,6 +2941,7 @@ extern int making_const_table;
/* Define the codes that are matched by predicates in arm.c */
#define PREDICATE_CODES \
{"s_register_operand", {SUBREG, REG}}, \
+ {"arm_hard_register_operand", {REG}}, \
{"f_register_operand", {SUBREG, REG}}, \
{"arm_add_operand", {SUBREG, REG, CONST_INT}}, \
{"fpu_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index d391dae..139257c 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -28,31 +28,72 @@
;; Unfortunately RISC iX doesn't work well with these so they are disabled.
;; (See arm.h)
+;;---------------------------------------------------------------------------
+;; Constants
+
+;; Register numbers
+(define_constants
+ [(IP_REGNUM 12) ; Scratch register
+ (SP_REGNUM 13) ; Stack pointer
+ (LR_REGNUM 14) ; Return address register
+ (PC_REGNUM 15) ; Program counter
+ (CC_REGNUM 24) ; Condition code pseudo register
+ (LAST_ARM_REGNUM 15)
+ ]
+)
+
;; UNSPEC Usage:
-;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter,
-;; the mode is MODE_FLOAT
-;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter,
-;; the mode is MODE_FLOAT
-;; 2 `push multiple' operation: operand 0 is the first register. Subsequent
-;; registers are in parallel (use...) expressions.
-;; 3 A symbol that has been treated properly for pic usage, that is, we
-;; will add the pic_register value to it before trying to dereference it.
;; Note: sin and cos are no-longer used.
-;;
+
+(define_constants
+ [(UNSPEC_SIN 0) ; `sin' operation (MODE_FLOAT):
+ ; operand 0 is the result,
+ ; operand 1 the parameter.
+ (UNPSEC_COS 1) ; `cos' operation (MODE_FLOAT):
+ ; operand 0 is the result,
+ ; operand 1 the parameter.
+ (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
+ ; operand 0 is the first register,
+ ; subsequent registers are in parallel (use ...)
+ ; expressions.
+ (UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic
+ ; usage, that is, we will add the pic_register
+ ; value to it before trying to dereference it.
+ (UNSPEC_PRLG_STK 4) ; A special barrier that prevents frame accesses
+ ; being scheduled before the stack adjustment insn.
+ (UNSPEC_CLZ 5) ; `clz' instruction, count leading zeros (SImode):
+ ; operand 0 is the result,
+ ; operand 1 is the parameter.
+ ]
+)
+
;; UNSPEC_VOLATILE Usage:
-;; 0 `blockage' insn to prevent scheduling across an insn in the code.
-;; 1 `epilogue' insn, used to represent any part of the instruction epilogue
-;; sequence that isn't expanded into normal RTL. Used for both normal
-;; and sibcall epilogues.
-;; 2 `align' insn. Used at the head of a minipool table for inlined
-;; constants.
-;; 3 `end-of-table'. Used to mark the end of a minipool table.
-;; 4 `pool-entry(1)'. An entry in the constant pool for an 8-bit object.
-;; 5 `pool-entry(2)'. An entry in the constant pool for a 16-bit object.
-;; 6 `pool-entry(4)'. An entry in the constant pool for a 32-bit object.
-;; 7 `pool-entry(8)'. An entry in the constant pool for a 64-bit object.
-;;
+
+(define_constants
+ [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
+ ; insn in the code.
+ (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
+ ; instruction epilogue sequence that isn't expanded
+ ; into normal RTL. Used for both normal and sibcall
+ ; epilogues.
+ (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table
+ ; for inlined constants.
+ (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool
+ ; table.
+ (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for
+ ; an 8-bit object.
+ (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for
+ ; a 16-bit object.
+ (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for
+ ; a 32-bit object.
+ (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
+ ; a 64-bit object.
+ (VUNSPEC_PREFETCH 8) ; `pld' insn to prefetch a cache line:
+ ; operand 0 is the address to fetch.
+ ]
+)
+;;---------------------------------------------------------------------------
;; Attributes
; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
@@ -345,14 +386,8 @@
(eq_attr "type" "!mult,load,store1,store2,store3,store4")) 32 32)
;;---------------------------------------------------------------------------
-;; Make code more maintainable by using names for fixed registers.
-
-(define_constants
- [(LR_REGNUM 14)
- (LAST_ARM_REGNUM 15)
- (CC_REGNUM 24)]
-)
-
+;; Insn patterns
+;;
;; Addition insns.
;; Note: For DImode insns, there is normally no reason why operands should
@@ -2869,14 +2904,16 @@
;; to always call a library function.
;(define_insn "sinsf2"
; [(set (match_operand:SF 0 "s_register_operand" "=f")
-; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
+; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")]
+; UNSPEC_SIN))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "sin%?s\\t%0, %1"
;[(set_attr "type" "float_em")])
;
;(define_insn "sindf2"
; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
+; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")]
+; UNSPEC_SIN))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "sin%?d\\t%0, %1"
;[(set_attr "type" "float_em")])
@@ -2884,28 +2921,32 @@
;(define_insn "*sindf_esfdf"
; [(set (match_operand:DF 0 "s_register_operand" "=f")
; (unspec:DF [(float_extend:DF
-; (match_operand:SF 1 "s_register_operand" "f"))] 0))]
+; (match_operand:SF 1 "s_register_operand" "f"))]
+; UNSPEC_SIN))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "sin%?d\\t%0, %1"
;[(set_attr "type" "float_em")])
;
;(define_insn "sinxf2"
; [(set (match_operand:XF 0 "s_register_operand" "=f")
-; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
+; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")]
+; UNSPEC_SIN))]
; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
; "sin%?e\\t%0, %1"
;[(set_attr "type" "float_em")])
;
;(define_insn "cossf2"
; [(set (match_operand:SF 0 "s_register_operand" "=f")
-; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
+; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")]
+; UNSPEC_COS))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "cos%?s\\t%0, %1"
;[(set_attr "type" "float_em")])
;
;(define_insn "cosdf2"
; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
+; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")]
+; UNSPEC_COS))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "cos%?d\\t%0, %1"
;[(set_attr "type" "float_em")])
@@ -2913,14 +2954,16 @@
;(define_insn "*cosdf_esfdf"
; [(set (match_operand:DF 0 "s_register_operand" "=f")
; (unspec:DF [(float_extend:DF
-; (match_operand:SF 1 "s_register_operand" "f"))] 1))]
+; (match_operand:SF 1 "s_register_operand" "f"))]
+; UNSPEC_COS))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "cos%?d\\t%0, %1"
;[(set_attr "type" "float_em")])
;
;(define_insn "cosxf2"
; [(set (match_operand:XF 0 "s_register_operand" "=f")
-; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
+; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")]
+; UNSEPC_COS))]
; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
; "cos%?e\\t%0, %1"
;[(set_attr "type" "float_em")])
@@ -4119,7 +4162,7 @@
(define_insn "pic_load_addr_arm"
[(set (match_operand:SI 0 "s_register_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "" "mX")] 3))]
+ (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
"TARGET_ARM && flag_pic"
"ldr%?\\t%0, %1"
[(set_attr "type" "load")
@@ -4129,7 +4172,7 @@
(define_insn "pic_load_addr_thumb"
[(set (match_operand:SI 0 "s_register_operand" "=l")
- (unspec:SI [(match_operand:SI 1 "" "mX")] 3))]
+ (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
"TARGET_THUMB && flag_pic"
"ldr\\t%0, %1"
[(set_attr "type" "load")
@@ -4140,7 +4183,7 @@
;; pic register in the rtl.
(define_expand "pic_load_addr_based"
[(set (match_operand:SI 0 "s_register_operand" "=r")
- (unspec:SI [(match_operand 1 "" "") (match_dup 2)] 3))]
+ (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
"TARGET_ARM && flag_pic"
"operands[2] = pic_offset_table_rtx;"
)
@@ -4148,7 +4191,8 @@
(define_insn "*pic_load_addr_based_insn"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec:SI [(match_operand 1 "" "")
- (match_operand 2 "s_register_operand" "r")] 3))]
+ (match_operand 2 "s_register_operand" "r")]
+ UNSPEC_PIC_SYM))]
"TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
"*
#ifdef AOF_ASSEMBLER
@@ -6671,7 +6715,7 @@
;; all of memory. This blocks insns from being moved across this point.
(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
"TARGET_EITHER"
""
[(set_attr "length" "0")
@@ -8600,7 +8644,7 @@
)
(define_expand "epilogue"
- [(unspec_volatile [(return)] 1)]
+ [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
"TARGET_EITHER"
"
if (TARGET_THUMB)
@@ -8613,13 +8657,13 @@
emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
gen_rtvec (1,
gen_rtx_RETURN (VOIDmode)),
- 1));
+ VUNSPEC_EPILOGUE));
DONE;
"
)
(define_insn "sibcall_epilogue"
- [(unspec_volatile [(const_int 0)] 1)]
+ [(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)]
"TARGET_ARM"
"*
output_asm_insn (\"%@ Sibcall epilogue\", operands);
@@ -8633,7 +8677,7 @@
)
(define_insn "*epilogue_insns"
- [(unspec_volatile [(return)] 1)]
+ [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
"TARGET_EITHER"
"*
if (TARGET_ARM)
@@ -8838,7 +8882,8 @@
(define_insn "*push_multi"
[(match_parallel 2 "multi_register_push"
[(set (match_operand:BLK 0 "memory_operand" "=m")
- (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
+ (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
+ UNSPEC_PUSH_MULT))])]
"TARGET_ARM"
"*
{
@@ -8875,7 +8920,8 @@
(define_insn "*push_fp_multi"
[(match_parallel 2 "multi_register_push"
[(set (match_operand:BLK 0 "memory_operand" "=m")
- (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")] 2))])]
+ (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
+ UNSPEC_PUSH_MULT))])]
"TARGET_ARM"
"*
{
@@ -8891,7 +8937,7 @@
;; Special patterns for dealing with the constant pool
(define_insn "align_4"
- [(unspec_volatile [(const_int 0)] 2)]
+ [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
"TARGET_EITHER"
"*
assemble_align (32);
@@ -8900,7 +8946,7 @@
)
(define_insn "consttable_end"
- [(unspec_volatile [(const_int 0)] 3)]
+ [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
"TARGET_EITHER"
"*
making_const_table = FALSE;
@@ -8909,7 +8955,7 @@
)
(define_insn "consttable_1"
- [(unspec_volatile [(match_operand 0 "" "")] 4)]
+ [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
"TARGET_THUMB"
"*
making_const_table = TRUE;
@@ -8921,7 +8967,7 @@
)
(define_insn "consttable_2"
- [(unspec_volatile [(match_operand 0 "" "")] 5)]
+ [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
"TARGET_THUMB"
"*
making_const_table = TRUE;
@@ -8933,7 +8979,7 @@
)
(define_insn "consttable_4"
- [(unspec_volatile [(match_operand 0 "" "")] 6)]
+ [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
"TARGET_EITHER"
"*
{
@@ -8957,7 +9003,7 @@
)
(define_insn "consttable_8"
- [(unspec_volatile [(match_operand 0 "" "")] 7)]
+ [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
"TARGET_EITHER"
"*
{
@@ -8994,16 +9040,37 @@
(define_insn "clz"
[(set (match_operand:SI 0 "s_register_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] 128))]
- "TARGET_ARM"
+ (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")]
+ UNSPEC_CLZ))]
+ "TARGET_ARM && arm_arch5"
"clz\\t%0, %1")
-;; XScale instructions.
+(define_expand "ffssi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_ARM && arm_arch5"
+ "
+ {
+ rtx t1, t2, t3;
+
+ t1 = gen_reg_rtx (SImode);
+ t2 = gen_reg_rtx (SImode);
+ t3 = gen_reg_rtx (SImode);
+
+ emit_insn (gen_negsi2 (t1, operands[1]));
+ emit_insn (gen_andsi3 (t2, operands[1], t1));
+ emit_insn (gen_clz (t3, t2));
+ emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
+ DONE;
+ }"
+)
+
+;; V5E instructions.
(define_insn "prefetch"
[(unspec_volatile
- [(match_operand:SI 0 "offsettable_memory_operand" "o")] 129)]
- "TARGET_ARM"
+ [(match_operand:SI 0 "offsettable_memory_operand" "o")] VUNSPEC_PREFETCH)]
+ "TARGET_ARM && arm_arch5e"
"pld\\t%0")
;; General predication pattern