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

- Introduce nodemap

- All float operations depend on fpu mode now
- Fix bestate switcher
- Add and fix fehler22 (unknown phi operands in x87 simulator)

[r14749]
parent a96bf26c
......@@ -39,11 +39,6 @@ typedef int (*cpset_cmp_function) (const void *p1, const void *p2);
/**
* The type of a cpset hash function.
*
* @param p1 pointer to an element
* @param p2 pointer to another element
*
* @return 1 if the elements are identically, zero else
*/
typedef unsigned (*cpset_hash_function) (const void *obj);
......@@ -59,6 +54,9 @@ typedef unsigned (*cpset_hash_function) (const void *obj);
#undef HashSetIterator
#undef HashSet
typedef struct cpset_t cpset_t;
typedef struct cpset_iterator_t cpset_iterator_t;
/**
* Initializes a cpset
*
......
......@@ -40,7 +40,7 @@ typedef struct HashSetEntry {
} HashSetEntry;
#endif
typedef struct HashSet {
struct HashSet {
HashSetEntry *entries;
size_t num_buckets;
size_t enlarge_threshold;
......@@ -54,16 +54,16 @@ typedef struct HashSet {
#ifdef ADDITIONAL_DATA
ADDITIONAL_DATA
#endif
} HashSet;
};
typedef struct HashSetIterator {
struct HashSetIterator {
HashSetEntry *current_bucket;
HashSetEntry *end;
#ifndef NDEBUG
const HashSet *set;
const struct HashSet *set;
unsigned entries_version;
#endif
} HashSetIterator;
};
#ifdef DO_REHASH
#undef HashSetEntry
......
......@@ -42,6 +42,9 @@
#undef HashSetIterator
#undef ValueType
typedef struct pset_new_t pset_new_t;
typedef struct pset_new_iterator_t pset_new_iterator_t;
/**
* Initializes a pset_new
*
......
......@@ -36,8 +36,9 @@
#define ValueType void*
#define NullValue NULL
#define DeletedValue ((void*)-1)
#define Hash(this,value) this->hash_function(value)
#define Hash(this,key) this->hash_function(key)
#define KeysEqual(this,key1,key2) this->cmp_function(key1, key2)
#define SCALAR_RETURN
#define SetRangeEmpty(ptr,size) memset(ptr, 0, (size) * sizeof(cpset_hashset_entry_t))
#define hashset_init _cpset_init
......
......@@ -79,13 +79,13 @@
#ifndef Hash
#define ID_HASH
#define Hash(self,value) ((unsigned)(value))
#define Hash(self,key) ((unsigned)(key))
#endif /* Hash */
#ifdef DO_REHASH
#define HashSetEntry ValueType
#define EntrySetHash(entry,new_hash)
#define EntryGetHash(self,entry) Hash(self,entry)
#define EntryGetHash(self,entry) Hash(self, GetKey(entry))
#define EntryGetValue(entry) (entry)
#else /* ! DO_REHASH */
#define EntryGetHash(self,entry) (entry).hash
......@@ -100,11 +100,19 @@
#endif /* Alloc */
#ifdef ID_HASH
#define InsertReturnValue int
#define GetInsertReturnValue(entry,new) (new)
#define InsertReturnValue int
#define GetInsertReturnValue(entry,found) (found)
#define NullReturnValue 0
#else /* ! ID_HASH */
#define InsertReturnValue ValueType
#define GetInsertReturnValue(entry,new) EntryGetValue(entry)
#ifdef SCALAR_RETURN
#define InsertReturnValue ValueType
#define GetInsertReturnValue(entry,found) EntryGetValue(entry)
#define NullReturnValue NullValue
#else
#define InsertReturnValue ValueType*
#define GetInsertReturnValue(entry,found) & EntryGetValue(entry)
#define NullReturnValue & NullValue
#endif
#endif /* ID_HASH */
#ifndef KeyType
......@@ -211,12 +219,12 @@ size_t hashset_size(const HashSet *self)
static INLINE
InsertReturnValue insert_nogrow(HashSet *self, KeyType key)
{
size_t num_probes = 0;
size_t num_buckets = self->num_buckets;
size_t hashmask = num_buckets - 1;
unsigned hash = Hash(self, key);
size_t bucknum = hash & hashmask;
size_t insert_pos = ILLEGAL_POS;
size_t num_probes = 0;
size_t num_buckets = self->num_buckets;
size_t hashmask = num_buckets - 1;
unsigned hash = Hash(self, key);
size_t bucknum = hash & hashmask;
size_t insert_pos = ILLEGAL_POS;
assert((num_buckets & (num_buckets - 1)) == 0);
......@@ -237,7 +245,7 @@ InsertReturnValue insert_nogrow(HashSet *self, KeyType key)
InitData(self, EntryGetValue(*nentry), key);
EntrySetHash(*nentry, hash);
self->num_elements++;
return GetInsertReturnValue(*nentry, 1);
return GetInsertReturnValue(*nentry, 0);
}
if(EntryIsDeleted(*entry)) {
if(insert_pos == ILLEGAL_POS)
......@@ -245,7 +253,7 @@ InsertReturnValue insert_nogrow(HashSet *self, KeyType key)
} else if(EntryGetHash(self, *entry) == hash) {
if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) {
// Value already in the set, return it
return GetInsertReturnValue(*entry, 0);
return GetInsertReturnValue(*entry, 1);
}
}
......@@ -263,13 +271,13 @@ InsertReturnValue insert_nogrow(HashSet *self, KeyType key)
static
void insert_new(HashSet *self, unsigned hash, ValueType value)
{
size_t num_probes = 0;
size_t num_probes = 0;
size_t num_buckets = self->num_buckets;
size_t hashmask = num_buckets - 1;
size_t bucknum = hash & hashmask;
size_t insert_pos = ILLEGAL_POS;
size_t hashmask = num_buckets - 1;
size_t bucknum = hash & hashmask;
size_t insert_pos = ILLEGAL_POS;
assert(value != NullValue);
//assert(value != NullValue);
while(1) {
HashSetEntry *entry = & self->entries[bucknum];
......@@ -306,8 +314,8 @@ static INLINE
void reset_thresholds(HashSet *self)
{
self->enlarge_threshold = (size_t) HT_OCCUPANCY_FLT(self->num_buckets);
self->shrink_threshold = (size_t) HT_EMPTY_FLT(self->num_buckets);
self->consider_shrink = 0;
self->shrink_threshold = (size_t) HT_EMPTY_FLT(self->num_buckets);
self->consider_shrink = 0;
}
/**
......@@ -327,10 +335,10 @@ void resize(HashSet *self, size_t new_size)
SetRangeEmpty(new_entries, new_size);
/* use the new array */
self->entries = new_entries;
self->num_buckets = new_size;
self->entries = new_entries;
self->num_buckets = new_size;
self->num_elements = 0;
self->num_deleted = 0;
self->num_deleted = 0;
#ifndef NDEBUG
self->entries_version++;
#endif
......@@ -423,26 +431,26 @@ InsertReturnValue hashset_insert(HashSet *self, KeyType key)
* @param key the key to search for
* @returns the found value or NullValue if nothing was found
*/
ValueType hashset_find(const HashSet *self, ConstKeyType key)
InsertReturnValue hashset_find(const HashSet *self, ConstKeyType key)
{
size_t num_probes = 0;
size_t num_buckets = self->num_buckets;
size_t hashmask = num_buckets - 1;
unsigned hash = Hash(self, key);
size_t bucknum = hash & hashmask;
size_t num_probes = 0;
size_t num_buckets = self->num_buckets;
size_t hashmask = num_buckets - 1;
unsigned hash = Hash(self, key);
size_t bucknum = hash & hashmask;
while(1) {
HashSetEntry *entry = & self->entries[bucknum];
if(EntryIsEmpty(*entry)) {
return NullValue;
return NullReturnValue;
}
if(EntryIsDeleted(*entry)) {
// value is deleted
} else if(EntryGetHash(self, *entry) == hash) {
if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) {
// found the value
return EntryGetValue(*entry);
return GetInsertReturnValue(*entry, 1);
}
}
......@@ -461,11 +469,11 @@ ValueType hashset_find(const HashSet *self, ConstKeyType key)
*/
void hashset_remove(HashSet *self, ConstKeyType key)
{
size_t num_probes = 0;
size_t num_buckets = self->num_buckets;
size_t hashmask = num_buckets - 1;
unsigned hash = Hash(self, key);
size_t bucknum = hash & hashmask;
size_t num_probes = 0;
size_t num_buckets = self->num_buckets;
size_t hashmask = num_buckets - 1;
unsigned hash = Hash(self, key);
size_t bucknum = hash & hashmask;
#ifndef NDEBUG
self->entries_version++;
......@@ -504,12 +512,12 @@ void init_size(HashSet *self, size_t initial_size)
if(initial_size < 4)
initial_size = 4;
self->entries = Alloc(initial_size);
self->entries = Alloc(initial_size);
SetRangeEmpty(self->entries, initial_size);
self->num_buckets = initial_size;
self->num_buckets = initial_size;
self->consider_shrink = 0;
self->num_elements = 0;
self->num_deleted = 0;
self->num_elements = 0;
self->num_deleted = 0;
#ifndef NDEBUG
self->entries_version = 0;
#endif
......@@ -551,7 +559,7 @@ void hashset_init_size(HashSet *self, size_t expected_elements)
}
needed_size = expected_elements * HT_1_DIV_OCCUPANCY_FLT;
po2size = ceil_po2(needed_size);
po2size = ceil_po2(needed_size);
init_size(self, po2size);
}
......@@ -563,9 +571,9 @@ void hashset_init_size(HashSet *self, size_t expected_elements)
void hashset_iterator_init(HashSetIterator *self, const HashSet *hashset)
{
self->current_bucket = hashset->entries - 1;
self->end = hashset->entries + hashset->num_buckets;
self->end = hashset->entries + hashset->num_buckets;
#ifndef NDEBUG
self->set = hashset;
self->set = hashset;
self->entries_version = hashset->entries_version;
#endif
}
......@@ -578,7 +586,7 @@ void hashset_iterator_init(HashSetIterator *self, const HashSet *hashset)
ValueType hashset_iterator_next(HashSetIterator *self)
{
HashSetEntry *current_bucket = self->current_bucket;
HashSetEntry *end = self->end;
HashSetEntry *end = self->end;
/* using hashset_insert or hashset_remove is not allowed while iterating */
assert(self->entries_version == self->set->entries_version);
......
......@@ -54,5 +54,5 @@
int pset_new_contains(const pset_new_t *pset_new, const ValueType val)
{
return pset_new_find(pset_new, val) != NullValue;
return pset_new_find(pset_new, val);
}
......@@ -39,6 +39,9 @@
#include "iredges_t.h"
#include "ircons_t.h"
#include "irgmod.h"
#include "irnodeset.h"
#include "irnodemap.h"
#include "adt/cpset.h"
#include "bearch_t.h"
#include "beuses.h"
......@@ -66,6 +69,7 @@ typedef struct minibelady_env_t {
create_reload_func create_reload;
create_spill_func create_spill;
spill_info_t *spills;
ir_nodemap_t spill_infos;
be_uses_t *uses; /**< env for the next-use magic */
} minibelady_env_t;
......@@ -81,6 +85,7 @@ block_info_t *new_block_info(struct obstack *obst, ir_node *block)
block_info_t *res = obstack_alloc(obst, sizeof(*res));
memset(res, 0, sizeof(res[0]));
assert(is_Block(block));
set_irn_link(block, res);
mark_irn_visited(block);
......@@ -102,8 +107,8 @@ spill_info_t *create_spill_info(minibelady_env_t *env, ir_node *state)
spill_info->value = state;
spill_info->reloads = NEW_ARR_F(ir_node*, 0);
set_irn_link(state, spill_info);
mark_irn_visited(state);
ir_nodemap_insert(&env->spill_infos, state, spill_info);
//ir_fprintf(stderr, "Insert %+F -> %p\n", state, spill_info);
spill_info->next = env->spills;
env->spills = spill_info;
......@@ -111,6 +116,15 @@ spill_info_t *create_spill_info(minibelady_env_t *env, ir_node *state)
return spill_info;
}
static INLINE
spill_info_t *get_spill_info(minibelady_env_t *env, const ir_node *node)
{
spill_info_t *spill_info
= (spill_info_t*) ir_nodemap_get(&env->spill_infos, node);
//ir_fprintf(stderr, "Get %+F -> %p\n", node, spill_info);
return spill_info;
}
static
spill_info_t *create_spill(minibelady_env_t *env, ir_node *state, int force)
{
......@@ -118,11 +132,8 @@ spill_info_t *create_spill(minibelady_env_t *env, ir_node *state, int force)
ir_node *next;
ir_node *after;
if(irn_visited(state)) {
spill_info = (spill_info_t*) get_irn_link(state);
if(spill_info->spill != NULL || !force)
return spill_info;
} else {
spill_info = get_spill_info(env, state);
if(spill_info == NULL) {
spill_info = create_spill_info(env, state);
}
......@@ -164,8 +175,8 @@ void spill_phi(minibelady_env_t *env, ir_node *phi)
spill_info_t *spill_info;
/* does a spill exist for the phis value? */
if(irn_visited(phi)) {
spill_info = (spill_info_t*) get_irn_link(phi);
spill_info = get_spill_info(env, phi);
if(spill_info != NULL) {
spill_to_kill = spill_info->spill;
} else {
spill_info = create_spill_info(env, phi);
......@@ -531,6 +542,7 @@ void be_assure_state(be_irg_t *birg, const arch_register_t *reg, void *func_env,
env.lv = be_get_birg_liveness(birg);
env.uses = be_begin_uses(irg, env.lv);
env.spills = NULL;
ir_nodemap_init(&env.spill_infos);
assure_doms(irg);
set_using_visited(irg);
......@@ -588,6 +600,7 @@ void be_assure_state(be_irg_t *birg, const arch_register_t *reg, void *func_env,
/* some nodes might be dead now. */
be_remove_dead_nodes_from_schedule(birg);
ir_nodemap_destroy(&env.spill_infos);
be_end_uses(env.uses);
obstack_free(&env.obst, NULL);
}
......
......@@ -816,7 +816,6 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node
set_irn_n(irn, 2, tmp);
}
set_ia32_am_support(irn, ia32_am_Source);
set_ia32_op_type(irn, ia32_AddrModeS);
set_ia32_am_flavour(irn, ia32_B);
set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i)));
......@@ -958,7 +957,6 @@ static void transform_to_Load(ia32_code_gen_t *cg, ir_node *node) {
else
new_op = new_rd_ia32_Load(dbg, irg, block, ptr, noreg, mem);
set_ia32_am_support(new_op, ia32_am_Source);
set_ia32_op_type(new_op, ia32_AddrModeS);
set_ia32_am_flavour(new_op, ia32_B);
set_ia32_ls_mode(new_op, spillmode);
......@@ -1033,7 +1031,6 @@ static void transform_to_Store(ia32_code_gen_t *cg, ir_node *node) {
store = new_rd_ia32_Store(dbg, irg, block, ptr, noreg, val, nomem);
}
set_ia32_am_support(store, ia32_am_Dest);
set_ia32_op_type(store, ia32_AddrModeD);
set_ia32_am_flavour(store, ia32_B);
set_ia32_ls_mode(store, mode);
......
......@@ -105,12 +105,12 @@ static void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
/* generate the add */
if (mode_is_float(mode)) {
res = new_rd_ia32_xAdd(dbg, irg, block, noreg, noreg, res, in1, nomem);
set_ia32_am_support(res, ia32_am_Source);
set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
set_ia32_ls_mode(res, get_ia32_ls_mode(irn));
}
else {
res = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, res, in1, nomem);
set_ia32_am_support(res, ia32_am_Full);
set_ia32_am_support(res, ia32_am_Full, ia32_am_binary);
set_ia32_commutative(res);
}
......@@ -449,7 +449,6 @@ static void fix_am_source(ir_node *irn, void *env) {
set_ia32_ls_mode(load, ls_mode);
set_ia32_am_flavour(load, get_ia32_am_flavour(irn));
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_support(load, ia32_am_Source);
set_ia32_am_scale(load, get_ia32_am_scale(irn));
set_ia32_am_sc(load, get_ia32_am_sc(irn));
add_ia32_am_offs_int(load, get_ia32_am_offs_int(irn));
......
......@@ -66,7 +66,6 @@ static ir_node *create_fpu_mode_spill(void *env, ir_node *state, int force,
spill = new_rd_ia32_FnstCW(NULL, irg, block, frame, noreg, state,
nomem);
set_ia32_am_support(spill, ia32_am_Dest);
set_ia32_op_type(spill, ia32_AddrModeD);
set_ia32_am_flavour(spill, ia32_B);
set_ia32_ls_mode(spill, ia32_reg_classes[CLASS_ia32_fp_cw].mode);
......@@ -91,7 +90,6 @@ static ir_node *create_fpu_mode_reload(void *env, ir_node *state,
if(spill != NULL) {
reload = new_rd_ia32_FldCW(NULL, irg, block, frame, noreg, spill);
set_ia32_am_support(reload, ia32_am_Source);
set_ia32_op_type(reload, ia32_AddrModeS);
set_ia32_am_flavour(reload, ia32_B);
set_ia32_ls_mode(reload, ia32_reg_classes[CLASS_ia32_fp_cw].mode);
......@@ -107,7 +105,6 @@ static ir_node *create_fpu_mode_reload(void *env, ir_node *state,
assert(last_state != NULL);
cwstore = new_rd_ia32_FnstCW(NULL, irg, block, frame, noreg, last_state,
nomem);
set_ia32_am_support(cwstore, ia32_am_Dest);
set_ia32_op_type(cwstore, ia32_AddrModeD);
set_ia32_am_flavour(cwstore, ia32_B);
set_ia32_ls_mode(cwstore, lsmode);
......@@ -115,7 +112,6 @@ static ir_node *create_fpu_mode_reload(void *env, ir_node *state,
sched_add_before(before, cwstore);
load = new_rd_ia32_Load(NULL, irg, block, frame, noreg, cwstore);
set_ia32_am_support(load, ia32_am_Source);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_flavour(load, ia32_B);
set_ia32_ls_mode(load, lsmode);
......@@ -134,7 +130,6 @@ static ir_node *create_fpu_mode_reload(void *env, ir_node *state,
sched_add_before(before, or);
store = new_rd_ia32_Store(NULL, irg, block, frame, noreg, or, nomem);
set_ia32_am_support(store, ia32_am_Dest);
set_ia32_op_type(store, ia32_AddrModeD);
set_ia32_am_flavour(store, ia32_B);
set_ia32_ls_mode(store, lsmode);
......@@ -142,7 +137,6 @@ static ir_node *create_fpu_mode_reload(void *env, ir_node *state,
sched_add_before(before, store);
fldcw = new_rd_ia32_FldCW(NULL, irg, block, frame, noreg, store);
set_ia32_am_support(fldcw, ia32_am_Source);
set_ia32_op_type(fldcw, ia32_AddrModeS);
set_ia32_am_flavour(fldcw, ia32_B);
set_ia32_ls_mode(fldcw, lsmode);
......
......@@ -488,12 +488,23 @@ ia32_am_type_t get_ia32_am_support(const ir_node *node) {
return attr->data.am_support;
}
ia32_am_arity_t get_ia32_am_arity(const ir_node *node) {
const ia32_attr_t *attr = get_ia32_attr_const(node);
return attr->data.am_arity;
}
/**
* Sets the supported address mode of an ia32 node
*/
void set_ia32_am_support(ir_node *node, ia32_am_type_t am_tp) {
void set_ia32_am_support(ir_node *node, ia32_am_type_t am_tp,
ia32_am_arity_t arity) {
ia32_attr_t *attr = get_ia32_attr(node);
attr->data.am_support = am_tp;
attr->data.am_arity = arity;
assert((am_tp == ia32_am_None && arity == ia32_am_arity_none) ||
(am_tp != ia32_am_None &&
((arity == ia32_am_unary) || (arity == ia32_am_binary))));
}
/**
......
......@@ -84,10 +84,13 @@ void set_ia32_immop_type(ir_node *node, ia32_immop_type_t tp);
*/
ia32_am_type_t get_ia32_am_support(const ir_node *node);
ia32_am_arity_t get_ia32_am_arity(const ir_node *node);
/**
* Sets the supported addrmode of an ia32 node
*/
void set_ia32_am_support(ir_node *node, ia32_am_type_t am_tp);
void set_ia32_am_support(ir_node *node, ia32_am_type_t am_tp,
ia32_am_arity_t am_arity);
/**
* Gets the addrmode flavour of an ia32 node
......
......@@ -52,9 +52,15 @@ typedef enum {
ia32_am_None = 0, /**<< no addrmode support */
ia32_am_Dest = 1, /**<< addrmode for destination only */
ia32_am_Source = 2, /**<< addrmode for source only */
ia32_am_Full = 3 /**<< full addmode support */
ia32_am_Full = 3, /**<< full addmode support */
} ia32_am_type_t;
typedef enum {
ia32_am_arity_none = 0,
ia32_am_unary = 1,
ia32_am_binary = 2,
} ia32_am_arity_t;
/**
* Different Address Mode properties:
* O - Offset is set
......@@ -99,16 +105,17 @@ typedef enum {
typedef struct ia32_attr_t ia32_attr_t;
struct ia32_attr_t {
except_attr exc; /**< the exception attribute. MUST be the first one. */
struct {
struct ia32_attr_data_bitfield {
unsigned tp:3; /**< ia32 node type. */
unsigned imm_tp:2; /**< ia32 immop type. */
unsigned am_support:2; /**< Indicates the address mode type supported by this node. */
unsigned am_arity : 2;
unsigned am_flavour:4; /**< The concrete address mode characteristics. */
unsigned am_scale:2; /**< The address mode scale for index register. */
unsigned am_sc_sign:1; /**< The sign bit of the address mode symconst. */
unsigned use_frame:1; /**< Indicates whether the operation uses the frame pointer or not. */
unsigned except_label:1; /**< Set if this node needs a label because of posiible exception. */
unsigned except_label:1; /**< Set if this node needs a label because of possible exception. */
ia32_op_flavour_t op_flav:2;/**< Flavour of an op (flavour_Div/Mod/DivMod). */
......@@ -154,6 +161,7 @@ struct ia32_attr_t {
const arch_register_t **slots; /**< register slots for assigned registers */
};
COMPILETIME_ASSERT(sizeof(struct ia32_attr_data_bitfield) <= 4, attr_bitfield);
typedef struct ia32_immediate_attr_t ia32_immediate_attr_t;
struct ia32_immediate_attr_t {
......
......@@ -45,7 +45,7 @@
#include "ia32_new_nodes.h"
#include "bearch_ia32_t.h"
#include "gen_ia32_regalloc_if_t.h"
#include "gen_ia32_regalloc_if.h"
#include "ia32_transform.h"
#include "ia32_dbg_stat.h"
#include "ia32_util.h"
......@@ -311,7 +311,7 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) {
// create a push
push = new_rd_ia32_Push(NULL, irg, block, noreg, noreg, val, curr_sp, mem);
set_ia32_am_support(push, ia32_am_Source);
set_ia32_am_support(push, ia32_am_Source, ia32_am_unary);
copy_ia32_Immop_attr(push, store);
sched_add_before(irn, push);
......@@ -527,7 +527,8 @@ static ia32_am_cand_t is_am_candidate(heights_t *h, const ir_node *block, ir_nod
int is_cand = 0, cand;
int arity;
if (is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn) || is_ia32_vfild(irn) || is_ia32_vfist(irn) ||
if (is_ia32_Ld(irn) || is_ia32_St(irn) ||
is_ia32_vfild(irn) || is_ia32_vfist(irn) ||
is_ia32_GetST0(irn) || is_ia32_SetST0(irn) || is_ia32_xStoreSimple(irn))
return 0;
......@@ -536,11 +537,11 @@ static ia32_am_cand_t is_am_candidate(heights_t *h, const ir_node *block, ir_nod
left = get_irn_n(irn, 2);
arity = get_irn_arity(irn);
assert(arity == 5 || arity == 4);
if(arity == 5) {
if(get_ia32_am_arity(irn) == ia32_am_binary) {
/* binary op */
right = get_irn_n(irn, 3);
} else {
assert(get_ia32_am_arity(irn) == ia32_am_unary);
/* unary op */
right = left;
}
......@@ -1327,6 +1328,7 @@ static void optimize_am(ir_node *irn, void *env) {
ir_node *addr_b, *addr_i;
int need_exchange_on_fail = 0;
ia32_am_type_t am_support;
ia32_am_arity_t am_arity;
ia32_am_cand_t cand;
ia32_am_cand_t orig_cand;
int dest_possible;
......@@ -1349,24 +1351,28 @@ static void optimize_am(ir_node *irn, void *env) {
return;
am_support = get_ia32_am_support(irn);
am_arity = get_ia32_am_arity(irn);
block = get_nodes_block(irn);
/* fold following patterns: */