Mercurial > hg > CbC > CbC_gcc
diff gcc/config/arm/arm.md @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
line wrap: on
line diff
--- a/gcc/config/arm/arm.md Fri Feb 12 23:41:23 2010 +0900 +++ b/gcc/config/arm/arm.md Mon May 24 12:47:05 2010 +0900 @@ -1,6 +1,6 @@ ;;- Machine description for ARM for GNU compiler ;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000, -;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 ;; Free Software Foundation, Inc. ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) ;; and Martin Simmons (@harleqn.co.uk). @@ -101,6 +101,8 @@ ; a given symbolic address. (UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call. (UNSPEC_RBIT 26) ; rbit operation. + (UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from + ; another symbolic address. ] ) @@ -146,13 +148,6 @@ ; patterns that share the same RTL in both ARM and Thumb code. (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code"))) -; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects -; scheduling decisions for the load unit and the multiplier. -(define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_tune_strongarm"))) - -; IS_XSCALE is set to 'yes' when compiling for XScale. -(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale"))) - ;; Operand number of an input operand that is shifted. Zero if the ;; given instruction does not shift one of its input operands. (define_attr "shift" "" (const_int 0)) @@ -1265,8 +1260,8 @@ (match_operand:SI 2 "register_operand" "l,0,0")))] "TARGET_THUMB1 && arm_arch6" "@ - mul\\t%0, %2 - mul\\t%0, %1 + mul\\t%0, %2 + mul\\t%0, %1 mul\\t%0, %1" [(set_attr "length" "2") (set_attr "insn" "mul")] @@ -3538,17 +3533,11 @@ (define_expand "negdi2" [(parallel - [(set (match_operand:DI 0 "s_register_operand" "") - (neg:DI (match_operand:DI 1 "s_register_operand" ""))) + [(set (match_operand:DI 0 "s_register_operand" "") + (neg:DI (match_operand:DI 1 "s_register_operand" ""))) (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" - " - if (TARGET_THUMB1) - { - if (GET_CODE (operands[1]) != REG) - operands[1] = force_reg (DImode, operands[1]); - } - " + "" ) ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). @@ -3564,8 +3553,8 @@ ) (define_insn "*thumb1_negdi2" - [(set (match_operand:DI 0 "register_operand" "=&l") - (neg:DI (match_operand:DI 1 "register_operand" "l"))) + [(set (match_operand:DI 0 "register_operand" "=&l") + (neg:DI (match_operand:DI 1 "register_operand" "l"))) (clobber (reg:CC CC_REGNUM))] "TARGET_THUMB1" "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1" @@ -5242,14 +5231,17 @@ ;; the insn alone, and to force the minipool generation pass to then move ;; the GOT symbol to memory. -(define_insn "pic_load_addr_arm" +(define_insn "pic_load_addr_32bit" [(set (match_operand:SI 0 "s_register_operand" "=r") (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] - "TARGET_ARM && flag_pic" + "TARGET_32BIT && flag_pic" "ldr%?\\t%0, %1" [(set_attr "type" "load1") - (set (attr "pool_range") (const_int 4096)) - (set (attr "neg_pool_range") (const_int 4084))] + (set_attr "pool_range" "4096") + (set (attr "neg_pool_range") + (if_then_else (eq_attr "is_thumb" "no") + (const_int 4084) + (const_int 0)))] ) (define_insn "pic_load_addr_thumb1" @@ -5267,7 +5259,7 @@ (const_int 4) (match_operand 2 "" "")] UNSPEC_PIC_BASE))] - "TARGET_THUMB1" + "TARGET_THUMB" "* (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", INTVAL (operands[2])); @@ -6663,6 +6655,30 @@ operands[2] = force_reg (SImode, operands[2]); ") +;; A pattern to recognize a special situation and optimize for it. +;; On the thumb, zero-extension from memory is preferrable to sign-extension +;; due to the available addressing modes. Hence, convert a signed comparison +;; with zero into an unsigned comparison with 127 if possible. +(define_expand "cbranchqi4" + [(set (pc) (if_then_else + (match_operator 0 "lt_ge_comparison_operator" + [(match_operand:QI 1 "memory_operand" "") + (match_operand:QI 2 "const0_operand" "")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "TARGET_THUMB1" +{ + rtx xops[3]; + xops[1] = gen_reg_rtx (SImode); + emit_insn (gen_zero_extendqisi2 (xops[1], operands[1])); + xops[2] = GEN_INT (127); + xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU, + VOIDmode, xops[1], xops[2]); + xops[3] = operands[3]; + emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3])); + DONE; +}) + (define_expand "cbranchsf4" [(set (pc) (if_then_else (match_operator 0 "arm_comparison_operator" @@ -6700,7 +6716,7 @@ operands[3])); DONE;" ) -(define_insn "*cbranchsi4_insn" +(define_insn "cbranchsi4_insn" [(set (pc) (if_then_else (match_operator 0 "arm_comparison_operator" [(match_operand:SI 1 "s_register_operand" "l,*h") @@ -6709,7 +6725,20 @@ (pc)))] "TARGET_THUMB1" "* - output_asm_insn (\"cmp\\t%1, %2\", operands); + rtx t = prev_nonnote_insn (insn); + if (t != NULL_RTX + && INSN_P (t) + && INSN_CODE (t) == CODE_FOR_cbranchsi4_insn) + { + t = XEXP (SET_SRC (PATTERN (t)), 0); + if (!rtx_equal_p (XEXP (t, 0), operands[1]) + || !rtx_equal_p (XEXP (t, 1), operands[2])) + t = NULL_RTX; + } + else + t = NULL_RTX; + if (t == NULL_RTX) + output_asm_insn (\"cmp\\t%1, %2\", operands); switch (get_attr_length (insn)) { @@ -7525,15 +7554,15 @@ (if_then_else (match_operator 4 "arm_comparison_operator" [(plus:SI - (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1") - (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ")) + (match_operand:SI 2 "s_register_operand" "%l,0,*l,1,1,1") + (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*l,lIJ,lIJ,lIJ")) (const_int 0)]) (label_ref (match_operand 5 "" "")) (pc))) (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m") (plus:SI (match_dup 2) (match_dup 3))) - (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))] + (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))] "TARGET_THUMB1 && (GET_CODE (operands[4]) == EQ || GET_CODE (operands[4]) == NE @@ -7543,8 +7572,7 @@ { rtx cond[3]; - - cond[0] = (which_alternative < 3) ? operands[0] : operands[1]; + cond[0] = (which_alternative < 2) ? operands[0] : operands[1]; cond[1] = operands[2]; cond[2] = operands[3]; @@ -7553,7 +7581,7 @@ else output_asm_insn (\"add\\t%0, %1, %2\", cond); - if (which_alternative >= 3 + if (which_alternative >= 2 && which_alternative < 4) output_asm_insn (\"mov\\t%0, %1\", operands); else if (which_alternative >= 4) @@ -8622,7 +8650,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM + "TARGET_32BIT && (GET_CODE (operands[0]) == SYMBOL_REF) && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" "* @@ -8638,7 +8666,7 @@ (match_operand:SI 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM + "TARGET_32BIT && (GET_CODE (operands[1]) == SYMBOL_REF) && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" "* @@ -8653,7 +8681,7 @@ (match_operand:SI 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB + "TARGET_THUMB1 && GET_CODE (operands[0]) == SYMBOL_REF && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" "bl\\t%a0" @@ -8667,7 +8695,7 @@ (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB + "TARGET_THUMB1 && GET_CODE (operands[1]) == SYMBOL_REF && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" "bl\\t%a1" @@ -8681,7 +8709,7 @@ (match_operand 1 "general_operand" "")) (return) (use (match_operand 2 "" ""))])] - "TARGET_ARM" + "TARGET_32BIT" " { if (operands[2] == NULL_RTX) @@ -8695,7 +8723,7 @@ (match_operand 2 "general_operand" ""))) (return) (use (match_operand 3 "" ""))])] - "TARGET_ARM" + "TARGET_32BIT" " { if (operands[3] == NULL_RTX) @@ -8708,7 +8736,7 @@ (match_operand 1 "" "")) (return) (use (match_operand 2 "" ""))] - "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF" + "TARGET_32BIT && GET_CODE (operands[0]) == SYMBOL_REF" "* return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\"; " @@ -8721,15 +8749,20 @@ (match_operand 2 "" ""))) (return) (use (match_operand 3 "" ""))] - "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF" + "TARGET_32BIT && GET_CODE (operands[1]) == SYMBOL_REF" "* return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\"; " [(set_attr "type" "call")] ) +(define_expand "return" + [(return)] + "TARGET_32BIT && USE_RETURN_INSN (FALSE)" + "") + ;; Often the return insn will be the same as loading from memory, so set attr -(define_insn "return" +(define_insn "*arm_return" [(return)] "TARGET_ARM && USE_RETURN_INSN (FALSE)" "* @@ -11194,6 +11227,107 @@ (set_attr "length" "4")] ) +(define_insn "arm_rev" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))] + "TARGET_EITHER && arm_arch6" + "rev\t%0, %1" + [(set (attr "length") + (if_then_else (eq_attr "is_thumb" "yes") + (const_int 2) + (const_int 4)))] +) + +(define_expand "arm_legacy_rev" + [(set (match_operand:SI 2 "s_register_operand" "") + (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "") + (const_int 16)) + (match_dup 1))) + (set (match_dup 2) + (lshiftrt:SI (match_dup 2) + (const_int 8))) + (set (match_operand:SI 3 "s_register_operand" "") + (rotatert:SI (match_dup 1) + (const_int 8))) + (set (match_dup 2) + (and:SI (match_dup 2) + (const_int -65281))) + (set (match_operand:SI 0 "s_register_operand" "") + (xor:SI (match_dup 3) + (match_dup 2)))] + "TARGET_32BIT" + "" +) + +;; Reuse temporaries to keep register pressure down. +(define_expand "thumb_legacy_rev" + [(set (match_operand:SI 2 "s_register_operand" "") + (ashift:SI (match_operand:SI 1 "s_register_operand" "") + (const_int 24))) + (set (match_operand:SI 3 "s_register_operand" "") + (lshiftrt:SI (match_dup 1) + (const_int 24))) + (set (match_dup 3) + (ior:SI (match_dup 3) + (match_dup 2))) + (set (match_operand:SI 4 "s_register_operand" "") + (const_int 16)) + (set (match_operand:SI 5 "s_register_operand" "") + (rotatert:SI (match_dup 1) + (match_dup 4))) + (set (match_dup 2) + (ashift:SI (match_dup 5) + (const_int 24))) + (set (match_dup 5) + (lshiftrt:SI (match_dup 5) + (const_int 24))) + (set (match_dup 5) + (ior:SI (match_dup 5) + (match_dup 2))) + (set (match_dup 5) + (rotatert:SI (match_dup 5) + (match_dup 4))) + (set (match_operand:SI 0 "s_register_operand" "") + (ior:SI (match_dup 5) + (match_dup 3)))] + "TARGET_THUMB" + "" +) + +(define_expand "bswapsi2" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))] +"TARGET_EITHER" +" + if (!arm_arch6) + { + if (!optimize_size) + { + rtx op2 = gen_reg_rtx (SImode); + rtx op3 = gen_reg_rtx (SImode); + + if (TARGET_THUMB) + { + rtx op4 = gen_reg_rtx (SImode); + rtx op5 = gen_reg_rtx (SImode); + + emit_insn (gen_thumb_legacy_rev (operands[0], operands[1], + op2, op3, op4, op5)); + } + else + { + emit_insn (gen_arm_legacy_rev (operands[0], operands[1], + op2, op3)); + } + + DONE; + } + else + FAIL; + } + " +) + ;; Load the FPA co-processor patterns (include "fpa.md") ;; Load the Maverick co-processor patterns