From b15bca310fdefc699d81f7800253b71a795166cf Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Mon, 8 Jan 2001 15:33:06 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 18 ++++ gcc/config/arm/arm.c | 25 ++++-- gcc/config/arm/arm.h | 29 +++---- gcc/config/arm/arm.md | 185 ++++++++++++++++++++++++++++-------------- 4 files changed, 173 insertions(+), 84 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 721b1c7097f..363513ad6ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2001-01-08 Richard Earnshaw + + * 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 * jump.c (jump_optimize_1): Use reversed_comparison_code diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 16479d4fba7..54017732889 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 2701e24ce46..c1abdb2c31c 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 d391dae6f6b..139257c4276 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 -- 2.30.2