Commit a0fa334a authored by Matthias Braun's avatar Matthias Braun
Browse files

be: Make ia32 PIC styles a general be option.

parent 6bd1f80e
......@@ -773,7 +773,7 @@ static void emit_jumptable_target(ir_entity const *const table,
{
ir_node const *const block = get_cfop_target_block(proj_x);
be_gas_emit_block_name(block);
if (be_options.pic) {
if (be_options.pic_style != BE_PIC_NONE) {
be_emit_char('-');
be_gas_emit_entity(table);
}
......@@ -784,7 +784,8 @@ static void emit_amd64_jmp_switch(const ir_node *node)
const amd64_switch_jmp_attr_t *attr = get_amd64_switch_jmp_attr_const(node);
amd64_emitf(node, "jmp %*AM");
ir_mode *entry_mode = be_options.pic ? mode_Iu : mode_Lu;
ir_mode *entry_mode = be_options.pic_style != BE_PIC_NONE ? mode_Iu
: mode_Lu;
be_emit_jump_table(node, attr->table, attr->table_entity, entry_mode,
emit_jumptable_target);
}
......
......@@ -54,7 +54,7 @@ static void fix_address_pic(ir_node *const node, void *const data)
void amd64_adjust_pic(ir_graph *irg)
{
if (!be_options.pic)
if (be_options.pic_style == BE_PIC_NONE)
return;
irg_walk_graph(irg, fix_address_pic, NULL, NULL);
be_dump(DUMP_BE, irg, "pic");
......
......@@ -363,7 +363,8 @@ void init_lconst_addr(amd64_addr_t *addr, ir_entity *entity)
assert(entity_has_definition(entity));
assert(get_entity_linkage(entity) & IR_LINKAGE_CONSTANT);
assert(get_entity_visibility(entity) == ir_visibility_private);
x86_immediate_kind_t kind = be_options.pic ? X86_IMM_PCREL : X86_IMM_ADDR;
x86_immediate_kind_t kind = be_options.pic_style != BE_PIC_NONE
? X86_IMM_PCREL : X86_IMM_ADDR;
*addr = (amd64_addr_t) {
.immediate = {
.entity = entity,
......@@ -1559,7 +1560,7 @@ static ir_node *gen_Switch(ir_node *const node)
int arity = 0;
ir_node *in[1];
amd64_addr_t addr;
if (be_options.pic) {
if (be_options.pic_style != BE_PIC_NONE) {
ir_node *const base
= create_picaddr_lea(new_block, X86_IMM_PCREL, entity);
ir_node *load_in[3];
......
......@@ -33,6 +33,13 @@ typedef enum be_dump_flags_t {
DUMP_BE = 1 << 6
} be_dump_flags_t;
typedef enum be_pic_style_t {
BE_PIC_NONE,
BE_PIC_MACH_O,
BE_PIC_ELF_PLT,
BE_PIC_ELF_NO_PLT,
} be_pic_style_t;
/** Backend options */
struct be_options_t {
unsigned dump_flags; /**< backend dumping flags */
......@@ -40,10 +47,10 @@ struct be_options_t {
bool opt_profile_generate; /**< instrument code for profiling */
bool opt_profile_use; /**< use existing profile data */
bool omit_fp; /**< try to omit the frame pointer */
bool pic; /**< create position independent code */
bool do_verify; /**< backend verify option */
char ilp_solver[128]; /**< the ilp solver name */
bool verbose_asm; /**< dump verbose assembler */
be_pic_style_t pic_style;
};
extern be_options_t be_options;
......
......@@ -474,7 +474,7 @@ static be_gas_section_t determine_basic_section(const ir_entity *entity)
&& entity_is_string_const(entity, true))
return GAS_SECTION_CSTRING;
if (be_options.pic) {
if (be_options.pic_style != BE_PIC_NONE) {
ir_initializer_t const *const init = get_entity_initializer(entity);
switch (classify_initializer_relocs(init)) {
case ONLY_LOCAL_RELOCATIONS: return GAS_SECTION_REL_RO_LOCAL;
......
......@@ -63,10 +63,10 @@ be_options_t be_options = {
.opt_profile_generate = false,
.opt_profile_use = false,
.omit_fp = false,
.pic = false,
.do_verify = true,
.ilp_solver = "",
.verbose_asm = true,
.pic_style = BE_PIC_NONE,
};
/* back end instruction set architecture to use */
......@@ -85,6 +85,17 @@ static const lc_opt_enum_mask_items_t dump_items[] = {
{ NULL, 0 }
};
static const lc_opt_enum_int_items_t pic_style_items[] = {
{ "none", BE_PIC_NONE },
{ "mach-o", BE_PIC_MACH_O },
{ "elf", BE_PIC_ELF_PLT },
{ "elf-noplt", BE_PIC_ELF_NO_PLT },
{ NULL, BE_PIC_NONE },
};
static lc_opt_enum_int_var_t pic_style_var = {
(int*)&be_options.pic_style, pic_style_items
};
static lc_opt_enum_mask_var_t dump_var = {
&be_options.dump_flags, dump_items
};
......@@ -92,7 +103,7 @@ static lc_opt_enum_mask_var_t dump_var = {
static const lc_opt_table_entry_t be_main_options[] = {
LC_OPT_ENT_ENUM_MASK("dump", "dump irg on several occasions", &dump_var),
LC_OPT_ENT_BOOL ("omitfp", "omit frame pointer", &be_options.omit_fp),
LC_OPT_ENT_BOOL ("pic", "create PIC code", &be_options.pic),
LC_OPT_ENT_ENUM_INT ("pic", "Generate position independent code", &pic_style_var),
LC_OPT_ENT_BOOL ("verify", "verify the backend irg", &be_options.do_verify),
LC_OPT_ENT_BOOL ("time", "get backend timing statistics", &be_options.timing),
LC_OPT_ENT_BOOL ("profilegenerate", "instrument the code for execution count profiling", &be_options.opt_profile_generate),
......
......@@ -1599,24 +1599,12 @@ static const backend_params *ia32_get_libfirm_params(void)
return &ia32_backend_params;
}
static const lc_opt_enum_int_items_t pic_style_items[] = {
{ "none", IA32_PIC_NONE },
{ "mach-o", IA32_PIC_MACH_O },
{ "elf", IA32_PIC_ELF_PLT },
{ "elf-noplt", IA32_PIC_ELF_NO_PLT },
{ NULL, IA32_PIC_NONE },
};
static lc_opt_enum_int_var_t pic_style_var = {
(int*)&ia32_pic_style, pic_style_items
};
static const lc_opt_table_entry_t ia32_options[] = {
LC_OPT_ENT_BOOL("gprof", "Create gprof profiling code", &gprof),
LC_OPT_ENT_BOOL("precise_float_spill", "Spill floatingpoint values precisely (the whole 80 bits)", &precise_x87_spills),
LC_OPT_ENT_BOOL("struct_in_reg",
"Return small structs in integer registers",
&return_small_struct_in_regs),
LC_OPT_ENT_ENUM_INT("pic", "Generate position independent code",
&pic_style_var),
LC_OPT_LAST
};
......
......@@ -24,13 +24,6 @@
#define IA32_REGISTER_SIZE 4
typedef enum ia32_pic_style_t {
IA32_PIC_NONE,
IA32_PIC_MACH_O,
IA32_PIC_ELF_PLT,
IA32_PIC_ELF_NO_PLT,
} ia32_pic_style_t;
typedef struct ia32_irg_data_t {
unsigned do_x87_sim:1; /**< set to 1 if x87 simulation should be enforced */
ir_node *noreg_gp; /**< unique NoReg_GP node */
......@@ -51,8 +44,6 @@ extern ir_mode *ia32_mode_float64;
extern ir_mode *ia32_mode_float32;
extern ir_mode *ia32_mode_flags;
extern ia32_pic_style_t ia32_pic_style;
static inline ia32_irg_data_t *ia32_get_irg_data(const ir_graph *irg)
{
return (ia32_irg_data_t*) be_birg_from_irg(irg)->isa_link;
......
......@@ -882,10 +882,10 @@ static void emit_jumptable_target(ir_entity const *const table,
(void)table;
ir_node const *const block = get_cfop_target_block(proj_x);
be_gas_emit_block_name(block);
if (ia32_pic_style == IA32_PIC_ELF_PLT
|| ia32_pic_style == IA32_PIC_ELF_NO_PLT) {
be_pic_style_t const pic_style = be_options.pic_style;
if (pic_style == BE_PIC_ELF_PLT || pic_style == BE_PIC_ELF_NO_PLT) {
be_emit_cstring("@GOTOFF");
} else if (ia32_pic_style == IA32_PIC_MACH_O) {
} else if (pic_style == BE_PIC_MACH_O) {
be_emit_char('-');
be_emit_string(pic_base_label);
}
......@@ -1249,16 +1249,16 @@ static void emit_ia32_GetEIP(const ir_node *node)
}
ia32_emitf(node, "call %E", thunk);
switch (ia32_pic_style) {
case IA32_PIC_MACH_O:
switch (be_options.pic_style) {
case BE_PIC_MACH_O:
be_emit_irprintf("%s:\n", pic_base_label);
be_emit_write_line();
return;
case IA32_PIC_ELF_PLT:
case IA32_PIC_ELF_NO_PLT:
case BE_PIC_ELF_PLT:
case BE_PIC_ELF_NO_PLT:
ia32_emitf(node, "addl $_GLOBAL_OFFSET_TABLE_, %D0");
return;
case IA32_PIC_NONE:
case BE_PIC_NONE:
break;
}
panic("invalid pic_style");
......
......@@ -23,8 +23,6 @@
#include "irnode_t.h"
#include "x86_imm.h"
ia32_pic_style_t ia32_pic_style = IA32_PIC_NONE;
/**
* Create a trampoline entity for the given method.
*/
......@@ -130,10 +128,10 @@ static void fix_address_elf(ir_node *const node, void *const data)
&& !(get_entity_linkage(entity) & IR_LINKAGE_MERGE))
continue;
if (ia32_pic_style == IA32_PIC_ELF_PLT) {
if (be_options.pic_style == BE_PIC_ELF_PLT) {
res = be_new_Relocation(irg, X86_IMM_PLT, entity, mode_P);
} else {
assert(ia32_pic_style == IA32_PIC_ELF_NO_PLT);
assert(be_options.pic_style == BE_PIC_ELF_NO_PLT);
res = get_table_load(irg, X86_IMM_GOT, entity);
}
} else {
......@@ -191,16 +189,14 @@ static void fix_address_macho(ir_node *const node, void *const data)
void ia32_adjust_pic(ir_graph *irg)
{
switch (ia32_pic_style) {
case IA32_PIC_NONE:
switch (be_options.pic_style) {
case BE_PIC_NONE:
return;
case IA32_PIC_ELF_PLT:
case IA32_PIC_ELF_NO_PLT:
be_options.pic = true;
case BE_PIC_ELF_PLT:
case BE_PIC_ELF_NO_PLT:
irg_walk_graph(irg, fix_address_elf, NULL, NULL);
return;
case IA32_PIC_MACH_O:
be_options.pic = true;
case BE_PIC_MACH_O:
irg_walk_graph(irg, fix_address_macho, NULL, NULL);
return;
}
......
......@@ -231,7 +231,7 @@ ir_node *ia32_get_pic_base(ir_graph *irg)
*/
static ir_node *get_global_base(ir_graph *const irg)
{
if (ia32_pic_style != IA32_PIC_NONE)
if (be_options.pic_style != BE_PIC_NONE)
return ia32_get_pic_base(irg);
return noreg_GP;
}
......@@ -2951,14 +2951,15 @@ static ir_node *gen_Switch(ir_node *node)
ir_node *switchjmp;
ir_node *table_am;
if (ia32_pic_style == IA32_PIC_NONE) {
be_pic_style_t const pic_style = be_options.pic_style;
if (pic_style == BE_PIC_NONE) {
switchjmp = new_bd_ia32_SwitchJmp(dbgi, block, base, new_sel, n_outs,
table, entity);
table_am = switchjmp;
} else {
assert(ia32_pic_style == IA32_PIC_ELF_PLT
|| ia32_pic_style == IA32_PIC_ELF_NO_PLT
|| ia32_pic_style == IA32_PIC_MACH_O);
assert(pic_style == BE_PIC_ELF_PLT
|| pic_style == BE_PIC_ELF_NO_PLT
|| pic_style == BE_PIC_MACH_O);
ir_node *const add = new_bd_ia32_Add(dbgi, block, base, new_sel, nomem,
base, noreg_GP);
set_ia32_commutative(add);
......@@ -5857,11 +5858,11 @@ void ia32_transform_graph(ir_graph *irg)
| IR_GRAPH_PROPERTY_NO_TUPLES
| IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
switch (ia32_pic_style) {
case IA32_PIC_NONE: lconst_imm_kind = X86_IMM_ADDR; break;
case IA32_PIC_MACH_O: lconst_imm_kind = X86_IMM_PICBASE_REL; break;
case IA32_PIC_ELF_PLT:
case IA32_PIC_ELF_NO_PLT: lconst_imm_kind = X86_IMM_GOTOFF; break;
switch (be_options.pic_style) {
case BE_PIC_NONE: lconst_imm_kind = X86_IMM_ADDR; break;
case BE_PIC_MACH_O: lconst_imm_kind = X86_IMM_PICBASE_REL; break;
case BE_PIC_ELF_PLT:
case BE_PIC_ELF_NO_PLT: lconst_imm_kind = X86_IMM_GOTOFF; break;
}
/* fix get_eip mode ia32_pic sets it to mode_P */
ir_node *const get_eip = ia32_get_irg_data(irg)->get_eip;
......
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