Commit 84b2a7e3 authored by Matthias Braun's avatar Matthias Braun
Browse files

ia32: Match Relocation node

parent d28d0a06
......@@ -481,7 +481,8 @@ static bool match_immediate_32(x86_imm32_t *imm, const ir_node *op,
ir_tarval *tv;
ir_entity *entity;
if (!be_match_immediate(op, &tv, &entity))
unsigned reloc_kind;
if (!be_match_immediate(op, &tv, &entity, &reloc_kind))
return false;
int32_t val;
......@@ -501,14 +502,14 @@ static bool match_immediate_32(x86_imm32_t *imm, const ir_node *op,
val = 0;
}
x86_immediate_kind_t kind = X86_IMM_VALUE;
x86_immediate_kind_t kind = (x86_immediate_kind_t)reloc_kind;
if (entity != NULL) {
if (!can_match_ip_relative) {
/* TODO: check if entity is in lower 4GB address space/relative */
return false;
}
/* TODO: use a new relocation type for ip-relative? */
kind = X86_IMM_ADDR;
if (kind == X86_IMM_VALUE)
kind = X86_IMM_ADDR;
}
imm->entity = entity;
......
......@@ -855,25 +855,41 @@ ir_node *be_skip_sameconv(ir_node *node)
return node;
}
bool be_match_immediate(ir_node const *const node, ir_tarval **const tarval_out, ir_entity **const entity_out)
bool be_match_immediate(ir_node const *const node, ir_tarval **const tarval_out,
ir_entity **const entity_out, unsigned *reloc_kind_out)
{
ir_node const *addr;
ir_node const *cnst;
unsigned reloc_kind;
ir_entity *entity;
ir_node const *cnst;
if (is_Const(node)) {
addr = NULL;
cnst = node;
entity = NULL;
cnst = node;
reloc_kind = 0;
} else if (is_Address(node)) {
addr = node;
cnst = NULL;
entity = get_Address_entity(node);
cnst = NULL;
reloc_kind = 0;
} else if (be_is_Relocation(node)) {
entity = be_get_Relocation_entity(node);
cnst = NULL;
reloc_kind = be_get_Relocation_kind(node);
} else if (is_Add(node)) {
ir_node const *const l = get_Add_left(node);
ir_node const *const r = get_Add_right(node);
if (is_Address(l) && is_Const(r)) {
addr = l;
cnst = r;
} else if (is_Const(l) && is_Address(r)) {
addr = r;
cnst = l;
ir_node const *l = get_Add_left(node);
ir_node const *r = get_Add_right(node);
if (be_is_Relocation(r) || is_Address(r)) {
ir_node const *tmp = l;
l = r;
r = tmp;
}
if (!is_Const(l))
return false;
cnst = l;
if (is_Address(r)) {
entity = get_Address_entity(node);
reloc_kind = 0;
} else if (be_is_Relocation(r)) {
entity = get_Address_entity(node);
reloc_kind = be_get_Relocation_kind(node);
} else {
return false;
}
......@@ -881,16 +897,8 @@ bool be_match_immediate(ir_node const *const node, ir_tarval **const tarval_out,
return false;
}
ir_entity *entity;
if (addr) {
entity = get_Address_entity(addr);
if (is_tls_entity(entity))
return false;
} else {
entity = NULL;
}
*tarval_out = cnst ? get_Const_tarval(cnst) : NULL;
*entity_out = entity;
*tarval_out = cnst ? get_Const_tarval(cnst) : NULL;
*entity_out = entity;
*reloc_kind_out = reloc_kind;
return true;
}
......@@ -157,6 +157,7 @@ ir_node *be_skip_downconv(ir_node *node, bool single_user);
/** Skip all signedness convs */
ir_node *be_skip_sameconv(ir_node *node);
bool be_match_immediate(ir_node const *node, ir_tarval **tarval_out, ir_entity **entity_out);
bool be_match_immediate(ir_node const *node, ir_tarval **tarval_out,
ir_entity **entity_out, unsigned *reloc_kind_out);
#endif
......@@ -504,6 +504,19 @@ static ir_node *gen_Address(ir_node *node)
return cnst;
}
static ir_node *gen_be_Relocation(ir_node *node)
{
ir_node *block = be_transform_nodes_block(node);
dbg_info *dbgi = get_irn_dbg_info(node);
x86_imm32_t imm = {
.kind = (x86_immediate_kind_t)be_get_Relocation_kind(node),
.entity = be_get_Relocation_entity(node),
};
ir_node *cnst = new_bd_ia32_Const(dbgi, block, &imm);
SET_IA32_ORIG_NODE(cnst, node);
return cnst;
}
static ir_type *make_array_type(ir_type *tp)
{
unsigned alignment = get_type_alignment_bytes(tp);
......@@ -5757,6 +5770,7 @@ static void register_transformers(void)
be_set_transform_function(op_Sub, gen_Sub);
be_set_transform_function(op_Switch, gen_Switch);
be_set_transform_function(op_Unknown, gen_Unknown);
be_set_transform_function(op_be_Relocation, gen_be_Relocation);
be_set_transform_proj_function(op_Alloc, gen_Proj_Alloc);
be_set_transform_proj_function(op_ASM, gen_Proj_ASM);
be_set_transform_proj_function(op_Builtin, gen_Proj_Builtin);
......
......@@ -9,20 +9,19 @@
* nodes that can be used as address mode for x86 instructions
* @author Matthias Braun
*/
#include "x86_address_mode.h"
#include "bediagnostic.h"
#include "beirg.h"
#include "beutil.h"
#include "belive.h"
#include "benode.h"
#include "betranshlp.h"
#include "x86_address_mode.h"
#include "irtypes.h"
#include "irnode_t.h"
#include "irprintf.h"
#include "beutil.h"
#include "iredges_t.h"
#include "irgwalk.h"
#include "benode.h"
#include "belive.h"
#include "irnode_t.h"
#include "irprintf.h"
#include "irtypes.h"
static bitset_t *non_address_mode_nodes;
......@@ -76,6 +75,13 @@ static bool eat_imm(x86_address_t *const addr, ir_node const *const node)
return true;
default:
if (be_is_Relocation(node)) {
if (addr->imm.entity)
return false;
addr->imm.entity = be_get_Relocation_entity(node);
addr->imm.kind = (x86_immediate_kind_t)be_get_Relocation_kind(node);
return true;
}
/* All other nodes are no immediates. */
return false;
}
......
......@@ -47,7 +47,8 @@ bool x86_match_immediate(x86_imm32_t *immediate, const ir_node *node,
ir_tarval *offset;
ir_entity *entity;
if (!be_match_immediate(node, &offset, &entity))
unsigned reloc_kind;
if (!be_match_immediate(node, &offset, &entity, &reloc_kind))
return false;
long val = 0;
......@@ -62,12 +63,13 @@ bool x86_match_immediate(x86_imm32_t *immediate, const ir_node *node,
return false;
}
x86_immediate_kind_t kind = X86_IMM_VALUE;
x86_immediate_kind_t kind = (x86_immediate_kind_t)reloc_kind;
if (entity != NULL) {
/* we need full 32bits for entities */
if (constraint != 'i' && constraint != 'g')
return false;
kind = X86_IMM_ADDR;
if (kind == X86_IMM_VALUE)
kind = X86_IMM_ADDR;
}
/* we are fine */
......
......@@ -277,7 +277,8 @@ static bool sparc_match_immediate(sparc_asm_operand_t *const operand, ir_node *c
{
ir_tarval *offset;
ir_entity *entity;
if (!be_match_immediate(node, &offset, &entity))
unsigned reloc_kind;
if (!be_match_immediate(node, &offset, &entity, &reloc_kind))
return false;
if (entity && imm_type != 'g' && imm_type != 'i')
......
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