Commit ad4328b6 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

be: Factorise the code for ia32 to match an immediate.

Other backends can use this, too.
This also corrects the bug, that for Address+Const immediates the check, whether it is a tls entity, was missing.
parent 446c97de
......@@ -14,6 +14,7 @@
#include "belive.h"
#include "benode.h"
#include "betranshlp.h"
#include "beutil.h"
#include "cgana.h"
#include "debug.h"
#include "execfreq_t.h"
......@@ -872,3 +873,43 @@ 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)
{
ir_node const *addr;
ir_node const *cnst;
if (is_Const(node)) {
addr = NULL;
cnst = node;
} else if (is_Address(node)) {
addr = node;
cnst = NULL;
} 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;
} else {
return false;
}
} else {
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;
return true;
}
......@@ -157,4 +157,6 @@ 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);
#endif
......@@ -22,7 +22,6 @@
#include "beirg.h"
#include "benode.h"
#include "betranshlp.h"
#include "beutil.h"
#include "gen_ia32_regalloc_if.h"
#include "ia32_new_nodes.h"
#include "irprintf.h"
......@@ -279,37 +278,15 @@ bool x86_match_immediate(x86_imm32_t *immediate, const ir_node *node,
if (get_mode_arithmetic(mode) != irma_twos_complement)
return false;
const ir_node *cnst;
ir_entity *entity;
if (is_Const(node)) {
cnst = node;
entity = NULL;
} else if (is_Address(node)) {
cnst = NULL;
entity = get_Address_entity(node);
if (is_tls_entity(entity))
return false;
} else if (is_Add(node)) {
ir_node *left = get_Add_left(node);
ir_node *right = get_Add_right(node);
if (is_Const(left) && is_Address(right)) {
cnst = left;
entity = get_Address_entity(right);
} else if (is_Address(left) && is_Const(right)) {
cnst = right;
entity = get_Address_entity(left);
} else {
return false;
}
} else {
ir_tarval *offset;
ir_entity *entity;
if (!be_match_immediate(node, &offset, &entity))
return false;
}
long val = 0;
if (cnst != NULL) {
ir_tarval *offset = get_Const_tarval(cnst);
if (offset) {
if (!tarval_is_long(offset)) {
be_warningf(cnst, "tarval is not long");
be_warningf(node, "tarval is not long");
return false;
}
......
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