summaryrefslogtreecommitdiffhomepage
path: root/ir/be/betranshlp.c
diff options
context:
space:
mode:
authorChristoph Mallon <mallon@cs.uni-saarland.de>2015-05-24 14:18:44 +0200
committerChristoph Mallon <mallon@cs.uni-saarland.de>2015-05-29 17:35:20 +0200
commitad4328b62ef8bd4730b347dfc838478ac0561cbe (patch)
tree1efb1baa89c105e02793daabc8df697f0c075b2d /ir/be/betranshlp.c
parent446c97de6f7c3bdeef819875fe8a4915ec8da777 (diff)
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.
Diffstat (limited to 'ir/be/betranshlp.c')
-rw-r--r--ir/be/betranshlp.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/ir/be/betranshlp.c b/ir/be/betranshlp.c
index b65972a..96b2f17 100644
--- a/ir/be/betranshlp.c
+++ b/ir/be/betranshlp.c
@@ -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;
+}