* 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
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.
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 *);
{
/* 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)
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;
*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));
}
+/* 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. */
}
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':
#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
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.
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"))]
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.
/* SymbianOS cannot merge entities with vague linkage at runtime. */
#define TARGET_ARM_DYNAMIC_VAGUE_LINKAGE_P false
+
+#define TARGET_DEFAULT_WORD_RELOCATIONS 1
"%{pthread:-lpthread} \
%{shared:-lc} \
%{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+
+#define TARGET_DEFAULT_WORD_RELOCATIONS 1
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
-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
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