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
This commit is contained in:
Richard Earnshaw 2001-01-08 15:33:06 +00:00 committed by Richard Earnshaw
parent 261efdefd0
commit b15bca310f
4 changed files with 173 additions and 84 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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 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 this if the program counter is overloaded on a register. */
#define PC_REGNUM 15
/* The number of the last ARM (integer) register. */
#define LAST_ARM_REGNUM 15
#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}}, \

View File

@ -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