summaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arm/arm.md')
-rw-r--r--gcc/config/arm/arm.md1279
1 files changed, 808 insertions, 471 deletions
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index d05c6980659..cafac0b58e4 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -145,7 +145,7 @@
; Floating Point Unit. If we only have floating point emulation, then there
; is no point in scheduling the floating point insns. (Well, for best
; performance we should try and group them together).
-(define_attr "fpu" "softfpa,fpa,fpe2,fpe3,maverick"
+(define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
(const (symbol_ref "arm_fpu_attr")))
; LENGTH of an instruction (in bytes)
@@ -167,13 +167,26 @@
(set_attr "length" "4")
(set_attr "pool_range" "250")])
+;; The instruction used to implement a particular pattern. This
+;; information is used by pipeline descriptions to provide accurate
+;; scheduling information.
+
+(define_attr "insn"
+ "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,other"
+ (const_string "other"))
+
; TYPE attribute is used to detect floating point instructions which, if
; running on a co-processor can run in parallel with other, basic instructions
; If write-buffer scheduling is enabled then it can also be used in the
; scheduling of writes.
; Classification of each insn
-; normal any data instruction that doesn't hit memory or fp regs
+; alu any alu instruction that doesn't hit memory or fp
+; regs or have a shifted source operand
+; alu_shift any data instruction that doesn't hit memory or fp
+; regs, but has a source operand shifted by a constant
+; alu_shift_reg any data instruction that doesn't hit memory or fp
+; regs, but has a source operand shifted by a register value
; mult a multiply instruction
; block blockage insn, this blocks all functional units
; float a floating point arithmetic operation (subject to expansion)
@@ -191,19 +204,27 @@
; r_mem_f the reverse of f_mem_r
; f_2_r fast transfer float to arm (no memory needed)
; r_2_f fast transfer arm to float
+; branch a branch
; call a subroutine call
-; load any load from memory
-; store1 store 1 word to memory from arm registers
+; load_byte load byte(s) from memory to arm registers
+; load1 load 1 word from memory to arm registers
+; load2 load 2 words from memory to arm registers
+; load3 load 3 words from memory to arm registers
+; load4 load 4 words from memory to arm registers
+; store store 1 word to memory from arm registers
; store2 store 2 words
; store3 store 3 words
-; store4 store 4 words
+; store4 store 4 (or more) words
; Additions for Cirrus Maverick co-processor:
; mav_farith Floating point arithmetic (4 cycle)
; mav_dmult Double multiplies (7 cycle)
;
(define_attr "type"
- "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4,mav_farith,mav_dmult"
- (const_string "normal"))
+ "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
+ (if_then_else
+ (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
+ (const_string "mult")
+ (const_string "alu")))
; Load scheduling, set from the arm_ld_sched variable
; initialized by arm_override_options()
@@ -251,7 +272,7 @@
; to stall the processor. Used with model_wbuf above.
(define_attr "write_conflict" "no,yes"
(if_then_else (eq_attr "type"
- "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
+ "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
(const_string "yes")
(const_string "no")))
@@ -259,7 +280,7 @@
; than one on the main cpu execution unit.
(define_attr "core_cycles" "single,multi"
(if_then_else (eq_attr "type"
- "normal,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
+ "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
(const_string "single")
(const_string "multi")))
@@ -267,115 +288,27 @@
;; distant label. Only applicable to Thumb code.
(define_attr "far_jump" "yes,no" (const_string "no"))
-(define_automaton "arm")
+;;---------------------------------------------------------------------------
+;; Pipeline descriptions
-;; Write buffer
-;
-; Strictly, we should model a 4-deep write buffer for ARM7xx based chips
-;
-; The write buffer on some of the arm6 processors is hard to model exactly.
-; There is room in the buffer for up to two addresses and up to eight words
-; of memory, but the two needn't be split evenly. When writing the two
-; addresses are fully pipelined. However, a read from memory that is not
-; currently in the cache will block until the writes have completed.
-; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
-; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
-; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
-; cycle to add as well.
-(define_cpu_unit "write_buf" "arm")
-
-;; Write blockage unit
-;
-; The write_blockage unit models (partially), the fact that reads will stall
-; until the write buffer empties.
-; The f_mem_r and r_mem_f could also block, but they are to the stack,
-; so we don't model them here
-(define_cpu_unit "write_blockage" "arm")
+;; Processor type. This attribute must exactly match the table in
+;; arm-cores.def.
+(define_attr "tune"
+ "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7m,arm7d,arm7dm,arm7di,arm7dmi,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7tdmi,arm710t,arm720t,arm740t,arm8,arm810,arm9,arm920,arm920t,arm940t,arm9tdmi,arm9e,ep9312,strongarm,strongarm110,strongarm1100,strongarm1110,arm10tdmi,arm1020t,arm926ejs,arm1026ejs,xscale,iwmmxt,arm1136js,arm1136jfs"
+ (const (symbol_ref "arm_tune")))
-;; Core
-;
-(define_cpu_unit "core" "arm")
-
-(define_insn_reservation "r_mem_f_wbuf" 5
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "r_mem_f"))
- "core+write_buf*3")
-
-(define_insn_reservation "store1_wbuf" 5
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store1"))
- "core+write_buf*3+write_blockage*5")
-
-(define_insn_reservation "store2_wbuf" 7
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store2"))
- "core+write_buf*4+write_blockage*7")
-
-(define_insn_reservation "store3_wbuf" 9
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store3"))
- "core+write_buf*5+write_blockage*9")
-
-(define_insn_reservation "store4_wbuf" 11
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store4"))
- "core+write_buf*6+write_blockage*11")
-
-(define_insn_reservation "store2" 3
- (and (eq_attr "model_wbuf" "no")
- (eq_attr "type" "store2"))
- "core*3")
-
-(define_insn_reservation "store3" 4
- (and (eq_attr "model_wbuf" "no")
- (eq_attr "type" "store3"))
- "core*4")
-
-(define_insn_reservation "store4" 5
- (and (eq_attr "model_wbuf" "no")
- (eq_attr "type" "store4"))
- "core*5")
-
-(define_insn_reservation "store1_ldsched" 1
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1"))
- "core")
-
-(define_insn_reservation "load_ldsched_xscale" 3
- (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
- (eq_attr "is_xscale" "yes"))
- "core")
-
-(define_insn_reservation "load_ldsched" 2
- (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
- (eq_attr "is_xscale" "no"))
- "core")
-
-(define_insn_reservation "load_or_store" 2
- (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1"))
- "core*2")
-
-(define_insn_reservation "mult" 16
- (and (eq_attr "ldsched" "no") (eq_attr "type" "mult"))
- "core*16")
-
-(define_insn_reservation "mult_ldsched_strongarm" 3
- (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
- (eq_attr "type" "mult"))
- "core*2")
-
-(define_insn_reservation "mult_ldsched" 4
- (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
- (eq_attr "type" "mult"))
- "core*4")
-
-(define_insn_reservation "multi_cycle" 32
- (and (eq_attr "core_cycles" "multi")
- (eq_attr "type" "!mult,load,store1,store2,store3,store4"))
- "core*32")
-
-(define_insn_reservation "single_cycle" 1
- (eq_attr "core_cycles" "single")
- "core")
+;; True if the generic scheduling description should be used.
+
+(define_attr "generic_sched" "yes,no"
+ (if_then_else
+ (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
+ (const_string "no")
+ (const_string "yes")))
+
+(include "arm-generic.md")
+(include "arm926ejs.md")
+(include "arm1026ejs.md")
+(include "arm1136jfs.md")
;;---------------------------------------------------------------------------
@@ -397,7 +330,7 @@
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
- if (TARGET_CIRRUS)
+ if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
{
if (!cirrus_fp_register (operands[0], DImode))
operands[0] = force_reg (DImode, operands[0]);
@@ -433,7 +366,7 @@
(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
(match_operand:DI 2 "s_register_operand" "r, 0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM && !TARGET_CIRRUS"
+ "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -461,7 +394,7 @@
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM && !TARGET_CIRRUS"
+ "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -490,7 +423,7 @@
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM && !TARGET_CIRRUS"
+ "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -801,7 +734,10 @@
(match_operand:SI 1 "s_register_operand" "r"))))]
"TARGET_ARM"
"adc%?\\t%0, %1, %3%S2"
- [(set_attr "conds" "use")]
+ [(set_attr "conds" "use")
+ (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*addsi3_carryin_alt1"
@@ -864,10 +800,10 @@
(define_expand "addsf3"
[(set (match_operand:SF 0 "s_register_operand" "")
(plus:SF (match_operand:SF 1 "s_register_operand" "")
- (match_operand:SF 2 "fpa_add_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (match_operand:SF 2 "arm_float_add_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS
+ if (TARGET_MAVERICK
&& !cirrus_fp_register (operands[2], SFmode))
operands[2] = force_reg (SFmode, operands[2]);
")
@@ -875,10 +811,10 @@
(define_expand "adddf3"
[(set (match_operand:DF 0 "s_register_operand" "")
(plus:DF (match_operand:DF 1 "s_register_operand" "")
- (match_operand:DF 2 "fpa_add_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (match_operand:DF 2 "arm_float_add_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS
+ if (TARGET_MAVERICK
&& !cirrus_fp_register (operands[2], DFmode))
operands[2] = force_reg (DFmode, operands[2]);
")
@@ -891,7 +827,7 @@
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
- if (TARGET_CIRRUS
+ if (TARGET_HARD_FLOAT && TARGET_MAVERICK
&& TARGET_ARM
&& cirrus_fp_register (operands[0], DImode)
&& cirrus_fp_register (operands[1], DImode))
@@ -1087,11 +1023,11 @@
(define_expand "subsf3"
[(set (match_operand:SF 0 "s_register_operand" "")
- (minus:SF (match_operand:SF 1 "fpa_rhs_operand" "")
- (match_operand:SF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
+ (match_operand:SF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS)
+ if (TARGET_MAVERICK)
{
if (!cirrus_fp_register (operands[1], SFmode))
operands[1] = force_reg (SFmode, operands[1]);
@@ -1102,11 +1038,11 @@
(define_expand "subdf3"
[(set (match_operand:DF 0 "s_register_operand" "")
- (minus:DF (match_operand:DF 1 "fpa_rhs_operand" "")
- (match_operand:DF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
+ (match_operand:DF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS)
+ if (TARGET_MAVERICK)
{
if (!cirrus_fp_register (operands[1], DFmode))
operands[1] = force_reg (DFmode, operands[1]);
@@ -1133,7 +1069,7 @@
(match_operand:SI 1 "s_register_operand" "%?r,0")))]
"TARGET_ARM"
"mul%?\\t%0, %2, %1"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "mul")
(set_attr "predicable" "yes")]
)
@@ -1154,7 +1090,7 @@
return \"mul\\t%0, %0, %2\";
"
[(set_attr "length" "4,4,2")
- (set_attr "type" "mult")]
+ (set_attr "insn" "mul")]
)
(define_insn "*mulsi3_compare0"
@@ -1168,7 +1104,7 @@
"TARGET_ARM && !arm_arch_xscale"
"mul%?s\\t%0, %2, %1"
[(set_attr "conds" "set")
- (set_attr "type" "mult")]
+ (set_attr "insn" "muls")]
)
(define_insn "*mulsi_compare0_scratch"
@@ -1181,7 +1117,7 @@
"TARGET_ARM && !arm_arch_xscale"
"mul%?s\\t%0, %2, %1"
[(set_attr "conds" "set")
- (set_attr "type" "mult")]
+ (set_attr "insn" "muls")]
)
;; Unnamed templates to match MLA instruction.
@@ -1194,7 +1130,7 @@
(match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
"TARGET_ARM"
"mla%?\\t%0, %2, %1, %3"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "mla")
(set_attr "predicable" "yes")]
)
@@ -1212,7 +1148,7 @@
"TARGET_ARM && !arm_arch_xscale"
"mla%?s\\t%0, %2, %1, %3"
[(set_attr "conds" "set")
- (set_attr "type" "mult")]
+ (set_attr "insn" "mlas")]
)
(define_insn "*mulsi3addsi_compare0_scratch"
@@ -1227,7 +1163,7 @@
"TARGET_ARM && !arm_arch_xscale"
"mla%?s\\t%0, %2, %1, %3"
[(set_attr "conds" "set")
- (set_attr "type" "mult")]
+ (set_attr "insn" "mlas")]
)
;; Unnamed template to match long long multiply-accumulate (smlal)
@@ -1239,9 +1175,9 @@
(sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
(sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
(match_operand:DI 1 "s_register_operand" "0")))]
- "TARGET_ARM && arm_fast_multiply"
+ "TARGET_ARM && arm_arch3m"
"smlal%?\\t%Q0, %R0, %3, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smlal")
(set_attr "predicable" "yes")]
)
@@ -1250,9 +1186,9 @@
(mult:DI
(sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
(sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
- "TARGET_ARM && arm_fast_multiply"
+ "TARGET_ARM && arm_arch3m"
"smull%?\\t%Q0, %R0, %1, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smull")
(set_attr "predicable" "yes")]
)
@@ -1261,9 +1197,9 @@
(mult:DI
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
(zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
- "TARGET_ARM && arm_fast_multiply"
+ "TARGET_ARM && arm_arch3m"
"umull%?\\t%Q0, %R0, %1, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "umull")
(set_attr "predicable" "yes")]
)
@@ -1276,9 +1212,9 @@
(zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
(zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
(match_operand:DI 1 "s_register_operand" "0")))]
- "TARGET_ARM && arm_fast_multiply"
+ "TARGET_ARM && arm_arch3m"
"umlal%?\\t%Q0, %R0, %3, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "umlal")
(set_attr "predicable" "yes")]
)
@@ -1291,9 +1227,9 @@
(sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
(const_int 32))))
(clobber (match_scratch:SI 3 "=&r,&r"))]
- "TARGET_ARM && arm_fast_multiply"
+ "TARGET_ARM && arm_arch3m"
"smull%?\\t%3, %0, %2, %1"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smull")
(set_attr "predicable" "yes")]
)
@@ -1306,9 +1242,9 @@
(zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
(const_int 32))))
(clobber (match_scratch:SI 3 "=&r,&r"))]
- "TARGET_ARM && arm_fast_multiply"
+ "TARGET_ARM && arm_arch3m"
"umull%?\\t%3, %0, %2, %1"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "umull")
(set_attr "predicable" "yes")]
)
@@ -1320,7 +1256,7 @@
(match_operand:HI 2 "s_register_operand" "r"))))]
"TARGET_ARM && arm_arch5e"
"smulbb%?\\t%0, %1, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smulxy")
(set_attr "predicable" "yes")]
)
@@ -1333,7 +1269,7 @@
(match_operand:HI 2 "s_register_operand" "r"))))]
"TARGET_ARM && arm_arch5e"
"smultb%?\\t%0, %1, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smulxy")
(set_attr "predicable" "yes")]
)
@@ -1346,7 +1282,7 @@
(const_int 16))))]
"TARGET_ARM && arm_arch5e"
"smulbt%?\\t%0, %1, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smulxy")
(set_attr "predicable" "yes")]
)
@@ -1360,7 +1296,7 @@
(const_int 16))))]
"TARGET_ARM && arm_arch5e"
"smultt%?\\t%0, %1, %2"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smulxy")
(set_attr "predicable" "yes")]
)
@@ -1373,7 +1309,7 @@
(match_operand:HI 3 "s_register_operand" "r")))))]
"TARGET_ARM && arm_arch5e"
"smlabb%?\\t%0, %2, %3, %1"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smlaxy")
(set_attr "predicable" "yes")]
)
@@ -1387,16 +1323,16 @@
(match_operand:HI 3 "s_register_operand" "r")))))]
"TARGET_ARM && arm_arch5e"
"smlalbb%?\\t%Q0, %R0, %2, %3"
- [(set_attr "type" "mult")
+ [(set_attr "insn" "smlalxy")
(set_attr "predicable" "yes")])
(define_expand "mulsf3"
[(set (match_operand:SF 0 "s_register_operand" "")
(mult:SF (match_operand:SF 1 "s_register_operand" "")
- (match_operand:SF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (match_operand:SF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS
+ if (TARGET_MAVERICK
&& !cirrus_fp_register (operands[2], SFmode))
operands[2] = force_reg (SFmode, operands[2]);
")
@@ -1404,10 +1340,10 @@
(define_expand "muldf3"
[(set (match_operand:DF 0 "s_register_operand" "")
(mult:DF (match_operand:DF 1 "s_register_operand" "")
- (match_operand:DF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (match_operand:DF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS
+ if (TARGET_MAVERICK
&& !cirrus_fp_register (operands[2], DFmode))
operands[2] = force_reg (DFmode, operands[2]);
")
@@ -1416,16 +1352,16 @@
(define_expand "divsf3"
[(set (match_operand:SF 0 "s_register_operand" "")
- (div:SF (match_operand:SF 1 "fpa_rhs_operand" "")
- (match_operand:SF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
+ (match_operand:SF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"")
(define_expand "divdf3"
[(set (match_operand:DF 0 "s_register_operand" "")
- (div:DF (match_operand:DF 1 "fpa_rhs_operand" "")
- (match_operand:DF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
+ (match_operand:DF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"")
;; Modulo insns
@@ -1433,15 +1369,15 @@
(define_expand "modsf3"
[(set (match_operand:SF 0 "s_register_operand" "")
(mod:SF (match_operand:SF 1 "s_register_operand" "")
- (match_operand:SF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ (match_operand:SF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"")
(define_expand "moddf3"
[(set (match_operand:DF 0 "s_register_operand" "")
(mod:DF (match_operand:DF 1 "s_register_operand" "")
- (match_operand:DF 2 "fpa_rhs_operand" "")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ (match_operand:DF 2 "arm_float_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"")
;; Boolean and,ior,xor insns
@@ -2048,16 +1984,18 @@
)
(define_insn "andsi_not_shiftsi_si"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (and:SI (not:SI (match_operator:SI 4 "shift_operator"
- [(match_operand:SI 2 "s_register_operand" "r")
- (match_operand:SI 3 "arm_rhs_operand" "rM")]))
- (match_operand:SI 1 "s_register_operand" "r")))]
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (and:SI (not:SI (match_operator:SI 4 "shift_operator"
+ [(match_operand:SI 2 "s_register_operand" "r")
+ (match_operand:SI 3 "arm_rhs_operand" "rM")]))
+ (match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_ARM"
"bic%?\\t%0, %1, %2%S4"
[(set_attr "predicable" "yes")
(set_attr "shift" "2")
- ]
+ (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*andsi_notsi_si_compare0"
@@ -2537,6 +2475,41 @@
;; Shift and rotation insns
+(define_expand "ashldi3"
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (ashift:DI (match_operand:DI 1 "s_register_operand" "")
+ (match_operand:SI 2 "reg_or_int_operand" "")))]
+ "TARGET_ARM"
+ "
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
+ {
+ emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
+ DONE;
+ }
+ /* Ideally we shouldn't fail here if we could know that operands[1]
+ ends up already living in an iwmmxt register. Otherwise it's
+ cheaper to have the alternate code being generated than moving
+ values to iwmmxt regs and back. */
+ FAIL;
+ }
+ else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
+ FAIL;
+ "
+)
+
+(define_insn "arm_ashldi3_1bit"
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
+ (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
+ (const_int 1)))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM"
+ "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "8")]
+)
+
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "s_register_operand" "")
(ashift:SI (match_operand:SI 1 "s_register_operand" "")
@@ -2561,6 +2534,41 @@
[(set_attr "length" "2")]
)
+(define_expand "ashrdi3"
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
+ (match_operand:SI 2 "reg_or_int_operand" "")))]
+ "TARGET_ARM"
+ "
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
+ {
+ emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
+ DONE;
+ }
+ /* Ideally we shouldn't fail here if we could know that operands[1]
+ ends up already living in an iwmmxt register. Otherwise it's
+ cheaper to have the alternate code being generated than moving
+ values to iwmmxt regs and back. */
+ FAIL;
+ }
+ else if (!TARGET_REALLY_IWMMXT)
+ FAIL;
+ "
+)
+
+(define_insn "arm_ashrdi3_1bit"
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
+ (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
+ (const_int 1)))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM"
+ "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "8")]
+)
+
(define_expand "ashrsi3"
[(set (match_operand:SI 0 "s_register_operand" "")
(ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
@@ -2582,6 +2590,41 @@
[(set_attr "length" "2")]
)
+(define_expand "lshrdi3"
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
+ (match_operand:SI 2 "reg_or_int_operand" "")))]
+ "TARGET_ARM"
+ "
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
+ {
+ emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
+ DONE;
+ }
+ /* Ideally we shouldn't fail here if we could know that operands[1]
+ ends up already living in an iwmmxt register. Otherwise it's
+ cheaper to have the alternate code being generated than moving
+ values to iwmmxt regs and back. */
+ FAIL;
+ }
+ else if (!TARGET_REALLY_IWMMXT)
+ FAIL;
+ "
+)
+
+(define_insn "arm_lshrdi3_1bit"
+ [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
+ (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
+ (const_int 1)))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM"
+ "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "8")]
+)
+
(define_expand "lshrsi3"
[(set (match_operand:SI 0 "s_register_operand" "")
(lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
@@ -2652,19 +2695,6 @@
[(set_attr "length" "2")]
)
-(define_expand "ashldi3"
- [(set (match_operand:DI 0 "s_register_operand" "")
- (ashift:DI (match_operand:DI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
- "TARGET_ARM && (TARGET_IWMMXT || TARGET_CIRRUS)"
- "
- if (! s_register_operand (operands[1], DImode))
- operands[1] = copy_to_mode_reg (DImode, operands[1]);
- if (! s_register_operand (operands[2], SImode))
- operands[2] = copy_to_mode_reg (SImode, operands[2]);
- "
-)
-
(define_insn "*arm_shiftsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(match_operator:SI 3 "shift_operator"
@@ -2674,7 +2704,9 @@
"mov%?\\t%0, %1%S3"
[(set_attr "predicable" "yes")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*shiftsi3_compare0"
@@ -2689,7 +2721,9 @@
"mov%?s\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*shiftsi3_compare0_scratch"
@@ -2702,8 +2736,7 @@
"TARGET_ARM"
"mov%?s\\t%0, %1%S3"
[(set_attr "conds" "set")
- (set_attr "shift" "1")
- ]
+ (set_attr "shift" "1")]
)
(define_insn "*notsi_shiftsi"
@@ -2715,7 +2748,9 @@
"mvn%?\\t%0, %1%S3"
[(set_attr "predicable" "yes")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*notsi_shiftsi_compare0"
@@ -2730,7 +2765,9 @@
"mvn%?s\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*not_shiftsi_compare0_scratch"
@@ -2744,7 +2781,9 @@
"mvn%?s\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
;; We don't really have extzv, but defining this using shifts helps
@@ -2841,14 +2880,14 @@
(define_expand "negsf2"
[(set (match_operand:SF 0 "s_register_operand" "")
(neg:SF (match_operand:SF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
""
)
(define_expand "negdf2"
[(set (match_operand:DF 0 "s_register_operand" "")
(neg:DF (match_operand:DF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"")
;; abssi2 doesn't really clobber the condition codes if a different register
@@ -2895,25 +2934,25 @@
(define_expand "abssf2"
[(set (match_operand:SF 0 "s_register_operand" "")
(abs:SF (match_operand:SF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"")
(define_expand "absdf2"
[(set (match_operand:DF 0 "s_register_operand" "")
(abs:DF (match_operand:DF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"")
(define_expand "sqrtsf2"
[(set (match_operand:SF 0 "s_register_operand" "")
(sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"")
(define_expand "sqrtdf2"
[(set (match_operand:DF 0 "s_register_operand" "")
(sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"")
(define_insn_and_split "one_cmpldi2"
@@ -2984,9 +3023,9 @@
(define_expand "floatsisf2"
[(set (match_operand:SF 0 "s_register_operand" "")
(float:SF (match_operand:SI 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS)
+ if (TARGET_MAVERICK)
{
emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
DONE;
@@ -2996,9 +3035,9 @@
(define_expand "floatsidf2"
[(set (match_operand:DF 0 "s_register_operand" "")
(float:DF (match_operand:SI 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS)
+ if (TARGET_MAVERICK)
{
emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
DONE;
@@ -3008,9 +3047,9 @@
(define_expand "fix_truncsfsi2"
[(set (match_operand:SI 0 "s_register_operand" "")
(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS)
+ if (TARGET_MAVERICK)
{
if (!cirrus_fp_register (operands[0], SImode))
operands[0] = force_reg (SImode, operands[0]);
@@ -3024,9 +3063,9 @@
(define_expand "fix_truncdfsi2"
[(set (match_operand:SI 0 "s_register_operand" "")
(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS)
+ if (TARGET_MAVERICK)
{
if (!cirrus_fp_register (operands[1], DFmode))
operands[1] = force_reg (DFmode, operands[0]);
@@ -3041,7 +3080,7 @@
[(set (match_operand:SF 0 "s_register_operand" "")
(float_truncate:SF
(match_operand:DF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
""
)
@@ -3070,7 +3109,7 @@
ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
- (set_attr "type" "*,load")
+ (set_attr "type" "*,load_byte")
(set_attr "pool_range" "*,4092")
(set_attr "neg_pool_range" "*,4084")]
)
@@ -3099,72 +3138,42 @@
"TARGET_EITHER"
"
{
- if (TARGET_ARM)
+ if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
{
- if (arm_arch4 && GET_CODE (operands[1]) == MEM)
- {
- /* Note: We do not have to worry about TARGET_MMU_TRAPS
- 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_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
- {
- 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]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode);
+ /* Note: We do not have to worry about TARGET_MMU_TRAPS
+ 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;
}
- else /* TARGET_THUMB */
- {
- if (GET_CODE (operands[1]) == MEM)
- {
- rtx tmp;
- tmp = gen_rtx_ZERO_EXTEND (SImode, operands[1]);
- tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
- emit_insn (tmp);
- }
- else
- {
- rtx ops[3];
-
- if (!s_register_operand (operands[1], HImode))
- operands[1] = copy_to_mode_reg (HImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode);
-
- ops[0] = operands[2];
- ops[1] = operands[1];
- ops[2] = GEN_INT (16);
-
- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
- gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
+ if (TARGET_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
+ {
+ emit_insn (gen_movhi_bytes (operands[0], operands[1]));
+ DONE;
+ }
- ops[0] = operands[0];
- ops[1] = operands[2];
- ops[2] = GEN_INT (16);
+ if (!s_register_operand (operands[1], HImode))
+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
- gen_rtx_LSHIFTRT (SImode, ops[1],
- ops[2])));
- }
- DONE;
+ if (arm_arch6)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_ZERO_EXTEND (SImode, operands[1])));
+ DONE;
}
+
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode);
}"
)
(define_insn "*thumb_zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=l")
- (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
- "TARGET_THUMB"
+ [(set (match_operand:SI 0 "register_operand" "=l")
+ (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_THUMB && !arm_arch6"
"*
rtx mem = XEXP (operands[1], 0);
@@ -3199,21 +3208,91 @@
return \"ldrh\\t%0, %1\";
"
[(set_attr "length" "4")
- (set_attr "type" "load")
+ (set_attr "type" "load_byte")
(set_attr "pool_range" "60")]
)
+(define_insn "*thumb_zero_extendhisi2_v6"
+ [(set (match_operand:SI 0 "register_operand" "=l,l")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
+ "TARGET_THUMB && arm_arch6"
+ "*
+ rtx mem;
+
+ if (which_alternative == 0)
+ return \"uxth\\t%0, %1\";
+
+ mem = XEXP (operands[1], 0);
+
+ if (GET_CODE (mem) == CONST)
+ mem = XEXP (mem, 0);
+
+ if (GET_CODE (mem) == LABEL_REF)
+ return \"ldr\\t%0, %1\";
+
+ if (GET_CODE (mem) == PLUS)
+ {
+ rtx a = XEXP (mem, 0);
+ rtx b = XEXP (mem, 1);
+
+ /* This can happen due to bugs in reload. */
+ if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
+ {
+ rtx ops[2];
+ ops[0] = operands[0];
+ ops[1] = a;
+
+ output_asm_insn (\"mov %0, %1\", ops);
+
+ XEXP (mem, 0) = operands[0];
+ }
+
+ else if ( GET_CODE (a) == LABEL_REF
+ && GET_CODE (b) == CONST_INT)
+ return \"ldr\\t%0, %1\";
+ }
+
+ return \"ldrh\\t%0, %1\";
+ "
+ [(set_attr "length" "2,4")
+ (set_attr "type" "alu_shift,load_byte")
+ (set_attr "pool_range" "*,60")]
+)
+
(define_insn "*arm_zero_extendhisi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
- "TARGET_ARM && arm_arch4"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_ARM && arm_arch4 && !arm_arch6"
"ldr%?h\\t%0, %1"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")
(set_attr "pool_range" "256")
(set_attr "neg_pool_range" "244")]
)
+(define_insn "*arm_zero_extendhisi2_v6"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_ARM && arm_arch6"
+ "@
+ uxth%?\\t%0, %1
+ ldr%?h\\t%0, %1"
+ [(set_attr "type" "alu_shift,load_byte")
+ (set_attr "predicable" "yes")
+ (set_attr "pool_range" "*,256")
+ (set_attr "neg_pool_range" "*,244")]
+)
+
+(define_insn "*arm_zero_extendhisi2addsi"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
+ (match_operand:SI 2 "s_register_operand" "r")))]
+ "TARGET_ARM && arm_arch6"
+ "uxtah%?\\t%0, %2, %1"
+ [(set_attr "type" "alu_shift")
+ (set_attr "predicable" "yes")]
+)
+
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
@@ -3249,7 +3328,7 @@
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
"TARGET_EITHER"
"
- if (GET_CODE (operands[1]) != MEM)
+ if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
{
if (TARGET_ARM)
{
@@ -3285,26 +3364,61 @@
)
(define_insn "*thumb_zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=l")
- (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_THUMB"
+ [(set (match_operand:SI 0 "register_operand" "=l")
+ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_THUMB && !arm_arch6"
"ldrb\\t%0, %1"
[(set_attr "length" "2")
- (set_attr "type" "load")
+ (set_attr "type" "load_byte")
(set_attr "pool_range" "32")]
)
+(define_insn "*thumb_zero_extendqisi2_v6"
+ [(set (match_operand:SI 0 "register_operand" "=l,l")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
+ "TARGET_THUMB && arm_arch6"
+ "@
+ uxtb\\t%0, %1
+ ldrb\\t%0, %1"
+ [(set_attr "length" "2,2")
+ (set_attr "type" "alu_shift,load_byte")
+ (set_attr "pool_range" "*,32")]
+)
+
(define_insn "*arm_zero_extendqisi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_ARM"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_ARM && !arm_arch6"
"ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")
(set_attr "pool_range" "4096")
(set_attr "neg_pool_range" "4084")]
)
+(define_insn "*arm_zero_extendqisi2_v6"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_ARM && arm_arch6"
+ "@
+ uxtb%?\\t%0, %1
+ ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
+ [(set_attr "type" "alu_shift,load_byte")
+ (set_attr "predicable" "yes")
+ (set_attr "pool_range" "*,4096")
+ (set_attr "neg_pool_range" "*,4084")]
+)
+
+(define_insn "*arm_zero_extendqisi2addsi"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
+ (match_operand:SI 2 "s_register_operand" "r")))]
+ "TARGET_ARM && arm_arch6"
+ "uxtab%?\\t%0, %2, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "alu_shift")]
+)
+
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
@@ -3334,15 +3448,23 @@
"TARGET_EITHER"
"
{
- if (TARGET_ARM && arm_arch4 && GET_CODE (operands[1]) == MEM)
+ if (GET_CODE (operands[1]) == MEM)
{
- /* Note: We do not have to worry about TARGET_MMU_TRAPS
- 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_THUMB)
+ {
+ emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
+ DONE;
+ }
+ else if (arm_arch4)
+ {
+ /* Note: We do not have to worry about TARGET_MMU_TRAPS
+ 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_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
@@ -3350,39 +3472,31 @@
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]);
- operands[2] = gen_reg_rtx (SImode);
- if (TARGET_THUMB)
+ if (arm_arch6)
{
- rtx ops[3];
-
- ops[0] = operands[2];
- ops[1] = operands[1];
- ops[2] = GEN_INT (16);
-
- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
- gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
-
- ops[0] = operands[0];
- ops[1] = operands[2];
- ops[2] = GEN_INT (16);
-
- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
- gen_rtx_ASHIFTRT (SImode, ops[1], ops[2])));
-
+ if (TARGET_THUMB)
+ emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
+ else
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_SIGN_EXTEND (SImode, operands[1])));
+
DONE;
}
+
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode);
}"
)
-(define_insn "*thumb_extendhisi2_insn"
- [(set (match_operand:SI 0 "register_operand" "=l")
- (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
- (clobber (match_scratch:SI 2 "=&l"))]
- "TARGET_THUMB"
+(define_insn "thumb_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=l")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
+ (clobber (match_scratch:SI 2 "=&l"))]
+ "TARGET_THUMB && !arm_arch6"
"*
{
rtx ops[4];
@@ -3432,10 +3546,83 @@
return \"\";
}"
[(set_attr "length" "4")
- (set_attr "type" "load")
+ (set_attr "type" "load_byte")
(set_attr "pool_range" "1020")]
)
+;; We used to have an early-clobber on the scratch register here.
+;; However, there's a bug somewhere in reload which means that this
+;; can be partially ignored during spill allocation if the memory
+;; address also needs reloading; this causes an abort later on when
+;; we try to verify the operands. Fortunately, we don't really need
+;; the early-clobber: we can always use operand 0 if operand 2
+;; overlaps the address.
+(define_insn "*thumb_extendhisi2_insn_v6"
+ [(set (match_operand:SI 0 "register_operand" "=l,l")
+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
+ (clobber (match_scratch:SI 2 "=X,l"))]
+ "TARGET_THUMB && arm_arch6"
+ "*
+ {
+ rtx ops[4];
+ rtx mem;
+
+ if (which_alternative == 0)
+ return \"sxth\\t%0, %1\";
+
+ mem = XEXP (operands[1], 0);
+
+ /* This code used to try to use 'V', and fix the address only if it was
+ offsettable, but this fails for e.g. REG+48 because 48 is outside the
+ range of QImode offsets, and offsettable_address_p does a QImode
+ address check. */
+
+ if (GET_CODE (mem) == CONST)
+ mem = XEXP (mem, 0);
+
+ if (GET_CODE (mem) == LABEL_REF)
+ return \"ldr\\t%0, %1\";
+
+ if (GET_CODE (mem) == PLUS)
+ {
+ rtx a = XEXP (mem, 0);
+ rtx b = XEXP (mem, 1);
+
+ if (GET_CODE (a) == LABEL_REF
+ && GET_CODE (b) == CONST_INT)
+ return \"ldr\\t%0, %1\";
+
+ if (GET_CODE (b) == REG)
+ return \"ldrsh\\t%0, %1\";
+
+ ops[1] = a;
+ ops[2] = b;
+ }
+ else
+ {
+ ops[1] = mem;
+ ops[2] = const0_rtx;
+ }
+
+ if (GET_CODE (ops[1]) != REG)
+ {
+ debug_rtx (ops[1]);
+ abort ();
+ }
+
+ ops[0] = operands[0];
+ if (reg_mentioned_p (operands[2], ops[1]))
+ ops[3] = ops[0];
+ else
+ ops[3] = operands[2];
+ output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
+ return \"\";
+ }"
+ [(set_attr "length" "2,4")
+ (set_attr "type" "alu_shift,load_byte")
+ (set_attr "pool_range" "*,1020")]
+)
+
(define_expand "extendhisi2_mem"
[(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
(set (match_dup 3)
@@ -3473,17 +3660,38 @@
}"
)
-(define_insn "*arm_extendhisi_insn"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
- "TARGET_ARM && arm_arch4"
+(define_insn "*arm_extendhisi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_ARM && arm_arch4 && !arm_arch6"
"ldr%?sh\\t%0, %1"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")
(set_attr "pool_range" "256")
(set_attr "neg_pool_range" "244")]
)
+(define_insn "*arm_extendhisi2_v6"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_ARM && arm_arch6"
+ "@
+ sxth%?\\t%0, %1
+ ldr%?sh\\t%0, %1"
+ [(set_attr "type" "alu_shift,load_byte")
+ (set_attr "predicable" "yes")
+ (set_attr "pool_range" "*,256")
+ (set_attr "neg_pool_range" "*,244")]
+)
+
+(define_insn "*arm_extendhisi2addsi"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
+ (match_operand:SI 2 "s_register_operand" "r")))]
+ "TARGET_ARM && arm_arch6"
+ "sxtah%?\\t%0, %2, %1"
+)
+
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
@@ -3550,7 +3758,7 @@
return \"#\";
return \"ldr%?sb\\t%0, %1\";
"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")
(set_attr "length" "8")
(set_attr "pool_range" "256")
@@ -3601,60 +3809,78 @@
"TARGET_EITHER"
"
{
- if (TARGET_ARM && arm_arch4 && GET_CODE (operands[1]) == MEM)
+ if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
{
- emit_insn (gen_rtx_SET (VOIDmode,
- operands[0],
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_SIGN_EXTEND (SImode, operands[1])));
DONE;
}
+
if (!s_register_operand (operands[1], QImode))
operands[1] = copy_to_mode_reg (QImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode);
-
- if (TARGET_THUMB)
- {
- rtx ops[3];
-
- ops[0] = operands[2];
- ops[1] = operands[1];
- ops[2] = GEN_INT (24);
-
- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
- gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
- ops[0] = operands[0];
- ops[1] = operands[2];
- ops[2] = GEN_INT (24);
-
- emit_insn (gen_rtx_SET (VOIDmode, ops[0],
- gen_rtx_ASHIFTRT (SImode, ops[1], ops[2])));
-
- DONE;
+ if (arm_arch6)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_SIGN_EXTEND (SImode, operands[1])));
+ DONE;
}
+
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode);
}"
)
; Rather than restricting all byte accesses to memory addresses that ldrsb
; can handle, we fix up the ones that ldrsb can't grok with a split.
-(define_insn "*arm_extendqisi_insn"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_ARM && arm_arch4"
+(define_insn "*arm_extendqisi"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_ARM && arm_arch4 && !arm_arch6"
"*
/* If the address is invalid, this will split the instruction into two. */
if (bad_signed_byte_operand (operands[1], VOIDmode))
return \"#\";
return \"ldr%?sb\\t%0, %1\";
"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")
(set_attr "length" "8")
(set_attr "pool_range" "256")
(set_attr "neg_pool_range" "244")]
)
+(define_insn "*arm_extendqisi_v6"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_ARM && arm_arch6"
+ "*
+ if (which_alternative == 0)
+ return \"sxtb%?\\t%0, %1\";
+
+ /* If the address is invalid, this will split the instruction into two. */
+ if (bad_signed_byte_operand (operands[1], VOIDmode))
+ return \"#\";
+
+ return \"ldr%?sb\\t%0, %1\";
+ "
+ [(set_attr "type" "alu_shift,load_byte")
+ (set_attr "predicable" "yes")
+ (set_attr "length" "4,8")
+ (set_attr "pool_range" "*,256")
+ (set_attr "neg_pool_range" "*,244")]
+)
+
+(define_insn "*arm_extendqisi2addsi"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
+ (match_operand:SI 2 "s_register_operand" "r")))]
+ "TARGET_ARM && arm_arch6"
+ "sxtab%?\\t%0, %2, %1"
+ [(set_attr "type" "alu_shift")
+ (set_attr "predicable" "yes")]
+)
+
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
(sign_extend:SI (match_operand:QI 1 "bad_signed_byte_operand" "")))]
@@ -3688,10 +3914,10 @@
}"
)
-(define_insn "*thumb_extendqisi2_insn"
- [(set (match_operand:SI 0 "register_operand" "=l,l")
- (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
- "TARGET_THUMB"
+(define_insn "*thumb_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=l,l")
+ (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
+ "TARGET_THUMB && !arm_arch6"
"*
{
rtx ops[3];
@@ -3763,14 +3989,95 @@
return \"\";
}"
[(set_attr "length" "2,6")
- (set_attr "type" "load,load")
+ (set_attr "type" "load_byte,load_byte")
(set_attr "pool_range" "32,32")]
)
+(define_insn "*thumb_extendqisi2_v6"
+ [(set (match_operand:SI 0 "register_operand" "=l,l,l")
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
+ "TARGET_THUMB && arm_arch6"
+ "*
+ {
+ rtx ops[3];
+ rtx mem;
+
+ if (which_alternative == 0)
+ return \"sxtb\\t%0, %1\";
+
+ mem = XEXP (operands[1], 0);
+
+ if (GET_CODE (mem) == CONST)
+ mem = XEXP (mem, 0);
+
+ if (GET_CODE (mem) == LABEL_REF)
+ return \"ldr\\t%0, %1\";
+
+ if (GET_CODE (mem) == PLUS
+ && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
+ return \"ldr\\t%0, %1\";
+
+ if (which_alternative == 0)
+ return \"ldrsb\\t%0, %1\";
+
+ ops[0] = operands[0];
+
+ if (GET_CODE (mem) == PLUS)
+ {
+ rtx a = XEXP (mem, 0);
+ rtx b = XEXP (mem, 1);
+
+ ops[1] = a;
+ ops[2] = b;
+
+ if (GET_CODE (a) == REG)
+ {
+ if (GET_CODE (b) == REG)
+ output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
+ else if (REGNO (a) == REGNO (ops[0]))
+ {
+ output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
+ output_asm_insn (\"sxtb\\t%0, %0\", ops);
+ }
+ else
+ output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
+ }
+ else if (GET_CODE (b) != REG)
+ abort ();
+ else
+ {
+ if (REGNO (b) == REGNO (ops[0]))
+ {
+ output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
+ output_asm_insn (\"sxtb\\t%0, %0\", ops);
+ }
+ else
+ output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
+ }
+ }
+ else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
+ {
+ output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
+ output_asm_insn (\"sxtb\\t%0, %0\", ops);
+ }
+ else
+ {
+ ops[1] = mem;
+ ops[2] = const0_rtx;
+
+ output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
+ }
+ return \"\";
+ }"
+ [(set_attr "length" "2,2,4")
+ (set_attr "type" "alu_shift,load_byte,load_byte")
+ (set_attr "pool_range" "*,32,32")]
+)
+
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "s_register_operand" "")
(float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT"
""
)
@@ -3854,12 +4161,14 @@
(define_insn "*arm_movdi"
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
(match_operand:DI 1 "di_operand" "rIK,mi,r"))]
- "TARGET_ARM && !TARGET_CIRRUS && ! TARGET_IWMMXT"
+ "TARGET_ARM
+ && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
+ && !TARGET_IWMMXT"
"*
return (output_move_double (operands));
"
[(set_attr "length" "8")
- (set_attr "type" "*,load,store2")
+ (set_attr "type" "*,load2,store2")
(set_attr "pool_range" "*,1020,*")
(set_attr "neg_pool_range" "*,1008,*")]
)
@@ -3872,7 +4181,7 @@
[(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
(match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
"TARGET_THUMB
- && !TARGET_CIRRUS
+ && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
&& ( register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
"*
@@ -3907,7 +4216,7 @@
}
}"
[(set_attr "length" "4,4,6,2,2,6,4,4")
- (set_attr "type" "*,*,*,load,store2,load,store2,*")
+ (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
(set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
)
@@ -3921,7 +4230,8 @@
/* Everything except mem = const or mem = mem can be done easily. */
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (SImode, operands[1]);
- if (GET_CODE (operands[1]) == CONST_INT
+ if (arm_general_register_operand (operands[0], SImode)
+ && GET_CODE (operands[1]) == CONST_INT
&& !(const_ok_for_arm (INTVAL (operands[1]))
|| const_ok_for_arm (~INTVAL (operands[1]))))
{
@@ -3954,6 +4264,7 @@
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
(match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
"TARGET_ARM && ! TARGET_IWMMXT
+ && !(TARGET_HARD_FLOAT && TARGET_VFP)
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
@@ -3961,14 +4272,14 @@
mvn%?\\t%0, #%B1
ldr%?\\t%0, %1
str%?\\t%1, %0"
- [(set_attr "type" "*,*,load,store1")
+ [(set_attr "type" "*,*,load1,store1")
(set_attr "predicable" "yes")
(set_attr "pool_range" "*,*,4096,*")
(set_attr "neg_pool_range" "*,*,4084,*")]
)
(define_split
- [(set (match_operand:SI 0 "s_register_operand" "")
+ [(set (match_operand:SI 0 "arm_general_register_operand" "")
(match_operand:SI 1 "const_int_operand" ""))]
"TARGET_ARM
&& (!(const_ok_for_arm (INTVAL (operands[1]))
@@ -3998,7 +4309,7 @@
str\\t%1, %0
mov\\t%0, %1"
[(set_attr "length" "2,2,4,4,2,2,2,2,2")
- (set_attr "type" "*,*,*,*,load,store1,load,store1,*")
+ (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
(set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
)
@@ -4050,7 +4361,7 @@
(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
"TARGET_ARM && flag_pic"
"ldr%?\\t%0, %1"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set (attr "pool_range") (const_int 4096))
(set (attr "neg_pool_range") (const_int 4084))]
)
@@ -4060,7 +4371,7 @@
(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
"TARGET_THUMB && flag_pic"
"ldr\\t%0, %1"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set (attr "pool_range") (const_int 1024))]
)
@@ -4086,7 +4397,7 @@
output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
return \"\";
"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set (attr "pool_range")
(if_then_else (eq_attr "is_thumb" "yes")
(const_int 1024)
@@ -4514,7 +4825,7 @@
return \"ldrh %0, %1\";
}"
[(set_attr "length" "2,4,2,2,2,2")
- (set_attr "type" "*,load,store1,*,*,*")]
+ (set_attr "type" "*,load1,store1,*,*,*")]
)
@@ -4532,7 +4843,7 @@
output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
return \"\";
}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "predicable" "yes")]
)
@@ -4601,7 +4912,7 @@
mvn%?\\t%0, #%B1\\t%@ movhi
str%?h\\t%1, %0\\t%@ movhi
ldr%?h\\t%0, %1\\t%@ movhi"
- [(set_attr "type" "*,*,store1,load")
+ [(set_attr "type" "*,*,store1,load1")
(set_attr "predicable" "yes")
(set_attr "pool_range" "*,*,*,256")
(set_attr "neg_pool_range" "*,*,*,244")]
@@ -4621,7 +4932,7 @@
mov%?\\t%0, %1\\t%@ movhi
mvn%?\\t%0, #%B1\\t%@ movhi
ldr%?\\t%0, %1\\t%@ movhi"
- [(set_attr "type" "*,*,load")
+ [(set_attr "type" "*,*,load1")
(set_attr "predicable" "yes")
(set_attr "pool_range" "4096")
(set_attr "neg_pool_range" "4084")]
@@ -4641,7 +4952,7 @@
mov%?\\t%0, %1\\t%@ movhi
mvn%?\\t%0, #%B1\\t%@ movhi
ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
- [(set_attr "type" "*,*,load")
+ [(set_attr "type" "*,*,load1")
(set_attr "predicable" "yes")
(set_attr "length" "4,4,8")
(set_attr "pool_range" "*,*,4092")
@@ -4656,7 +4967,7 @@
&& BYTES_BIG_ENDIAN
&& !TARGET_MMU_TRAPS"
"ldr%?\\t%0, %1\\t%@ movhi_bigend"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "predicable" "yes")
(set_attr "pool_range" "4096")
(set_attr "neg_pool_range" "4084")]
@@ -4796,7 +5107,7 @@
mvn%?\\t%0, #%B1
ldr%?b\\t%0, %1
str%?b\\t%1, %0"
- [(set_attr "type" "*,*,load,store1")
+ [(set_attr "type" "*,*,load1,store1")
(set_attr "predicable" "yes")]
)
@@ -4814,7 +5125,7 @@
mov\\t%0, %1
mov\\t%0, %1"
[(set_attr "length" "2")
- (set_attr "type" "*,load,store1,*,*,*")
+ (set_attr "type" "*,load1,store1,*,*,*")
(set_attr "pool_range" "*,32,*,*,*,*")]
)
@@ -4843,7 +5154,7 @@
[(set (match_operand:SF 0 "nonimmediate_operand" "")
(match_operand:SF 1 "immediate_operand" ""))]
"TARGET_ARM
- && !TARGET_HARD_FLOAT
+ && !(TARGET_HARD_FLOAT && TARGET_FPA)
&& reload_completed
&& GET_CODE (operands[1]) == CONST_DOUBLE"
[(set (match_dup 2) (match_dup 3))]
@@ -4859,7 +5170,6 @@
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
(match_operand:SF 1 "general_operand" "r,mE,r"))]
"TARGET_ARM
- && !TARGET_CIRRUS
&& TARGET_SOFT_FLOAT
&& (GET_CODE (operands[0]) != MEM
|| register_operand (operands[1], SFmode))"
@@ -4869,7 +5179,7 @@
str%?\\t%1, %0\\t%@ float"
[(set_attr "length" "4,4,4")
(set_attr "predicable" "yes")
- (set_attr "type" "*,load,store1")
+ (set_attr "type" "*,load1,store1")
(set_attr "pool_range" "*,4096,*")
(set_attr "neg_pool_range" "*,4084,*")]
)
@@ -4890,7 +5200,7 @@
mov\\t%0, %1
mov\\t%0, %1"
[(set_attr "length" "2")
- (set_attr "type" "*,load,store1,load,store1,*,*")
+ (set_attr "type" "*,load1,store1,load1,store1,*,*")
(set_attr "pool_range" "*,*,*,1020,*,*,*")]
)
@@ -4962,11 +5272,10 @@
[(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
(match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
"TARGET_ARM && TARGET_SOFT_FLOAT
- && !TARGET_CIRRUS
"
"* return output_move_double (operands);"
[(set_attr "length" "8,8,8")
- (set_attr "type" "*,load,store2")
+ (set_attr "type" "*,load2,store2")
(set_attr "pool_range" "1020")
(set_attr "neg_pool_range" "1008")]
)
@@ -5007,7 +5316,7 @@
}
"
[(set_attr "length" "4,2,2,6,4,4")
- (set_attr "type" "*,load,store2,load,store2,*")
+ (set_attr "type" "*,load2,store2,load2,store2,*")
(set_attr "pool_range" "*,*,*,1020,*,*")]
)
@@ -5080,7 +5389,7 @@
(mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
"TARGET_ARM && XVECLEN (operands[0], 0) == 5"
"ldm%?ia\\t%1!, {%3, %4, %5, %6}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load4")
(set_attr "predicable" "yes")]
)
@@ -5097,7 +5406,7 @@
(mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
"TARGET_ARM && XVECLEN (operands[0], 0) == 4"
"ldm%?ia\\t%1!, {%3, %4, %5}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load3")
(set_attr "predicable" "yes")]
)
@@ -5112,7 +5421,7 @@
(mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
"TARGET_ARM && XVECLEN (operands[0], 0) == 3"
"ldm%?ia\\t%1!, {%3, %4}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load2")
(set_attr "predicable" "yes")]
)
@@ -5130,7 +5439,7 @@
(mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
"TARGET_ARM && XVECLEN (operands[0], 0) == 4"
"ldm%?ia\\t%1, {%2, %3, %4, %5}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load4")
(set_attr "predicable" "yes")]
)
@@ -5144,7 +5453,7 @@
(mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
"TARGET_ARM && XVECLEN (operands[0], 0) == 3"
"ldm%?ia\\t%1, {%2, %3, %4}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load3")
(set_attr "predicable" "yes")]
)
@@ -5156,7 +5465,7 @@
(mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
"TARGET_ARM && XVECLEN (operands[0], 0) == 2"
"ldm%?ia\\t%1, {%2, %3}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load2")
(set_attr "predicable" "yes")]
)
@@ -6406,12 +6715,9 @@
(define_expand "cmpsf"
[(match_operand:SF 0 "s_register_operand" "")
- (match_operand:SF 1 "fpa_rhs_operand" "")]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (match_operand:SF 1 "arm_float_compare_operand" "")]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS && !cirrus_fp_register (operands[1], SFmode))
- operands[1] = force_reg (SFmode, operands[1]);
-
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
@@ -6420,12 +6726,9 @@
(define_expand "cmpdf"
[(match_operand:DF 0 "s_register_operand" "")
- (match_operand:DF 1 "fpa_rhs_operand" "")]
- "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ (match_operand:DF 1 "arm_float_compare_operand" "")]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
"
- if (TARGET_CIRRUS && !cirrus_fp_register (operands[1], DFmode))
- operands[1] = force_reg (DFmode, operands[1]);
-
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
@@ -6453,7 +6756,9 @@
"cmp%?\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*cmpsi_shiftsi_swp"
@@ -6466,7 +6771,9 @@
"cmp%?\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*cmpsi_neg_shiftsi"
@@ -6479,7 +6786,9 @@
"cmn%?\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- ]
+ (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
;; Cirrus SF compare instruction
@@ -6487,7 +6796,7 @@
[(set (reg:CCFP CC_REGNUM)
(compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
(match_operand:SF 1 "cirrus_fp_register" "v")))]
- "TARGET_ARM && TARGET_CIRRUS"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
"cfcmps%?\\tr15, %V0, %V1"
[(set_attr "type" "mav_farith")
(set_attr "cirrus" "compare")]
@@ -6498,7 +6807,7 @@
[(set (reg:CCFP CC_REGNUM)
(compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
(match_operand:DF 1 "cirrus_fp_register" "v")))]
- "TARGET_ARM && TARGET_CIRRUS"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
"cfcmpd%?\\tr15, %V0, %V1"
[(set_attr "type" "mav_farith")
(set_attr "cirrus" "compare")]
@@ -6508,7 +6817,7 @@
(define_expand "cmpdi"
[(match_operand:DI 0 "cirrus_fp_register" "")
(match_operand:DI 1 "cirrus_fp_register" "")]
- "TARGET_ARM && TARGET_CIRRUS"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
"{
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
@@ -6519,7 +6828,7 @@
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
(match_operand:DI 1 "cirrus_fp_register" "v")))]
- "TARGET_ARM && TARGET_CIRRUS"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
"cfcmp64%?\\tr15, %V0, %V1"
[(set_attr "type" "mav_farith")
(set_attr "cirrus" "compare")]
@@ -6637,7 +6946,7 @@
(if_then_else (unordered (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -6647,7 +6956,7 @@
(if_then_else (ordered (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -6657,7 +6966,7 @@
(if_then_else (ungt (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
)
@@ -6666,7 +6975,7 @@
(if_then_else (unlt (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
)
@@ -6675,7 +6984,7 @@
(if_then_else (unge (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
)
@@ -6684,7 +6993,7 @@
(if_then_else (unle (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
)
@@ -6695,7 +7004,7 @@
(if_then_else (uneq (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
)
@@ -6704,7 +7013,7 @@
(if_then_else (ltgt (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
)
@@ -6718,7 +7027,7 @@
(if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"*
if (arm_ccfsm_state != 0)
abort ();
@@ -6735,7 +7044,7 @@
(if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"*
if (arm_ccfsm_state != 0)
abort ();
@@ -6761,7 +7070,8 @@
}
return \"b%d1\\t%l0\";
"
- [(set_attr "conds" "use")]
+ [(set_attr "conds" "use")
+ (set_attr "type" "branch")]
)
; Special pattern to match reversed UNEQ.
@@ -6770,7 +7080,7 @@
(if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"*
if (arm_ccfsm_state != 0)
abort ();
@@ -6787,7 +7097,7 @@
(if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"*
if (arm_ccfsm_state != 0)
abort ();
@@ -6813,7 +7123,8 @@
}
return \"b%D1\\t%l0\";
"
- [(set_attr "conds" "use")]
+ [(set_attr "conds" "use")
+ (set_attr "type" "branch")]
)
@@ -6893,7 +7204,7 @@
(define_expand "sunordered"
[(set (match_operand:SI 0 "s_register_operand" "")
(unordered:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -6901,7 +7212,7 @@
(define_expand "sordered"
[(set (match_operand:SI 0 "s_register_operand" "")
(ordered:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -6909,7 +7220,7 @@
(define_expand "sungt"
[(set (match_operand:SI 0 "s_register_operand" "")
(ungt:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
arm_compare_op1);"
)
@@ -6917,7 +7228,7 @@
(define_expand "sunge"
[(set (match_operand:SI 0 "s_register_operand" "")
(unge:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
arm_compare_op1);"
)
@@ -6925,7 +7236,7 @@
(define_expand "sunlt"
[(set (match_operand:SI 0 "s_register_operand" "")
(unlt:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
arm_compare_op1);"
)
@@ -6933,7 +7244,7 @@
(define_expand "sunle"
[(set (match_operand:SI 0 "s_register_operand" "")
(unle:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
arm_compare_op1);"
)
@@ -6944,14 +7255,14 @@
; (define_expand "suneq"
; [(set (match_operand:SI 0 "s_register_operand" "")
; (uneq:SI (match_dup 1) (const_int 0)))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
+; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
; "abort ();"
; )
;
; (define_expand "sltgt"
; [(set (match_operand:SI 0 "s_register_operand" "")
; (ltgt:SI (match_dup 1) (const_int 0)))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
+; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
; "abort ();"
; )
@@ -7022,9 +7333,9 @@
FAIL;
/* When compiling for SOFT_FLOAT, ensure both arms are in registers.
- Otherwise, ensure it is a valid FP add operand. */
- if ((!TARGET_HARD_FLOAT)
- || (!fpa_add_operand (operands[3], SFmode)))
+ Otherwise, ensure it is a valid FP add operand */
+ if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
+ || (!arm_float_add_operand (operands[3], SFmode)))
operands[3] = force_reg (SFmode, operands[3]);
ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
@@ -7036,8 +7347,8 @@
[(set (match_operand:DF 0 "s_register_operand" "")
(if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
(match_operand:DF 2 "s_register_operand" "")
- (match_operand:DF 3 "fpa_add_operand" "")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ (match_operand:DF 3 "arm_float_add_operand" "")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"
{
enum rtx_code code = GET_CODE (operands[1]);
@@ -7403,7 +7714,7 @@
}
return output_return_instruction (const_true_rtx, TRUE, FALSE);
}"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "length" "12")
(set_attr "predicable" "yes")]
)
@@ -7426,7 +7737,7 @@
}"
[(set_attr "conds" "use")
(set_attr "length" "12")
- (set_attr "type" "load")]
+ (set_attr "type" "load1")]
)
(define_insn "*cond_return_inverted"
@@ -7446,7 +7757,7 @@
return output_return_instruction (operands[0], TRUE, TRUE);
}"
[(set_attr "conds" "use")
- (set_attr "type" "load")]
+ (set_attr "type" "load1")]
)
;; Generate a sequence of instructions to determine if the processor is
@@ -7590,7 +7901,7 @@
(match_operand:SI 0 "memory_operand" "m"))]
"TARGET_ARM"
"ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "pool_range" "4096")
(set_attr "neg_pool_range" "4084")
(set_attr "predicable" "yes")]
@@ -7636,7 +7947,9 @@
"%i1%?\\t%0, %2, %4%S3"
[(set_attr "predicable" "yes")
(set_attr "shift" "4")
- ]
+ (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_split
@@ -7672,7 +7985,9 @@
"%i1%?s\\t%0, %2, %4%S3"
[(set_attr "conds" "set")
(set_attr "shift" "4")
- ]
+ (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*arith_shiftsi_compare0_scratch"
@@ -7688,7 +8003,9 @@
"%i1%?s\\t%0, %2, %4%S3"
[(set_attr "conds" "set")
(set_attr "shift" "4")
- ]
+ (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*sub_shiftsi"
@@ -7701,7 +8018,9 @@
"sub%?\\t%0, %1, %3%S2"
[(set_attr "predicable" "yes")
(set_attr "shift" "3")
- ]
+ (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*sub_shiftsi_compare0"
@@ -7718,8 +8037,10 @@
"TARGET_ARM"
"sub%?s\\t%0, %1, %3%S2"
[(set_attr "conds" "set")
- (set_attr "shift" "3")
- ]
+ (set_attr "shift" "3")
+ (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*sub_shiftsi_compare0_scratch"
@@ -7734,8 +8055,10 @@
"TARGET_ARM"
"sub%?s\\t%0, %1, %3%S2"
[(set_attr "conds" "set")
- (set_attr "shift" "3")
- ]
+ (set_attr "shift" "3")
+ (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
@@ -8608,7 +8931,10 @@
mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
[(set_attr "conds" "use")
(set_attr "shift" "2")
- (set_attr "length" "4,8,8")]
+ (set_attr "length" "4,8,8")
+ (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*ifcompare_move_shift"
@@ -8644,7 +8970,10 @@
mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
[(set_attr "conds" "use")
(set_attr "shift" "2")
- (set_attr "length" "4,8,8")]
+ (set_attr "length" "4,8,8")
+ (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*ifcompare_shift_shift"
@@ -8681,7 +9010,12 @@
"mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
[(set_attr "conds" "use")
(set_attr "shift" "1")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set (attr "type") (if_then_else
+ (and (match_operand 2 "const_int_operand" "")
+ (match_operand 4 "const_int_operand" ""))
+ (const_string "alu_shift")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*ifcompare_not_arith"
@@ -8882,7 +9216,7 @@
}"
[(set_attr "length" "12")
(set_attr "predicable" "yes")
- (set_attr "type" "load")]
+ (set_attr "type" "load1")]
)
;; the arm can support extended pre-inc instructions
@@ -8939,7 +9273,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?b\\t%3, [%0, %2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -8955,7 +9289,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?b\\t%3, [%0, -%2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -8972,7 +9306,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -8989,7 +9323,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -9037,7 +9371,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?\\t%3, [%0, %2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "predicable" "yes")]
)
@@ -9053,7 +9387,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?\\t%3, [%0, -%2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "predicable" "yes")]
)
@@ -9072,7 +9406,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -9091,7 +9425,7 @@
&& (GET_CODE (operands[2]) != REG
|| REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
"ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -9145,7 +9479,7 @@
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
"ldr%?b\\t%5, [%0, %3%S2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -9163,7 +9497,7 @@
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
"ldr%?b\\t%5, [%0, -%3%S2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -9217,7 +9551,7 @@
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
"ldr%?\\t%5, [%0, %3%S2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "predicable" "yes")]
)
@@ -9235,7 +9569,7 @@
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
"ldr%?\\t%5, [%0, -%3%S2]!"
- [(set_attr "type" "load")
+ [(set_attr "type" "load1")
(set_attr "predicable" "yes")])
(define_insn "*loadhi_shiftpreinc"
@@ -9255,7 +9589,7 @@
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
"ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -9276,7 +9610,7 @@
&& REGNO (operands[1]) != FRAME_POINTER_REGNUM
&& REGNO (operands[3]) != FRAME_POINTER_REGNUM"
"ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
- [(set_attr "type" "load")
+ [(set_attr "type" "load_byte")
(set_attr "predicable" "yes")]
)
@@ -9388,7 +9722,7 @@
(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (const_int 0)))]
"TARGET_ARM
- && (!TARGET_CIRRUS
+ && (!(TARGET_HARD_FLOAT && TARGET_MAVERICK)
|| (!cirrus_fp_register (operands[0], SImode)
&& !cirrus_fp_register (operands[1], SImode)))
"
@@ -9832,7 +10166,7 @@
[(set (match_operand:BLK 0 "memory_operand" "=m")
(unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
UNSPEC_PUSH_MULT))])]
- "TARGET_ARM"
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
"*
{
char pattern[100];
@@ -10052,3 +10386,6 @@
(include "cirrus.md")
;; Load the Intel Wireless Multimedia Extension patterns
(include "iwmmxt.md")
+;; Load the VFP co-processor patterns
+(include "vfp.md")
+