Microblaze Target: PIC data text relative

2018-04-30 Andrew Sadek  <andrew.sadek.se@gmail.com>

gcc/ChangeLog:
	* config/microblaze/microblaze.opt: add new option -mpic-data-text-rel.
	* config/microblaze/microblaze-protos.h (microblaze_constant_address_p):
	Add declaration.
	* gcc/config/microblaze/microblaze.h (microblaze_constant_address_p):
	CONSTANT_ADDRESS_P definition to microblaze_constant_address_p.
	* config/microblaze/microblaze.c (TARGET_PIC_DATA_TEXT_REL):
	New addressing mode for data-text relative position indepenedent code.
	(microblaze_classify_unspec): add 'UNSPEC_TEXT' case ->
	'ADDRESS_SYMBOLIC_TXT_REL'.
	(microblaze_classify_address): Add handling for UNSPEC + CONST_INT.
	(microblaze_legitimate_pic_operand): Exclude function calls from
	pic operands in case of TARGET_PIC_DATA_TEXT_REL option.
	(microblaze_legitimize_address): Generate 'UNSPEC_TEXT' for all possible
	addresses cases.
	(microblaze_address_insns): Add 'ADDRESS_SYMBOLIC_TXT_REL' case.
	(print_operand): Add 'ADDRESS_SYMBOLIC_TXT_REL' case.
	(print_operand_address): Add 'ADDRESS_SYMBOLIC_TXT_REL' case + handling
	for 'address + offset'.
	(microblaze_expand_prologue): Add new function prologue call for
	'r20' assignation.
	(microblaze_asm_generate_pic_addr_dif_vec): Override new target hook
	'TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC' to disable address diff vector
	table in case of TARGET_PIC_DATA_TEXT_REL.
	(expand_pic_symbol_ref): Add handling for 'UNSPEC_TEXT'.
	* gcc/config/microblaze/microblaze.md (TARGET_PIC_DATA_TEXT_REL):
	Add new macros 'UNSPEC_TEXT',
	'UNSPEC_SET_TEXT' + add rule for setting r20 in function prologue
	+ exclude function calls from 'UNSPEC_PLT' in case of data text
	relative mode.
	* doc/tm.texi.in (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC): Add
	new target hook for generating address diff vector tables in case of
	flag_pic.
	* doc/tm.texi : Regenerate.
	* stmt.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC): Append new condition
	'targetm.asm_out.generate_pic_addr_diff_vec' to flag_pic in case
	of addr diff vector generation.
	* target.def (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC): Add
	target hook definition.
	* targhooks.h, gcc/targhooks.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
	Add default function for generate_pic_addr_diff_vec -> flag_pic.
	* doc/invoke.texi (Add new pic option): Add new microblaze pic
	option for data text relative.

testsuite/ChangeLog:
	* gcc.target/microblaze/others/data_var1.c: Include
	PIC case of r20 base register.
	* gcc.target/microblaze/others/data_var2.c: Ditto.
	* gcc.target/microblaze/others/picdtr.c: Add new
	test case for -mpic-is-data-text-relative.
	* gcc.target/microblaze/others/sdata_var1.c: Add
	* gcc.target/microblaze/others/sdata_var2.c: Ditto.
	* gcc.target/microblaze/others/sdata_var3.c: Ditto.
	* gcc.target/microblaze/others/sdata_var4.c: Ditto.
	* gcc.target/microblaze/others/sdata_var5.c: Ditto.
	* gcc.target/microblaze/others/sdata_var6.c: Ditto.
	* gcc.target/microblaze/others/string_cst1_gpopt.c:	Ditto.
	* gcc.target/microblaze/others/string_cst2_gpopt.c: Ditto.

From-SVN: r259758
This commit is contained in:
Andrew Sadek 2018-04-30 11:16:55 +00:00 committed by Michael Eager
parent 5885f02733
commit af1682fc3a
24 changed files with 318 additions and 55 deletions

View File

@ -1,3 +1,50 @@
2018-04-30 Andrew Sadek <andrew.sadek.se@gmail.com>
Microblaze Target: PIC data text relative
* config/microblaze/microblaze.opt: add new option -mpic-data-text-rel.
* config/microblaze/microblaze-protos.h (microblaze_constant_address_p):
Add declaration.
* gcc/config/microblaze/microblaze.h (microblaze_constant_address_p):
CONSTANT_ADDRESS_P definition to microblaze_constant_address_p.
* config/microblaze/microblaze.c (TARGET_PIC_DATA_TEXT_REL):
New addressing mode for data-text relative position indepenedent code.
(microblaze_classify_unspec): add 'UNSPEC_TEXT' case ->
'ADDRESS_SYMBOLIC_TXT_REL'.
(microblaze_classify_address): Add handling for UNSPEC + CONST_INT.
(microblaze_legitimate_pic_operand): Exclude function calls from
pic operands in case of TARGET_PIC_DATA_TEXT_REL option.
(microblaze_legitimize_address): Generate 'UNSPEC_TEXT' for all possible
addresses cases.
(microblaze_address_insns): Add 'ADDRESS_SYMBOLIC_TXT_REL' case.
(print_operand): Add 'ADDRESS_SYMBOLIC_TXT_REL' case.
(print_operand_address): Add 'ADDRESS_SYMBOLIC_TXT_REL' case + handling
for 'address + offset'.
(microblaze_expand_prologue): Add new function prologue call for
'r20' assignation.
(microblaze_asm_generate_pic_addr_dif_vec): Override new target hook
'TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC' to disable address diff vector
table in case of TARGET_PIC_DATA_TEXT_REL.
(expand_pic_symbol_ref): Add handling for 'UNSPEC_TEXT'.
* gcc/config/microblaze/microblaze.md (TARGET_PIC_DATA_TEXT_REL):
Add new macros 'UNSPEC_TEXT',
'UNSPEC_SET_TEXT' + add rule for setting r20 in function prologue
+ exclude function calls from 'UNSPEC_PLT' in case of data text
relative mode.
* doc/tm.texi.in (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC): Add
new target hook for generating address diff vector tables in case of
flag_pic.
* doc/tm.texi : Regenerate.
* stmt.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC): Append new condition
'targetm.asm_out.generate_pic_addr_diff_vec' to flag_pic in case
of addr diff vector generation.
* target.def (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC): Add
target hook definition.
* targhooks.h, gcc/targhooks.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
Add default function for generate_pic_addr_diff_vec -> flag_pic.
* doc/invoke.texi (Add new pic option): Add new microblaze pic
option for data text relative.
2018-04-30 Richard Biener <rguenther@suse.de>
* tree-chrec.h (evolution_function_is_constant_p): Remove

View File

@ -24,6 +24,7 @@
#ifdef RTX_CODE
extern int pic_address_needs_scratch (rtx);
extern bool microblaze_constant_address_p (rtx x);
extern void expand_block_move (rtx *);
extern void microblaze_expand_prologue (void);
extern void microblaze_expand_epilogue (void);

View File

@ -91,7 +91,8 @@ enum microblaze_address_type
ADDRESS_SYMBOLIC,
ADDRESS_GOTOFF,
ADDRESS_PLT,
ADDRESS_TLS
ADDRESS_TLS,
ADDRESS_SYMBOLIC_TXT_REL
};
/* Classifies symbols
@ -650,6 +651,10 @@ microblaze_classify_unspec (struct microblaze_address_info *info, rtx x)
info->type = ADDRESS_TLS;
info->tls_type = tls_reloc (INTVAL (XVECEXP (x, 0, 1)));
}
else if (XINT (x, 1) == UNSPEC_TEXT)
{
info->type = ADDRESS_SYMBOLIC_TXT_REL;
}
else
{
return false;
@ -701,8 +706,10 @@ get_base_reg (rtx x)
}
/* Return true if X is a valid address for machine mode MODE. If it is,
fill in INFO appropriately. STRICT is true if we should only accept
hard base registers.
fill in INFO appropriately.
STRICT > 0 if we should only accept hard base registers.
STRICT = 2 if the operand address is being printed thus
function has been called by print_operand_address.
type regA regB offset symbol
@ -728,6 +735,7 @@ microblaze_classify_address (struct microblaze_address_info *info, rtx x,
{
rtx xplus0;
rtx xplus1;
rtx offset;
info->type = ADDRESS_INVALID;
info->regA = NULL;
@ -735,6 +743,7 @@ microblaze_classify_address (struct microblaze_address_info *info, rtx x,
info->offset = NULL;
info->symbol = NULL;
info->symbol_type = SYMBOL_TYPE_INVALID;
offset = NULL;
switch (GET_CODE (x))
{
@ -795,8 +804,13 @@ microblaze_classify_address (struct microblaze_address_info *info, rtx x,
/* for (plus x const_int) just look at x. */
if (GET_CODE (xconst0) == PLUS
&& GET_CODE (XEXP (xconst0, 1)) == CONST_INT
&& SMALL_INT (XEXP (xconst0, 1)))
&& (SMALL_INT (XEXP (xconst0, 1))
|| GET_CODE (XEXP (xconst0, 0)) == UNSPEC))
{
/* Hold CONST_INT Value in offset in case of
UNSPEC + CONST_INT. */
offset = XEXP (xconst0, 1);
/* This is ok as info->symbol is set to xplus1 the full
const-expression below. */
xconst0 = XEXP (xconst0, 0);
@ -814,6 +828,15 @@ microblaze_classify_address (struct microblaze_address_info *info, rtx x,
return true;
}
if (GET_CODE (xconst0) == UNSPEC && TARGET_PIC_DATA_TEXT_REL)
{
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
return false;
info->offset = offset;
return microblaze_classify_unspec (info, xconst0);
}
/* Not base + symbol || base + UNSPEC. */
return false;
@ -858,6 +881,15 @@ microblaze_classify_address (struct microblaze_address_info *info, rtx x,
return !(flag_pic && pic_address_needs_scratch (x));
}
/* Avoid error in print_operand_address in case UNSPEC
is removed from SYMBOL or LABEL REFS during optimization. */
if ((GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
&& flag_pic && TARGET_PIC_DATA_TEXT_REL && strict == 2)
{
info->type = ADDRESS_SYMBOLIC_TXT_REL;
return true;
}
if (flag_pic == 2)
return false;
else if (microblaze_tls_symbol_p(x))
@ -893,6 +925,15 @@ microblaze_legitimate_address_p (machine_mode mode, rtx x, bool strict)
return microblaze_classify_address (&addr, x, mode, strict);
}
bool
microblaze_constant_address_p (rtx x)
{
return ((GET_CODE (x) == LABEL_REF) || (GET_CODE (x) == SYMBOL_REF)
|| GET_CODE (x) == CONST_INT
|| (GET_CODE (x) == CONST
&& ! (flag_pic && pic_address_needs_scratch (x))));
}
int
microblaze_valid_pic_const (rtx x)
{
@ -910,7 +951,8 @@ microblaze_valid_pic_const (rtx x)
int
microblaze_legitimate_pic_operand (rtx x)
{
if (flag_pic == 2 && (symbol_mentioned_p(x) || label_mentioned_p(x)))
if (flag_pic == 2 && (symbol_mentioned_p (x) || label_mentioned_p (x))
&& !(TARGET_PIC_DATA_TEXT_REL && call_insn_operand (x,VOIDmode)))
return 0;
if (microblaze_tls_referenced_p(x))
@ -1024,17 +1066,35 @@ microblaze_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
}
else if (flag_pic == 2)
{
rtx pic_ref, reg;
reg = gen_reg_rtx (Pmode);
if (!TARGET_PIC_DATA_TEXT_REL)
{
rtx pic_ref, reg;
reg = gen_reg_rtx (Pmode);
pic_ref = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xplus1),
UNSPEC_GOTOFF);
pic_ref = gen_rtx_CONST (Pmode, pic_ref);
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pic_ref);
pic_ref = gen_const_mem (Pmode, pic_ref);
emit_move_insn (reg, pic_ref);
result = gen_rtx_PLUS (Pmode, xplus0, reg);
return result;
pic_ref = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, xplus1),
UNSPEC_GOTOFF);
pic_ref = gen_rtx_CONST (Pmode, pic_ref);
pic_ref = gen_rtx_PLUS (Pmode,
pic_offset_table_rtx, pic_ref);
pic_ref = gen_const_mem (Pmode, pic_ref);
emit_move_insn (reg, pic_ref);
result = gen_rtx_PLUS (Pmode, xplus0, reg);
return result;
}
else
{
rtx pic_ref, reg;
reg = gen_reg_rtx (Pmode);
pic_ref = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, xplus1),
UNSPEC_TEXT);
pic_ref = gen_rtx_CONST (Pmode, pic_ref);
emit_insn (gen_addsi3 (reg,
pic_offset_table_rtx, xplus0));
result = gen_rtx_PLUS (Pmode, reg, pic_ref);
return result;
}
}
}
}
@ -1047,19 +1107,31 @@ microblaze_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
{
reg = microblaze_legitimize_tls_address (xinsn, NULL_RTX);
}
else
else if (flag_pic == 2)
{
rtx pic_ref;
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
if (!TARGET_PIC_DATA_TEXT_REL)
{
rtx pic_ref;
pic_ref = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xinsn), UNSPEC_GOTOFF);
pic_ref = gen_rtx_CONST (Pmode, pic_ref);
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pic_ref);
pic_ref = gen_const_mem (Pmode, pic_ref);
reg = pic_ref;
}
pic_ref = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xinsn), UNSPEC_GOTOFF);
pic_ref = gen_rtx_CONST (Pmode, pic_ref);
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pic_ref);
pic_ref = gen_const_mem (Pmode, pic_ref);
reg = pic_ref;
}
else
{
rtx pic_ref;
pic_ref = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xinsn), UNSPEC_TEXT);
pic_ref = gen_rtx_CONST (Pmode, pic_ref);
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pic_ref);
reg = pic_ref;
}
}
return reg;
}
@ -1388,6 +1460,7 @@ microblaze_address_insns (rtx x, machine_mode mode)
case ADDRESS_REG_INDEX:
return 1;
case ADDRESS_SYMBOLIC:
case ADDRESS_SYMBOLIC_TXT_REL:
case ADDRESS_GOTOFF:
return 2;
case ADDRESS_TLS:
@ -2066,7 +2139,7 @@ compute_frame_size (HOST_WIDE_INT size)
total_size = var_size + args_size;
if (flag_pic == 2)
if (flag_pic == 2 && !TARGET_PIC_DATA_TEXT_REL)
/* force setting GOT. */
df_set_regs_ever_live (MB_ABI_PIC_ADDR_REGNUM, true);
@ -2322,6 +2395,7 @@ print_operand (FILE * file, rtx op, int letter)
case ADDRESS_REG:
case ADDRESS_CONST_INT:
case ADDRESS_SYMBOLIC:
case ADDRESS_SYMBOLIC_TXT_REL:
case ADDRESS_GOTOFF:
case ADDRESS_TLS:
fputs ("i", file);
@ -2489,7 +2563,7 @@ print_operand_address (FILE * file, rtx addr)
{
struct microblaze_address_info info;
enum microblaze_address_type type;
if (!microblaze_classify_address (&info, addr, GET_MODE (addr), 1))
if (!microblaze_classify_address (&info, addr, GET_MODE (addr), 2))
fatal_insn ("insn contains an invalid address !", addr);
type = info.type;
@ -2515,6 +2589,7 @@ print_operand_address (FILE * file, rtx addr)
output_addr_const (file, info.offset);
break;
case ADDRESS_SYMBOLIC:
case ADDRESS_SYMBOLIC_TXT_REL:
case ADDRESS_GOTOFF:
case ADDRESS_PLT:
case ADDRESS_TLS:
@ -2529,6 +2604,16 @@ print_operand_address (FILE * file, rtx addr)
{
fputs ("@PLT", file);
}
else if (type == ADDRESS_SYMBOLIC_TXT_REL)
{
if (info.offset != NULL && CONST_INT_P (info.offset)
&& INTVAL (info.offset) > 0)
{
fprintf (file, "+");
output_addr_const (file, info.offset);
}
fputs ("@TXTREL", file);
}
else if (type == ADDRESS_TLS)
{
switch (info.tls_type)
@ -2888,7 +2973,6 @@ microblaze_expand_prologue (void)
if (flag_stack_usage_info)
current_function_static_stack_size = fsiz;
/* If this function is a varargs function, store any registers that
would normally hold arguments ($5 - $10) on the stack. */
if (((TYPE_ARG_TYPES (fntype) != 0
@ -2913,7 +2997,6 @@ microblaze_expand_prologue (void)
offset += GET_MODE_SIZE (SImode);
}
}
if (fsiz > 0)
@ -2960,8 +3043,18 @@ microblaze_expand_prologue (void)
if ((flag_pic == 2 || TLS_NEEDS_GOT )
&& df_regs_ever_live_p (MB_ABI_PIC_ADDR_REGNUM))
{
SET_REGNO (pic_offset_table_rtx, MB_ABI_PIC_ADDR_REGNUM);
emit_insn (gen_set_got (pic_offset_table_rtx)); /* setting GOT. */
if ((flag_pic == 2 && !TARGET_PIC_DATA_TEXT_REL) || TLS_NEEDS_GOT)
{
SET_REGNO (pic_offset_table_rtx, MB_ABI_PIC_ADDR_REGNUM);
/* setting GOT. */
emit_insn (gen_set_got (pic_offset_table_rtx));
}
else
{
SET_REGNO (pic_offset_table_rtx, MB_ABI_PIC_ADDR_REGNUM);
/* setting start of text. */
emit_insn (gen_set_text (pic_offset_table_rtx));
}
}
/* If we are profiling, make sure no instructions are scheduled before
@ -3154,6 +3247,14 @@ microblaze_elf_in_small_data_p (const_tree decl)
return (size > 0 && size <= microblaze_section_threshold);
}
/* We need to disable address diff vectors in
case of pic data text relative mode. */
static bool
microblaze_gen_pic_addr_dif_vec (void)
{
return (flag_pic && !TARGET_PIC_DATA_TEXT_REL);
}
static section *
microblaze_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
@ -3187,10 +3288,19 @@ static rtx
expand_pic_symbol_ref (machine_mode mode ATTRIBUTE_UNUSED, rtx op)
{
rtx result;
result = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op), UNSPEC_GOTOFF);
bool isFunc = (GET_CODE (op) == SYMBOL_REF
&& (SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_FUNCTION));
result = (!TARGET_PIC_DATA_TEXT_REL)
? gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op), UNSPEC_GOTOFF)
: gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op), UNSPEC_TEXT);
result = gen_rtx_CONST (Pmode, result);
result = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, result);
result = gen_const_mem (Pmode, result);
result = (TARGET_PIC_DATA_TEXT_REL && isFunc)
? gen_rtx_PLUS (Pmode, gen_raw_REG (Pmode,
get_base_reg (op)), result)
: gen_rtx_PLUS (Pmode, pic_offset_table_rtx, result);
result = (!TARGET_PIC_DATA_TEXT_REL)
? gen_const_mem (Pmode, result) : result;
return result;
}
@ -3294,10 +3404,37 @@ microblaze_expand_move (machine_mode mode, rtx operands[])
if (reload_in_progress)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
result = expand_pic_symbol_ref (mode, op1);
if (TARGET_PIC_DATA_TEXT_REL && GET_CODE (op0) == REG
&& REGNO (op0) >= FIRST_PSEUDO_REGISTER)
result = force_reg (SImode, result);
emit_move_insn (op0, result);
return true;
}
}
if (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1,1)) == CONST)
{
rtx p0, p1, result, temp;
p0 = XEXP (XEXP (op1,1), 0);
if (GET_CODE (p0) == PLUS)
{
p1 = XEXP (p0, 1);
p0 = XEXP (p0, 0);
}
if (GET_CODE (p0) == UNSPEC && GET_CODE (p1) == CONST_INT
&& flag_pic && TARGET_PIC_DATA_TEXT_REL)
{
result = gen_rtx_CONST (Pmode, p0);
result = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, result);
temp = force_reg (SImode, result);
emit_move_insn (op0, gen_rtx_PLUS (SImode, temp, p1));
return true;
}
}
/* Handle Case of (const (plus symbol const_int)). */
if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1,0)) == PLUS)
{
@ -3912,6 +4049,9 @@ microblaze_starting_frame_offset (void)
#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P microblaze_legitimate_constant_p
#undef TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC
#define TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC microblaze_gen_pic_addr_dif_vec
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG microblaze_machine_dependent_reorg

View File

@ -518,11 +518,7 @@ typedef struct microblaze_args
/* Identify valid constant addresses. Exclude if PIC addr which
needs scratch register. */
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT \
|| (GET_CODE (X) == CONST \
&& ! (flag_pic && pic_address_needs_scratch (X))))
#define CONSTANT_ADDRESS_P(X) microblaze_constant_address_p(X)
/* Define this, so that when PIC, reload won't try to reload invalid
addresses which require two reload registers. */

View File

@ -41,6 +41,8 @@
(UNSPEC_CMP 104) ;; signed compare
(UNSPEC_CMPU 105) ;; unsigned compare
(UNSPEC_TLS 106) ;; jump table
(UNSPEC_SET_TEXT 107) ;; set text start
(UNSPEC_TEXT 108) ;; data text relative
])
(define_c_enum "unspec" [
@ -1848,7 +1850,7 @@
{
gcc_assert (GET_MODE (operands[0]) == Pmode);
if (!flag_pic)
if (!flag_pic || TARGET_PIC_DATA_TEXT_REL)
emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
else
emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
@ -2053,7 +2055,8 @@
{
rtx addr = XEXP (operands[0], 0);
if (flag_pic == 2 && GET_CODE (addr) == SYMBOL_REF
if (flag_pic == 2 && !TARGET_PIC_DATA_TEXT_REL
&& GET_CODE (addr) == SYMBOL_REF
&& !SYMBOL_REF_LOCAL_P (addr))
{
rtx temp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PLT);
@ -2156,7 +2159,8 @@
{
rtx addr = XEXP (operands[1], 0);
if (flag_pic == 2 && GET_CODE (addr) == SYMBOL_REF
if (flag_pic == 2 && !TARGET_PIC_DATA_TEXT_REL
&& GET_CODE (addr) == SYMBOL_REF
&& !SYMBOL_REF_LOCAL_P (addr))
{
rtx temp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PLT);
@ -2313,6 +2317,18 @@
[(set_attr "type" "multi")
(set_attr "length" "12")])
;; The insn to set TEXT.
;; The hardcoded number "8" accounts for $pc difference
;; between "mfs" and "addik" instructions.
(define_insn "set_text"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI[(const_int 0)] UNSPEC_SET_TEXT))]
""
"mfs\t%0,rpc\n\taddik\t%0,%0,8@TXTPCREL"
[(set_attr "type" "multi")
(set_attr "length" "12")])
;; This insn gives the count of leading number of zeros for the second
;; operand and stores the result in first operand.
(define_insn "clzsi2"

View File

@ -127,5 +127,9 @@ mxl-prefetch
Target Mask(PREFETCH)
Use hardware prefetch instruction
mpic-data-is-text-relative
Target Mask(PIC_DATA_TEXT_REL)
Data referenced by offset from start of text instead of GOT (with -fPIC/-fPIE).
mxl-mode-xilkernel
Target

View File

@ -867,7 +867,8 @@ Objective-C and Objective-C++ Dialects}.
-mmemcpy -mxl-soft-mul -mxl-soft-div -mxl-barrel-shift @gol
-mxl-pattern-compare -mxl-stack-check -mxl-gp-opt -mno-clearbss @gol
-mxl-multiply-high -mxl-float-convert -mxl-float-sqrt @gol
-mbig-endian -mlittle-endian -mxl-reorder -mxl-mode-@var{app-model}}
-mbig-endian -mlittle-endian -mxl-reorder -mxl-mode-@var{app-model}
-mpic-data-is-text-relative}
@emph{MIPS Options}
@gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol
@ -20113,6 +20114,12 @@ Select application model @var{app-model}. Valid models are
@item executable
normal executable (default), uses startup code @file{crt0.o}.
@item -mpic-data-is-text-relative
@opindex mpic-data-is-text-relative
Assume that the displacement between the text and data segments is fixed
at static link time. This allows data to be referenced by offset from start of
text address instead of GOT since PC-relative addressing is not supported.
@item xmdstub
for use with Xilinx Microprocessor Debugger (XMD) based
software intrusive debug agent called xmdstub. This uses startup file

View File

@ -7491,6 +7491,14 @@ when the target cannot support (some kinds of) dynamic relocations
in read-only sections even in executables.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC (void)
Return true to generate ADDR_DIF_VEC table
or false to generate ADDR_VEC table for jumps in case of -fPIC.
The default version of this function returns true if flag_pic
equals true and false otherwise
@end deftypefn
@deftypefn {Target Hook} {section *} TARGET_ASM_SELECT_SECTION (tree @var{exp}, int @var{reloc}, unsigned HOST_WIDE_INT @var{align})
Return the section into which @var{exp} should be placed. You can
assume that @var{exp} is either a @code{VAR_DECL} node or a constant of

View File

@ -4922,6 +4922,8 @@ This macro is irrelevant if there is no separate readonly data section.
@hook TARGET_ASM_RELOC_RW_MASK
@hook TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC
@hook TARGET_ASM_SELECT_SECTION
@defmac USE_SELECT_SECTION_FOR_FUNCTIONS

View File

@ -853,7 +853,8 @@ emit_case_dispatch_table (tree index_expr, tree index_type,
/* Output the table. */
emit_label (table_label);
if (CASE_VECTOR_PC_RELATIVE || flag_pic)
if (CASE_VECTOR_PC_RELATIVE
|| (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
gen_rtx_LABEL_REF (Pmode,
table_label),

View File

@ -507,6 +507,18 @@ in read-only sections even in executables.",
int, (void),
default_reloc_rw_mask)
/* Return a flag for either generating ADDR_DIF_VEC table
or ADDR_VEC table for jumps in case of -fPIC/-fPIE. */
DEFHOOK
(generate_pic_addr_diff_vec,
"Return true to generate ADDR_DIF_VEC table\n\
or false to generate ADDR_VEC table for jumps in case of -fPIC.\n\
\n\
The default version of this function returns true if flag_pic\n\
equals true and false otherwise",
bool, (void),
default_generate_pic_addr_diff_vec)
/* Return a section for EXP. It may be a DECL or a constant. RELOC
is nonzero if runtime relocations must be applied; bit 1 will be
set if the runtime relocations require non-local name resolution.

View File

@ -1196,6 +1196,15 @@ default_reloc_rw_mask (void)
return flag_pic ? 3 : 0;
}
/* By default, address diff vectors are generated
for jump tables when flag_pic is true. */
bool
default_generate_pic_addr_diff_vec (void)
{
return flag_pic;
}
/* By default, do no modification. */
tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED,
tree id)

View File

@ -175,6 +175,7 @@ extern machine_mode default_secondary_memory_needed_mode (machine_mode);
extern void default_target_option_override (void);
extern void hook_void_bitmap (bitmap);
extern int default_reloc_rw_mask (void);
extern bool default_generate_pic_addr_diff_vec (void);
extern tree default_mangle_decl_assembler_name (tree, tree);
extern tree default_emutls_var_fields (tree, tree *);
extern tree default_emutls_var_init (tree, tree, tree);

View File

@ -1,3 +1,23 @@
2018-04-30 Andrew Sadek <andrew.sadek.se@gmail.com>
Microblaze Target: PIC data text relative
* gcc.target/microblaze/others/data_var1.c: Include
PIC case of r20 base register.
* gcc.target/microblaze/others/data_var2.c: Ditto.
* gcc.target/microblaze/others/picdtr.c: Add new
test case for -mpic-is-data-text-relative.
* gcc.target/microblaze/others/sdata_var1.c: Add
* gcc.target/microblaze/others/sdata_var2.c: Ditto.
* gcc.target/microblaze/others/sdata_var3.c: Ditto.
* gcc.target/microblaze/others/sdata_var4.c: Ditto.
* gcc.target/microblaze/others/sdata_var5.c: Ditto.
* gcc.target/microblaze/others/sdata_var6.c: Ditto.
* gcc.target/microblaze/others/string_cst1_gpopt.c:
Ditto.
* gcc.target/microblaze/others/string_cst2_gpopt.c:
Ditto.
2018-04-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/28364

View File

@ -3,6 +3,6 @@ int global;
int testfunc ()
{
/* { dg-final { scan-assembler "\lwi\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),r0" } } */
/* { dg-final { scan-assembler "\lwi\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),r(0|20)" } } */
return global;
}

View File

@ -3,6 +3,6 @@ int global = 10;
int testfunc ()
{
/* { dg-final { scan-assembler "\lwi\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),r0" } } */
/* { dg-final { scan-assembler "\lwi\tr(\[0-9]\|\[1-2]\[0-9]\|3\[0-1]),r(0|20)" } } */
return global;
}

View File

@ -1,4 +1,4 @@
/* { dg-options "-mxl-gp-opt" } */
/* { dg-options "-mxl-gp-opt -fno-pic" } */
/* { dg-final { scan-assembler "\.sbss\[^2]+" } } */
typedef int Boolean;

View File

@ -1,4 +1,4 @@
/* { dg-options "-mxl-gp-opt" } */
/* { dg-options "-mxl-gp-opt -fno-pic" } */
/* { dg-final { scan-assembler "\.sdata\[^2]+" } } */
int global = 10;

View File

@ -1,4 +1,4 @@
/* { dg-options "-mxl-gp-opt" } */
/* { dg-options "-mxl-gp-opt -fno-pic" } */
extern int a;

View File

@ -1,4 +1,4 @@
/* { dg-options "-mxl-gp-opt -G 16" } */
/* { dg-options "-mxl-gp-opt -G 16 -fno-pic" } */
/* { dg-final { scan-assembler "\.sbss\[^2]+" } } */
struct test_s {

View File

@ -1,4 +1,4 @@
/* { dg-options "-mxl-gp-opt -G 16" } */
/* { dg-options "-mxl-gp-opt -G 16 -fno-pic" } */
/* { dg-final { scan-assembler "\.sdata\[^2]+" } } */
struct test_s {

View File

@ -1,5 +1,4 @@
/* { dg-options "-mxl-gp-opt -G 16" } */
/* { dg-options "-mxl-gp-opt -G 16 -fno-pic" } */
struct test_s {
int a;
int b;

View File

@ -1,4 +1,4 @@
/* { dg-options "-mxl-gp-opt" } */
/* { dg-options "-mxl-gp-opt -fno-pic" } */
#include <string.h>

View File

@ -1,4 +1,4 @@
/* { dg-options "-mxl-gp-opt" } */
/* { dg-options "-mxl-gp-opt -fno-pic" } */
#include <string.h>