Commit 8b63716e by Christophe Lyon Committed by Christophe Lyon

[ARM/FDPIC v6 04/24] [ARM] FDPIC: Add support for FDPIC for arm architecture

The FDPIC register is hard-coded to r9, as defined in the ABI.

We have to disable tailcall optimizations if we don't know if the
target function is in the same module. If not, we have to set r9 to
the value associated with the target module.

When generating a symbol address, we have to take into account whether
it is a pointer to data or to a function, because different
relocations are needed.

2019-09-10  Christophe Lyon  <christophe.lyon@st.com>
	Mickaël Guêné <mickael.guene@st.com>

	gcc/
	* config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro
	in FDPIC mode.
	* config/arm/arm-protos.h (arm_load_function_descriptor): Declare
	new function.
	* config/arm/arm.c (arm_option_override): Define pic register to
	FDPIC_REGNUM.
	(arm_function_ok_for_sibcall): Disable sibcall optimization if we
	have no decl or go through PLT.
	(calculate_pic_address_constant): New function.
	(legitimize_pic_address): Call calculate_pic_address_constant.
	(arm_load_pic_register): Handle TARGET_FDPIC.
	(arm_is_segment_info_known): New function.
	(arm_pic_static_addr): Add support for FDPIC.
	(arm_load_function_descriptor): New function.
	(arm_emit_call_insn): Add support for FDPIC.
	(arm_assemble_integer): Add support for FDPIC.
	* config/arm/arm.h (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED):
	Define. (FDPIC_REGNUM): New define.
	* config/arm/arm.md (call): Add support for FDPIC.
	(call_value): Likewise.
	(restore_pic_register_after_call): New pattern.
	(untyped_call): Disable if FDPIC.
	(untyped_return): Likewise.
	* config/arm/unspecs.md (UNSPEC_PIC_RESTORE): New.

	gcc/testsuite/
	* gcc.target/arm/fp16-aapcs-2.c: Adjust scan-assembler-times.
	* gcc.target/arm/fp16-aapcs-4.c: Likewise.



Co-Authored-By: Mickaël Guêné <mickael.guene@st.com>

From-SVN: r275566
parent 45d53c67
2019-09-10 Christophe Lyon <christophe.lyon@st.com> 2019-09-10 Christophe Lyon <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com> Mickaël Guêné <mickael.guene@st.com>
* config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro
in FDPIC mode.
* config/arm/arm-protos.h (arm_load_function_descriptor): Declare
new function.
* config/arm/arm.c (arm_option_override): Define pic register to
FDPIC_REGNUM.
(arm_function_ok_for_sibcall): Disable sibcall optimization if we
have no decl or go through PLT.
(calculate_pic_address_constant): New function.
(legitimize_pic_address): Call calculate_pic_address_constant.
(arm_load_pic_register): Handle TARGET_FDPIC.
(arm_is_segment_info_known): New function.
(arm_pic_static_addr): Add support for FDPIC.
(arm_load_function_descriptor): New function.
(arm_emit_call_insn): Add support for FDPIC.
(arm_assemble_integer): Add support for FDPIC.
* config/arm/arm.h (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED):
Define. (FDPIC_REGNUM): New define.
* config/arm/arm.md (call): Add support for FDPIC.
(call_value): Likewise.
(restore_pic_register_after_call): New pattern.
(untyped_call): Disable if FDPIC.
(untyped_return): Likewise.
* config/arm/unspecs.md (UNSPEC_PIC_RESTORE): New.
2019-09-10 Christophe Lyon <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com>
* config.gcc: Handle arm*-*-uclinuxfdpiceabi. * config.gcc: Handle arm*-*-uclinuxfdpiceabi.
* config/arm/bpabi.h (TARGET_FDPIC_ASM_SPEC): New. * config/arm/bpabi.h (TARGET_FDPIC_ASM_SPEC): New.
(SUBTARGET_EXTRA_ASM_SPEC): Use TARGET_FDPIC_ASM_SPEC. (SUBTARGET_EXTRA_ASM_SPEC): Use TARGET_FDPIC_ASM_SPEC.
......
...@@ -203,6 +203,8 @@ arm_cpu_builtins (struct cpp_reader* pfile) ...@@ -203,6 +203,8 @@ arm_cpu_builtins (struct cpp_reader* pfile)
builtin_define ("__ARM_EABI__"); builtin_define ("__ARM_EABI__");
} }
def_or_undef_macro (pfile, "__FDPIC__", TARGET_FDPIC);
def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV); def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV);
def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV); def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV);
......
...@@ -139,6 +139,7 @@ extern int arm_max_const_double_inline_cost (void); ...@@ -139,6 +139,7 @@ extern int arm_max_const_double_inline_cost (void);
extern int arm_const_double_inline_cost (rtx); extern int arm_const_double_inline_cost (rtx);
extern bool arm_const_double_by_parts (rtx); extern bool arm_const_double_by_parts (rtx);
extern bool arm_const_double_by_immediates (rtx); extern bool arm_const_double_by_immediates (rtx);
extern rtx arm_load_function_descriptor (rtx funcdesc);
extern void arm_emit_call_insn (rtx, rtx, bool); extern void arm_emit_call_insn (rtx, rtx, bool);
bool detect_cmse_nonsecure_call (tree); bool detect_cmse_nonsecure_call (tree);
extern const char *output_call (rtx *); extern const char *output_call (rtx *);
......
...@@ -885,6 +885,9 @@ extern int arm_arch_cmse; ...@@ -885,6 +885,9 @@ extern int arm_arch_cmse;
Pascal), so the following is not true. */ Pascal), so the following is not true. */
#define STATIC_CHAIN_REGNUM 12 #define STATIC_CHAIN_REGNUM 12
/* r9 is the FDPIC register (base register for GOT and FUNCDESC accesses). */
#define FDPIC_REGNUM 9
/* Define this to be where the real frame pointer is if it is not possible to /* Define this to be where the real frame pointer is if it is not possible to
work out the offset between the frame pointer and the automatic variables work out the offset between the frame pointer and the automatic variables
until after register allocation has taken place. FRAME_POINTER_REGNUM until after register allocation has taken place. FRAME_POINTER_REGNUM
...@@ -1941,6 +1944,10 @@ extern unsigned arm_pic_register; ...@@ -1941,6 +1944,10 @@ extern unsigned arm_pic_register;
data addresses in memory. */ data addresses in memory. */
#define PIC_OFFSET_TABLE_REGNUM arm_pic_register #define PIC_OFFSET_TABLE_REGNUM arm_pic_register
/* For FDPIC, the FDPIC register is call-clobbered (otherwise PLT
entries would need to handle saving and restoring it). */
#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED TARGET_FDPIC
/* We can't directly access anything that contains a symbol, /* We can't directly access anything that contains a symbol,
nor can we indirect via the constant pool. One exception is nor can we indirect via the constant pool. One exception is
UNSPEC_TLS, which is always PIC. */ UNSPEC_TLS, which is always PIC. */
......
...@@ -7601,6 +7601,11 @@ ...@@ -7601,6 +7601,11 @@
: !REG_P (callee)) : !REG_P (callee))
XEXP (operands[0], 0) = force_reg (Pmode, callee); XEXP (operands[0], 0) = force_reg (Pmode, callee);
if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[0], 0)))
/* Indirect call: set r9 with FDPIC value of callee. */
XEXP (operands[0], 0)
= arm_load_function_descriptor (XEXP (operands[0], 0));
if (detect_cmse_nonsecure_call (addr)) if (detect_cmse_nonsecure_call (addr))
{ {
pat = gen_nonsecure_call_internal (operands[0], operands[1], pat = gen_nonsecure_call_internal (operands[0], operands[1],
...@@ -7612,10 +7617,33 @@ ...@@ -7612,10 +7617,33 @@
pat = gen_call_internal (operands[0], operands[1], operands[2]); pat = gen_call_internal (operands[0], operands[1], operands[2]);
arm_emit_call_insn (pat, XEXP (operands[0], 0), false); arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
} }
/* Restore FDPIC register (r9) after call. */
if (TARGET_FDPIC)
{
rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
rtx initial_fdpic_reg
= get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
initial_fdpic_reg));
}
DONE; DONE;
}" }"
) )
(define_insn "restore_pic_register_after_call"
[(set (match_operand:SI 0 "s_register_operand" "+r,r")
(unspec:SI [(match_dup 0)
(match_operand:SI 1 "nonimmediate_operand" "r,m")]
UNSPEC_PIC_RESTORE))]
""
"@
mov\t%0, %1
ldr\t%0, %1"
)
(define_expand "call_internal" (define_expand "call_internal"
[(parallel [(call (match_operand 0 "memory_operand") [(parallel [(call (match_operand 0 "memory_operand")
(match_operand 1 "general_operand")) (match_operand 1 "general_operand"))
...@@ -7689,6 +7717,11 @@ ...@@ -7689,6 +7717,11 @@
: !REG_P (callee)) : !REG_P (callee))
XEXP (operands[1], 0) = force_reg (Pmode, callee); XEXP (operands[1], 0) = force_reg (Pmode, callee);
if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[1], 0)))
/* Indirect call: set r9 with FDPIC value of callee. */
XEXP (operands[1], 0)
= arm_load_function_descriptor (XEXP (operands[1], 0));
if (detect_cmse_nonsecure_call (addr)) if (detect_cmse_nonsecure_call (addr))
{ {
pat = gen_nonsecure_call_value_internal (operands[0], operands[1], pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
...@@ -7701,6 +7734,18 @@ ...@@ -7701,6 +7734,18 @@
operands[2], operands[3]); operands[2], operands[3]);
arm_emit_call_insn (pat, XEXP (operands[1], 0), false); arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
} }
/* Restore FDPIC register (r9) after call. */
if (TARGET_FDPIC)
{
rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
rtx initial_fdpic_reg
= get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
initial_fdpic_reg));
}
DONE; DONE;
}" }"
) )
...@@ -8043,7 +8088,7 @@ ...@@ -8043,7 +8088,7 @@
(const_int 0)) (const_int 0))
(match_operand 1 "" "") (match_operand 1 "" "")
(match_operand 2 "" "")])] (match_operand 2 "" "")])]
"TARGET_EITHER" "TARGET_EITHER && !TARGET_FDPIC"
" "
{ {
int i; int i;
...@@ -8110,7 +8155,7 @@ ...@@ -8110,7 +8155,7 @@
(define_expand "untyped_return" (define_expand "untyped_return"
[(match_operand:BLK 0 "memory_operand") [(match_operand:BLK 0 "memory_operand")
(match_operand 1 "" "")] (match_operand 1 "" "")]
"TARGET_EITHER" "TARGET_EITHER && !TARGET_FDPIC"
" "
{ {
int i; int i;
......
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
UNSPEC_SP_SET ; Represent the setting of stack protector's canary UNSPEC_SP_SET ; Represent the setting of stack protector's canary
UNSPEC_SP_TEST ; Represent the testing of stack protector's canary UNSPEC_SP_TEST ; Represent the testing of stack protector's canary
; against the guard. ; against the guard.
UNSPEC_PIC_RESTORE ; Use to restore fdpic register
]) ])
(define_c_enum "unspec" [ (define_c_enum "unspec" [
......
2019-09-10 Christophe Lyon <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com>
* gcc.target/arm/fp16-aapcs-2.c: Adjust scan-assembler-times.
* gcc.target/arm/fp16-aapcs-4.c: Likewise.
2019-09-09 Marek Polacek <polacek@redhat.com> 2019-09-09 Marek Polacek <polacek@redhat.com>
PR c++/84374 - diagnose invalid uses of decltype(auto). PR c++/84374 - diagnose invalid uses of decltype(auto).
......
...@@ -17,5 +17,5 @@ F (__fp16 a, __fp16 b, __fp16 c) ...@@ -17,5 +17,5 @@ F (__fp16 a, __fp16 b, __fp16 c)
} }
/* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } } */ /* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } } */
/* { dg-final { scan-assembler-times {mov\tr1, r0} 1 } } */ /* { dg-final { scan-assembler-times {mov\tr1, r[03]} 1 } } */
/* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } } */ /* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } } */
...@@ -16,5 +16,5 @@ F (__fp16 a, __fp16 b, __fp16 c) ...@@ -16,5 +16,5 @@ F (__fp16 a, __fp16 b, __fp16 c)
} }
/* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } } */ /* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } } */
/* { dg-final { scan-assembler-times {mov\tr1, r0} 1 } } */ /* { dg-final { scan-assembler-times {mov\tr1, r[03]} 1 } } */
/* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } } */ /* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment