OSDN Git Service

2008-09-01 Paul Brook <paul@codesourcery.com>
authorpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Sep 2008 01:44:33 +0000 (01:44 +0000)
committerpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Sep 2008 01:44:33 +0000 (01:44 +0000)
* doc/invoke.texi: Document -mword-relocations.
* config/arm/uclinux-elf.h (TARGET_DEFAULT_WORD_RELOCATIONS): Define.
* config/arm/symbian.h (TARGET_DEFAULT_WORD_RELOCATIONS): Define.
* config/arm/vxworks.h (TARGET_DEFAULT_WORD_RELOCATIONS): Define.
* config/arm/arm.c (arm_split_constant): Use arm_emit_movpair.
(arm_rtx_costs_1, arm_size_rtx_costs): Handle HIGH and LO_SUM.
(arm_emit_movpair): New function.
(arm_print_operand <c>): Handle sybolic addresses.
* config/arm/arm.h (TARGET_USE_MOVT): Define.
(TARGET_DEFAULT_WORD_RELOCATIONS): Define.
* config/arm/arm-protos.h (arm_emit_movpair): Add prototype.
* config/arm/arm.opt: Add -mword-relocations.
* config/arm/arm.md (movsi): Use arm_emit_movpair.
(arm_movt, arm_movw): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139881 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/arm.opt
gcc/config/arm/symbian.h
gcc/config/arm/uclinux-elf.h
gcc/config/arm/vxworks.h
gcc/doc/invoke.texi

index d92bff6..7c4df92 100644 (file)
@@ -1,5 +1,22 @@
 2008-09-01  Paul Brook  <paul@codesourcery.com>
 
+       * doc/invoke.texi: Document -mword-relocations.
+       * config/arm/uclinux-elf.h (TARGET_DEFAULT_WORD_RELOCATIONS): Define.
+       * config/arm/symbian.h (TARGET_DEFAULT_WORD_RELOCATIONS): Define.
+       * config/arm/vxworks.h (TARGET_DEFAULT_WORD_RELOCATIONS): Define.
+       * config/arm/arm.c (arm_split_constant): Use arm_emit_movpair.
+       (arm_rtx_costs_1, arm_size_rtx_costs): Handle HIGH and LO_SUM.
+       (arm_emit_movpair): New function.
+       (arm_print_operand <c>): Handle sybolic addresses.
+       * config/arm/arm.h (TARGET_USE_MOVT): Define.
+       (TARGET_DEFAULT_WORD_RELOCATIONS): Define.
+       * config/arm/arm-protos.h (arm_emit_movpair): Add prototype.
+       * config/arm/arm.opt: Add -mword-relocations.
+       * config/arm/arm.md (movsi): Use arm_emit_movpair.
+       (arm_movt, arm_movw): New.
+
+2008-09-01  Paul Brook  <paul@codesourcery.com>
+
        * config/arm/arm.c (arm_override_options): Set arm_abi earlier.
        Allow Interworking on ARMv4 EABI based targets.
        * config/arm/bpabi.h (TARGET_FIX_V4BX_SPEC): Define.
index d0e408c..ab08ef4 100644 (file)
@@ -123,6 +123,7 @@ extern const char *fp_immediate_constant (rtx);
 extern void arm_emit_call_insn (rtx, rtx);
 extern const char *output_call (rtx *);
 extern const char *output_call_mem (rtx *);
+void arm_emit_movpair (rtx, rtx);
 extern const char *output_mov_long_double_fpa_from_arm (rtx *);
 extern const char *output_mov_long_double_arm_from_fpa (rtx *);
 extern const char *output_mov_long_double_arm_from_arm (rtx *);
index c6128ac..724f1ac 100644 (file)
@@ -1926,14 +1926,22 @@ arm_split_constant (enum rtx_code code, enum machine_mode mode, rtx insn,
            {
              /* Currently SET is the only monadic value for CODE, all
                 the rest are diadic.  */
-             emit_set_insn (target, GEN_INT (val));
+             if (TARGET_USE_MOVT)
+               arm_emit_movpair (target, GEN_INT (val));
+             else
+               emit_set_insn (target, GEN_INT (val));
+
              return 1;
            }
          else
            {
              rtx temp = subtargets ? gen_reg_rtx (mode) : target;
 
-             emit_set_insn (temp, GEN_INT (val));
+             if (TARGET_USE_MOVT)
+               arm_emit_movpair (temp, GEN_INT (val));
+             else
+               emit_set_insn (temp, GEN_INT (val));
+
              /* For MINUS, the value is subtracted from, since we never
                 have subtraction of a constant.  */
              if (code == MINUS)
@@ -5117,6 +5125,10 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
     case SYMBOL_REF:
       return 6;
 
+    case HIGH:
+    case LO_SUM:
+      return (outer == SET) ? 1 : -1;
+
     case CONST_DOUBLE:
       if (arm_const_double_rtx (x) || vfp3_const_double_rtx (x))
        return outer == SET ? 2 : -1;
@@ -5343,6 +5355,13 @@ arm_size_rtx_costs (rtx x, int code, int outer_code, int *total)
       *total = COSTS_N_INSNS (4);
       return true;
 
+    case HIGH:
+    case LO_SUM:
+      /* We prefer constant pool entries to MOVW/MOVT pairs, so bump the
+        cost of these slightly.  */
+      *total = COSTS_N_INSNS (1) + 1;
+      return true;
+
     default:
       if (mode != VOIDmode)
        *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
@@ -9891,6 +9910,14 @@ output_mov_long_double_arm_from_arm (rtx *operands)
 }
 
 
+/* Emit a MOVW/MOVT pair.  */
+void arm_emit_movpair (rtx dest, rtx src)
+{
+  emit_set_insn (dest, gen_rtx_HIGH (SImode, src));
+  emit_set_insn (dest, gen_rtx_LO_SUM (SImode, dest, src));
+}
+
+
 /* Output a move from arm registers to an fpa registers.
    OPERANDS[0] is an fpa register.
    OPERANDS[1] is the first registers of an arm register pair.  */
@@ -12906,10 +12933,21 @@ arm_print_operand (FILE *stream, rtx x, int code)
       }
       return;
 
-    /* An integer without a preceding # sign.  */
+    /* An integer or symbol address without a preceding # sign.  */
     case 'c':
-      gcc_assert (GET_CODE (x) == CONST_INT);
-      fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
+      switch (GET_CODE (x))
+       {
+       case CONST_INT:
+         fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
+         break;
+
+       case SYMBOL_REF:
+         output_addr_const (stream, x);
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
       return;
 
     case 'B':
index a8820cb..e12c3f9 100644 (file)
@@ -241,6 +241,9 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
 #define TARGET_INT_SIMD \
   (TARGET_32BIT && arm_arch6 && arm_arch_notm)
 
+/* Should MOVW/MOVT be used in preference to a constant pool.  */
+#define TARGET_USE_MOVT (arm_arch_thumb2 && !optimize_size)
+
 /* We could use unified syntax for arm mode, but for now we just use it
    for Thumb-2.  */
 #define TARGET_UNIFIED_ASM TARGET_THUMB2
@@ -1962,6 +1965,11 @@ typedef struct
    SYMBOL's section.  */
 #define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 0
 
+/* Nonzero if all target requires all absolute relocations be R_ARM_ABS32.  */
+#ifndef TARGET_DEFAULT_WORD_RELOCATIONS
+#define TARGET_DEFAULT_WORD_RELOCATIONS 0
+#endif
+
 /* Nonzero if the constant value X is a legitimate general operand.
    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
 
index 204f8a4..c5708d6 100644 (file)
                               optimize && can_create_pseudo_p ());
           DONE;
         }
+
+      if (TARGET_USE_MOVT && !target_word_relocations
+         && GET_CODE (operands[1]) == SYMBOL_REF
+         && !flag_pic && !arm_tls_referenced_p (operands[1]))
+       {
+         arm_emit_movpair (operands[0], operands[1]);
+         DONE;
+       }
     }
   else /* TARGET_THUMB1...  */
     {
   "
 )
 
+;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
+;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
+;; so this does not matter.
+(define_insn "*arm_movt"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
+       (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                  (match_operand:SI 2 "general_operand"      "i")))]
+  "TARGET_32BIT"
+  "movt%?\t%0, #:upper16:%c2"
+  [(set_attr "predicable" "yes")
+   (set_attr "length" "4")]
+)
+
+(define_insn "*arm_movw"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
+       (high:SI (match_operand:SI 1 "general_operand"      "i")))]
+  "TARGET_32BIT"
+  "movw%?\t%0, #:lower16:%c1"
+  [(set_attr "predicable" "yes")
+   (set_attr "length" "4")]
+)
+
 (define_insn "*arm_movsi_insn"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
        (match_operand:SI 1 "general_operand"      "rk, I,K,N,mi,rk"))]
index 2b005e4..c8bdcf8 100644 (file)
@@ -156,3 +156,7 @@ Assume big endian bytes, little endian words
 mvectorize-with-neon-quad
 Target Report Mask(NEON_VECTORIZE_QUAD)
 Use Neon quad-word (rather than double-word) registers for vectorization
+
+mword-relocations
+Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS)
++Only generate absolute relocations on word sized values.
index 3e583b3..af92c72 100644 (file)
 
 /* SymbianOS cannot merge entities with vague linkage at runtime.  */
 #define TARGET_ARM_DYNAMIC_VAGUE_LINKAGE_P false
+
+#define TARGET_DEFAULT_WORD_RELOCATIONS 1
index 98a7850..89b96f2 100644 (file)
@@ -83,3 +83,5 @@
   "%{pthread:-lpthread} \
    %{shared:-lc} \
    %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+
+#define TARGET_DEFAULT_WORD_RELOCATIONS 1
index 4416557..a7610ac 100644 (file)
@@ -113,3 +113,6 @@ along with GCC; see the file COPYING3.  If not see
    cannot allow arbitrary offsets for shared libraries either.  */
 #undef ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
 #define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
+
+#undef TARGET_DEFAULT_WORD_RELOCATIONS
+#define TARGET_DEFAULT_WORD_RELOCATIONS 1
index 33070a0..aa73f82 100644 (file)
@@ -448,7 +448,8 @@ Objective-C and Objective-C++ Dialects}.
 -mthumb  -marm @gol
 -mtpcs-frame  -mtpcs-leaf-frame @gol
 -mcaller-super-interworking  -mcallee-super-interworking @gol
--mtp=@var{name}}
+-mtp=@var{name}
+-mword-relocations}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu}  -msize  -minit-stack=@var{n}  -mno-interrupts @gol
@@ -8910,6 +8911,13 @@ models are @option{soft}, which generates calls to @code{__aeabi_read_tp},
 best available method for the selected processor.  The default setting is
 @option{auto}.
 
+@item -mword-relocations
+@opindex mword-relocations
+Only generate absolute relocations on word sized values (i.e. R_ARM_ABS32).
+This is enabled by default on targets (uClinux, SymbianOS) where the runtime
+loader imposes this restriction, and when @option{-fpic} or @option{-fPIC}
+is speficied.
+
 @end table
 
 @node AVR Options