From: Matthias Braun Date: Mon, 25 Jun 2007 19:25:43 +0000 (+0000) Subject: - Introduce nodemap X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=aef4d3b28b21856e05c0bd91552b51b69ed5ac50;p=libfirm - Introduce nodemap - All float operations depend on fpu mode now - Fix bestate switcher - Add and fix fehler22 (unknown phi operands in x87 simulator) [r14749] --- diff --git a/include/libfirm/adt/cpset.h b/include/libfirm/adt/cpset.h index 60e06d8ba..77934a82c 100644 --- a/include/libfirm/adt/cpset.h +++ b/include/libfirm/adt/cpset.h @@ -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 * diff --git a/include/libfirm/adt/hashset.h b/include/libfirm/adt/hashset.h index 9495ef0f7..54e49ca91 100644 --- a/include/libfirm/adt/hashset.h +++ b/include/libfirm/adt/hashset.h @@ -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 diff --git a/include/libfirm/adt/pset_new.h b/include/libfirm/adt/pset_new.h index 357f17c73..08a47ab5b 100644 --- a/include/libfirm/adt/pset_new.h +++ b/include/libfirm/adt/pset_new.h @@ -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 * diff --git a/ir/adt/cpset.c b/ir/adt/cpset.c index f5a0a26b3..d13447c68 100644 --- a/ir/adt/cpset.c +++ b/ir/adt/cpset.c @@ -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 diff --git a/ir/adt/hashset.c b/ir/adt/hashset.c index b3af299e9..08869b75b 100644 --- a/ir/adt/hashset.c +++ b/ir/adt/hashset.c @@ -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); diff --git a/ir/adt/pset_new.c b/ir/adt/pset_new.c index 975557f10..4f494af49 100644 --- a/ir/adt/pset_new.c +++ b/ir/adt/pset_new.c @@ -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); } diff --git a/ir/be/bestate.c b/ir/be/bestate.c index 7c228c255..5c152cfd7 100644 --- a/ir/be/bestate.c +++ b/ir/be/bestate.c @@ -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); } diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 24c18e065..f77ad76d7 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -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); diff --git a/ir/be/ia32/ia32_finish.c b/ir/be/ia32/ia32_finish.c index b7db6cd5c..b376c8640 100644 --- a/ir/be/ia32/ia32_finish.c +++ b/ir/be/ia32/ia32_finish.c @@ -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)); diff --git a/ir/be/ia32/ia32_fpu.c b/ir/be/ia32/ia32_fpu.c index ca5018dc3..003216c1f 100644 --- a/ir/be/ia32/ia32_fpu.c +++ b/ir/be/ia32/ia32_fpu.c @@ -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); diff --git a/ir/be/ia32/ia32_new_nodes.c b/ir/be/ia32/ia32_new_nodes.c index fe15be5b3..164dfbaa3 100644 --- a/ir/be/ia32/ia32_new_nodes.c +++ b/ir/be/ia32/ia32_new_nodes.c @@ -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)))); } /** diff --git a/ir/be/ia32/ia32_new_nodes.h b/ir/be/ia32/ia32_new_nodes.h index b464dbb1f..7389bb493 100644 --- a/ir/be/ia32/ia32_new_nodes.h +++ b/ir/be/ia32/ia32_new_nodes.h @@ -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 diff --git a/ir/be/ia32/ia32_nodes_attr.h b/ir/be/ia32/ia32_nodes_attr.h index f4daef57d..653a87110 100644 --- a/ir/be/ia32/ia32_nodes_attr.h +++ b/ir/be/ia32/ia32_nodes_attr.h @@ -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 { diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index dc8897150..50cd0c8b9 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -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: */ - /* - op -> Load into AMop with am_Source */ - /* conditions: */ - /* - op is am_Source capable AND */ - /* - the Load is only used by this op AND */ - /* - the Load is in the same block */ - /* - Store -> op -> Load into AMop with am_Dest */ - /* conditions: */ - /* - op is am_Dest capable AND */ - /* - the Store uses the same address as the Load AND */ - /* - the Load is only used by this op AND */ - /* - the Load and Store are in the same block AND */ - /* - nobody else uses the result of the op */ - if (get_ia32_am_support(irn) == ia32_am_None) + /* fold following patterns: + * - op -> Load into AMop with am_Source + * conditions: + * - op is am_Source capable AND + * - the Load is only used by this op AND + * - the Load is in the same block + * - Store -> op -> Load into AMop with am_Dest + * conditions: + * - op is am_Dest capable AND + * - the Store uses the same address as the Load AND + * - the Load is only used by this op AND + * - the Load and Store are in the same block AND + * - nobody else uses the result of the op + */ + if (am_support == ia32_am_None) return; + assert(am_arity == ia32_am_unary || am_arity == ia32_am_binary); + cand = is_am_candidate(h, block, irn); if (cand == IA32_AM_CAND_NONE) return; @@ -1376,8 +1382,7 @@ static void optimize_am(ir_node *irn, void *env) { cand & IA32_AM_CAND_LEFT, cand & IA32_AM_CAND_RIGHT)); left = get_irn_n(irn, 2); - if (get_irn_arity(irn) == 4) { - /* it's an "unary" operation */ + if (am_arity == ia32_am_unary) { right = left; assert(cand == IA32_AM_CAND_BOTH); } else { @@ -1491,7 +1496,7 @@ static void optimize_am(ir_node *irn, void *env) { set_ia32_am_sc_sign(irn); /* connect to Load memory and disconnect Load */ - if (get_irn_arity(irn) == 5) { + if (am_arity == ia32_am_binary) { /* binary AMop */ set_irn_n(irn, 4, get_irn_n(load, 2)); set_irn_n(irn, 2, ia32_get_admissible_noreg(cg, irn, 2)); @@ -1579,12 +1584,11 @@ static void optimize_am(ir_node *irn, void *env) { } /* connect to Load memory and disconnect Load */ - if (get_irn_arity(irn) == 5) { + if (am_arity == ia32_am_binary) { /* binary AMop */ set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3)); set_irn_n(irn, 4, get_irn_n(load, 2)); } else { - assert(get_irn_arity(irn) == 4); /* unary AMop */ set_irn_n(irn, 2, ia32_get_admissible_noreg(cg, irn, 2)); set_irn_n(irn, 3, get_irn_n(load, 2)); diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index a9462e07b..ffcb5e7f7 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -1410,7 +1410,8 @@ vfCMov => { vfadd => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -1419,7 +1420,8 @@ vfadd => { vfmul => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -1434,7 +1436,8 @@ l_vfmul => { vfsub => { irn_flags => "R", - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 4, units => [ "VFP" ], mode => "mode_E", @@ -1447,7 +1450,8 @@ l_vfsub => { }, vfdiv => { - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp", "none" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp", "none" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], outs => [ "res", "M" ], latency => 20, units => [ "VFP" ], @@ -1461,7 +1465,8 @@ l_vfdiv => { }, vfprem => { - reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] }, + reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] }, + ins => [ "base", "index", "left", "right", "mem", "fpcw" ], latency => 20, units => [ "VFP" ], mode => "mode_E", @@ -1476,6 +1481,7 @@ l_vfprem => { vfabs => { irn_flags => "R", reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + ins => [ "value" ], latency => 2, units => [ "VFP" ], mode => "mode_E", @@ -1485,39 +1491,13 @@ vfabs => { vfchs => { irn_flags => "R", reg_req => { in => [ "vfp"], out => [ "vfp" ] }, + ins => [ "value" ], latency => 2, units => [ "VFP" ], mode => "mode_E", attr_type => "ia32_x87_attr_t", }, -vfsin => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 150, - units => [ "VFP" ], - mode => "mode_E", - attr_type => "ia32_x87_attr_t", -}, - -vfcos => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 150, - units => [ "VFP" ], - mode => "mode_E", - attr_type => "ia32_x87_attr_t", -}, - -vfsqrt => { - irn_flags => "R", - reg_req => { in => [ "vfp"], out => [ "vfp" ] }, - latency => 30, - units => [ "VFP" ], - mode => "mode_E", - attr_type => "ia32_x87_attr_t", -}, - # virtual Load and Store vfld => { @@ -1552,6 +1532,7 @@ vfild => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] }, outs => [ "res", "M" ], + ins => [ "base", "index", "mem" ], latency => 4, units => [ "VFP" ], attr_type => "ia32_x87_attr_t", @@ -1566,6 +1547,7 @@ l_vfild => { vfist => { state => "exc_pinned", reg_req => { in => [ "gp", "gp", "vfp", "fpcw", "none" ] }, + ins => [ "base", "index", "val", "fpcw", "mem" ], latency => 4, units => [ "VFP" ], mode => "mode_M", @@ -1814,30 +1796,6 @@ fchs => { attr_type => "ia32_x87_attr_t", }, -fsin => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fsin', - attr_type => "ia32_x87_attr_t", -}, - -fcos => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fcos', - attr_type => "ia32_x87_attr_t", -}, - -fsqrt => { - op_flags => "R", - rd_constructor => "NONE", - reg_req => { }, - emit => '. fsqrt $', - attr_type => "ia32_x87_attr_t", -}, - # x87 Load and Store fld => { diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index d58c25aaf..f9f384623 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -95,6 +95,10 @@ typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, ir_node *op1, ir_node *op2, ir_node *mem); +typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg, + ir_node *block, ir_node *base, ir_node *index, ir_node *op1, + ir_node *op2, ir_node *mem, ir_node *fpcw); + typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, ir_node *op, ir_node *mem); @@ -284,7 +288,6 @@ static ir_node *gen_Const(ir_node *node) { floatent = get_entity_for_tv(env_cg, node); load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode); - set_ia32_am_support(load, ia32_am_Source); set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_flavour(load, ia32_am_N); set_ia32_am_sc(load, floatent); @@ -296,7 +299,6 @@ static ir_node *gen_Const(ir_node *node) { floatent = get_entity_for_tv(env_cg, node); load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem); - set_ia32_am_support(load, ia32_am_Source); set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_flavour(load, ia32_am_N); set_ia32_am_sc(load, floatent); @@ -371,49 +373,6 @@ static ir_node *gen_SymConst(ir_node *node) { return cnst; } -#if 0 -/** - * SSE convert of an integer node into a floating point node. - */ -static ir_node *gen_sse_conv_int2float(ia32_code_gen_t *cg, dbg_info *dbgi, - ir_graph *irg, ir_node *block, - ir_node *in, ir_node *old_node, ir_mode *tgt_mode) -{ - ir_node *noreg = ia32_new_NoReg_gp(cg); - ir_node *nomem = new_rd_NoMem(irg); - ir_node *old_pred = get_Cmp_left(old_node); - ir_mode *in_mode = get_irn_mode(old_pred); - int in_bits = get_mode_size_bits(in_mode); - ir_node *conv = new_rd_ia32_Conv_I2FP(dbgi, irg, block, noreg, noreg, in, nomem); - - set_ia32_ls_mode(conv, tgt_mode); - if (in_bits == 32) { - set_ia32_am_support(conv, ia32_am_Source); - } - SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node)); - - return conv; -} - -/** - * SSE convert of an float node into a double node. - */ -static ir_node *gen_sse_conv_f2d(ia32_code_gen_t *cg, dbg_info *dbgi, - ir_graph *irg, ir_node *block, - ir_node *in, ir_node *old_node) -{ - ir_node *noreg = ia32_new_NoReg_gp(cg); - ir_node *nomem = new_rd_NoMem(irg); - ir_node *conv = new_rd_ia32_Conv_FP2FP(dbgi, irg, block, noreg, noreg, in, nomem); - - set_ia32_am_support(conv, ia32_am_Source); - set_ia32_ls_mode(conv, mode_xmm); - SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node)); - - return conv; -} -#endif - /* Generates an entity for a known FP const (used for FP Neg + Abs) */ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) { static const struct { @@ -520,7 +479,8 @@ static void fold_immediate(ir_node *node, int in1, int in2) { } clear_ia32_commutative(node); - set_ia32_am_support(node, get_ia32_am_support(node) & ~ia32_am_Source); + set_ia32_am_support(node, get_ia32_am_support(node) & ~ia32_am_Source, + get_ia32_am_arity(node)); } /** @@ -566,9 +526,9 @@ static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2, new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, nomem); if (func == new_rd_ia32_IMul) { - set_ia32_am_support(new_node, ia32_am_Source); + set_ia32_am_support(new_node, ia32_am_Source, ia32_am_binary); } else { - set_ia32_am_support(new_node, ia32_am_Full); + set_ia32_am_support(new_node, ia32_am_Full, ia32_am_binary); } SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); @@ -587,8 +547,8 @@ static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2, * @param func The node constructor function * @return The constructed ia32 node. */ -static ir_node *gen_binop_float(ir_node *node, ir_node *op1, ir_node *op2, - construct_binop_func *func) +static ir_node *gen_binop_sse_float(ir_node *node, ir_node *op1, ir_node *op2, + construct_binop_func *func) { ir_node *block = be_transform_node(get_nodes_block(node)); ir_node *new_op1 = be_transform_node(op1); @@ -600,8 +560,9 @@ static ir_node *gen_binop_float(ir_node *node, ir_node *op1, ir_node *op2, ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg); ir_node *nomem = new_NoMem(); - new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, nomem); - set_ia32_am_support(new_node, ia32_am_Source); + new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, + nomem); + set_ia32_am_support(new_node, ia32_am_Source, ia32_am_binary); if (is_op_commutative(get_irn_op(node))) { set_ia32_commutative(new_node); } @@ -614,6 +575,43 @@ static ir_node *gen_binop_float(ir_node *node, ir_node *op1, ir_node *op2, return new_node; } +/** + * Construct a standard binary operation, set AM and immediate if required. + * + * @param op1 The first operand + * @param op2 The second operand + * @param func The node constructor function + * @return The constructed ia32 node. + */ +static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2, + construct_binop_float_func *func) +{ + ir_node *block = be_transform_node(get_nodes_block(node)); + ir_node *new_op1 = be_transform_node(op1); + ir_node *new_op2 = be_transform_node(op2); + ir_node *new_node = NULL; + dbg_info *dbgi = get_irn_dbg_info(node); + ir_graph *irg = current_ir_graph; + ir_mode *mode = get_irn_mode(node); + ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg); + ir_node *nomem = new_NoMem(); + ir_node *fpcw = be_abi_get_ignore_irn(env_cg->birg->abi, + &ia32_fp_cw_regs[REG_FPCW]); + + new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, + nomem, fpcw); + set_ia32_am_support(new_node, ia32_am_Source, ia32_am_binary); + if (is_op_commutative(get_irn_op(node))) { + set_ia32_commutative(new_node); + } + if (USE_SSE2(env_cg)) { + set_ia32_ls_mode(new_node, mode); + } + + SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); + + return new_node; +} /** * Construct a shift/rotate binary operation, sets AM and immediate if required. @@ -646,7 +644,7 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2, new_op = func(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem); /* set AM support */ - set_ia32_am_support(new_op, ia32_am_Dest); + set_ia32_am_support(new_op, ia32_am_Dest, ia32_am_binary); SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); @@ -675,7 +673,7 @@ static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func) new_node = func(dbgi, irg, block, noreg, noreg, new_op, nomem); DB((dbg, LEVEL_1, "INT unop ...")); - set_ia32_am_support(new_node, ia32_am_Dest); + set_ia32_am_support(new_node, ia32_am_Dest, ia32_am_unary); SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); @@ -711,9 +709,9 @@ static ir_node *gen_Add(ir_node *node) { if (mode_is_float(mode)) { FP_USED(env_cg); if (USE_SSE2(env_cg)) - return gen_binop_float(node, op1, op2, new_rd_ia32_xAdd); + return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd); else - return gen_binop_float(node, op1, op2, new_rd_ia32_vfadd); + return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd); } /* integer ADD */ @@ -734,7 +732,6 @@ static ir_node *gen_Add(ir_node *node) { new_op = new_rd_ia32_Lea(dbgi, irg, block, new_op1, noreg); set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op2)); set_ia32_am_flavour(new_op, ia32_am_B); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); DBG_OPT_LEA3(new_op1, new_op2, node, new_op); @@ -749,7 +746,6 @@ static ir_node *gen_Add(ir_node *node) { set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op1)); add_ia32_am_offs_int(new_op, offs); set_ia32_am_flavour(new_op, ia32_am_OB); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); } else if (tp2 == ia32_ImmSymConst) { tarval *tv = get_ia32_Immop_tarval(new_op1); @@ -762,7 +758,6 @@ static ir_node *gen_Add(ir_node *node) { add_ia32_am_offs_int(new_op, offs); set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op2)); set_ia32_am_flavour(new_op, ia32_am_OB); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); } else { tarval *tv1 = get_ia32_Immop_tarval(new_op1); @@ -805,7 +800,7 @@ static ir_node *gen_Add(ir_node *node) { new_op = new_rd_ia32_Add(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem); /* set AM support */ - set_ia32_am_support(new_op, ia32_am_Full); + set_ia32_am_support(new_op, ia32_am_Full, ia32_am_binary); set_ia32_commutative(new_op); fold_immediate(new_op, 2, 3); @@ -830,7 +825,7 @@ static ir_node *create_ia32_Mul(ir_node *node) { res = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_op1, new_op2, new_NoMem()); set_ia32_commutative(res); - set_ia32_am_support(res, ia32_am_Source); + set_ia32_am_support(res, ia32_am_Source | ia32_am_binary); /* imediates are not supported, so no fold_immediate */ proj_EAX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EAX); @@ -858,9 +853,9 @@ static ir_node *gen_Mul(ir_node *node) { if (mode_is_float(mode)) { FP_USED(env_cg); if (USE_SSE2(env_cg)) - return gen_binop_float(node, op1, op2, new_rd_ia32_xMul); + return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul); else - return gen_binop_float(node, op1, op2, new_rd_ia32_vfmul); + return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul); } /* @@ -899,9 +894,7 @@ static ir_node *gen_Mulh(ir_node *node) { } set_ia32_commutative(res); - set_ia32_am_support(res, ia32_am_Source); - - set_ia32_am_support(res, ia32_am_Source); + set_ia32_am_support(res, ia32_am_Source, ia32_am_binary); proj_EAX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EAX); proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EDX); @@ -982,7 +975,7 @@ static ir_node *gen_Max(ir_node *node) { if (mode_is_float(mode)) { FP_USED(env_cg); if (USE_SSE2(env_cg)) { - new_op = gen_binop_float(node, new_op1, new_op2, new_rd_ia32_xMax); + new_op = gen_binop_sse_float(node, new_op1, new_op2, new_rd_ia32_xMax); } else { panic("Can't create Max node"); } @@ -1021,7 +1014,7 @@ static ir_node *gen_Min(ir_node *node) { if (mode_is_float(mode)) { FP_USED(env_cg); if (USE_SSE2(env_cg)) { - new_op = gen_binop_float(node, op1, op2, new_rd_ia32_xMin); + new_op = gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMin); } else { panic("can't create Min node"); } @@ -1068,9 +1061,9 @@ static ir_node *gen_Sub(ir_node *node) { if (mode_is_float(mode)) { FP_USED(env_cg); if (USE_SSE2(env_cg)) - return gen_binop_float(node, op1, op2, new_rd_ia32_xSub); + return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xSub); else - return gen_binop_float(node, op1, op2, new_rd_ia32_vfsub); + return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub); } /* integer SUB */ @@ -1104,7 +1097,6 @@ static ir_node *gen_Sub(ir_node *node) { set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op1)); add_ia32_am_offs_int(new_op, -offs); set_ia32_am_flavour(new_op, ia32_am_OB); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); } else if (tp2 == ia32_ImmSymConst) { tarval *tv = get_ia32_Immop_tarval(new_op1); @@ -1118,7 +1110,6 @@ static ir_node *gen_Sub(ir_node *node) { set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op2)); set_ia32_am_sc_sign(new_op); set_ia32_am_flavour(new_op, ia32_am_OB); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); } else { tarval *tv1 = get_ia32_Immop_tarval(new_op1); @@ -1161,7 +1152,7 @@ static ir_node *gen_Sub(ir_node *node) { new_op = new_rd_ia32_Sub(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem); /* set AM support */ - set_ia32_am_support(new_op, ia32_am_Full); + set_ia32_am_support(new_op, ia32_am_Full, ia32_am_binary); fold_immediate(new_op, 2, 3); @@ -1251,7 +1242,7 @@ static ir_node *generate_DivMod(ir_node *node, ir_node *dividend, /* Matze: code can't handle this at the moment... */ #if 0 /* set AM support */ - set_ia32_am_support(res, ia32_am_Source); + set_ia32_am_support(res, ia32_am_Source, ia32_am_binary); #endif /* check, which Proj-Keep, we need to add */ @@ -1325,18 +1316,21 @@ static ir_node *gen_Quot(ir_node *node) { ir_mode *mode = get_irn_mode(op1); if (is_ia32_xConst(new_op2)) { new_op = new_rd_ia32_xDiv(dbgi, irg, block, noreg, noreg, new_op1, noreg, nomem); - set_ia32_am_support(new_op, ia32_am_None); + set_ia32_am_support(new_op, ia32_am_None, ia32_am_arity_none); copy_ia32_Immop_attr(new_op, new_op2); } else { new_op = new_rd_ia32_xDiv(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem); // Matze: disabled for now, spillslot coalescer fails - //set_ia32_am_support(new_op, ia32_am_Source); + //set_ia32_am_support(new_op, ia32_am_Source | ia32_am_binary); } set_ia32_ls_mode(new_op, mode); } else { - new_op = new_rd_ia32_vfdiv(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem); + ir_node *fpcw = be_abi_get_ignore_irn(env_cg->birg->abi, + &ia32_fp_cw_regs[REG_FPCW]); + new_op = new_rd_ia32_vfdiv(dbgi, irg, block, noreg, noreg, new_op1, + new_op2, nomem, fpcw); // Matze: disabled for now (spillslot coalescer fails) - //set_ia32_am_support(new_op, ia32_am_Source); + //set_ia32_am_support(new_op, ia32_am_Source | ia32_am_binary); } SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); return new_op; @@ -1661,7 +1655,6 @@ static ir_node *gen_Load(ir_node *node) { } set_irn_pinned(new_op, get_irn_pinned(node)); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); set_ia32_am_flavour(new_op, am_flav); set_ia32_ls_mode(new_op, mode); @@ -1750,7 +1743,6 @@ static ir_node *gen_Store(ir_node *node) { } set_irn_pinned(new_op, get_irn_pinned(node)); - set_ia32_am_support(new_op, ia32_am_Dest); set_ia32_op_type(new_op, ia32_AddrModeD); set_ia32_am_flavour(new_op, am_flav); set_ia32_ls_mode(new_op, mode); @@ -1872,7 +1864,7 @@ static ir_node *gen_Cond(ir_node *node) { // is not able to detect the mode of the spilled value // moreover, the lea optimize phase freely exchanges left/right // without updating the pnc - //set_ia32_am_support(res, ia32_am_Source); + //set_ia32_am_support(res, ia32_am_Source | ia32_am_binary); } else { /* determine the smallest switch case value */ @@ -1891,7 +1883,6 @@ static ir_node *gen_Cond(ir_node *node) { SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node)); add_ia32_am_offs_int(res, -switch_min); set_ia32_am_flavour(res, ia32_am_OB); - set_ia32_am_support(res, ia32_am_Source); set_ia32_op_type(res, ia32_AddrModeS); } @@ -2123,7 +2114,6 @@ static ir_node *gen_x87_fp_to_gp(ir_node *node) { set_irn_pinned(fist, op_pin_state_floats); set_ia32_use_frame(fist); - set_ia32_am_support(fist, ia32_am_Dest); set_ia32_op_type(fist, ia32_AddrModeD); set_ia32_am_flavour(fist, ia32_am_B); set_ia32_ls_mode(fist, mode_Iu); @@ -2134,7 +2124,6 @@ static ir_node *gen_x87_fp_to_gp(ir_node *node) { set_irn_pinned(load, op_pin_state_floats); set_ia32_use_frame(load); - set_ia32_am_support(load, ia32_am_Source); set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_flavour(load, ia32_am_B); set_ia32_ls_mode(load, mode_Iu); @@ -2161,12 +2150,12 @@ static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) { src_bits = get_mode_size_bits(src_mode); if (src_bits == 8) { new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, new_op, nomem); - set_ia32_am_support(new_op, ia32_am_Source); + set_ia32_am_support(new_op, ia32_am_Source, ia32_am_unary); set_ia32_ls_mode(new_op, src_mode); SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); } else if (src_bits < 32) { new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, new_op, nomem); - set_ia32_am_support(new_op, ia32_am_Source); + set_ia32_am_support(new_op, ia32_am_Source, ia32_am_unary); set_ia32_ls_mode(new_op, src_mode); SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); } @@ -2175,7 +2164,6 @@ static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) { store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, new_op, nomem); set_ia32_use_frame(store); - set_ia32_am_support(store, ia32_am_Dest); set_ia32_op_type(store, ia32_AddrModeD); set_ia32_am_flavour(store, ia32_am_OB); set_ia32_ls_mode(store, mode_Iu); @@ -2184,7 +2172,6 @@ static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) { fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store); set_ia32_use_frame(fild); - set_ia32_am_support(fild, ia32_am_Source); set_ia32_op_type(fild, ia32_AddrModeS); set_ia32_am_flavour(fild, ia32_am_OB); set_ia32_ls_mode(fild, mode_Iu); @@ -2215,14 +2202,12 @@ static ir_node *create_Strict_conv(ir_mode *src_mode, ir_mode *tgt_mode, store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, node, nomem, smaller_mode); set_ia32_use_frame(store); - set_ia32_am_support(store, ia32_am_Dest); set_ia32_op_type(store, ia32_AddrModeD); set_ia32_am_flavour(store, ia32_am_OB); load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store, smaller_mode); set_ia32_use_frame(load); - set_ia32_am_support(load, ia32_am_Source); set_ia32_op_type(load, ia32_AddrModeS); set_ia32_am_flavour(load, ia32_am_OB); @@ -2307,7 +2292,7 @@ static ir_node *gen_Conv(ir_node *node) { res = new_rd_ia32_Conv_I2FP(dbgi, irg, block, noreg, noreg, new_op, nomem); set_ia32_ls_mode(res, tgt_mode); if(src_bits == 32) { - set_ia32_am_support(res, ia32_am_Source); + set_ia32_am_support(res, ia32_am_Source, ia32_am_unary); } } else { return gen_x87_gp_to_fp(node, src_mode); @@ -2338,7 +2323,7 @@ static ir_node *gen_Conv(ir_node *node) { res = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, new_op, nomem); set_ia32_ls_mode(res, smaller_mode); } - set_ia32_am_support(res, ia32_am_Source); + set_ia32_am_support(res, ia32_am_Source, ia32_am_unary); } } @@ -2892,7 +2877,6 @@ static ir_node *gen_be_StackParam(ir_node *node) { set_ia32_frame_ent(new_op, ent); set_ia32_use_frame(new_op); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); set_ia32_am_flavour(new_op, ia32_am_B); set_ia32_ls_mode(new_op, load_mode); @@ -2917,7 +2901,6 @@ static ir_node *gen_be_FrameAddr(ir_node *node) { res = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg); set_ia32_frame_ent(res, arch_get_frame_entity(env_cg->arch_env, node)); - set_ia32_am_support(res, ia32_am_Full); set_ia32_use_frame(res); set_ia32_am_flavour(res, ia32_am_OB); @@ -2962,7 +2945,6 @@ static ir_node *gen_be_FrameLoad(ir_node *node) { set_ia32_frame_ent(new_op, ent); set_ia32_use_frame(new_op); - set_ia32_am_support(new_op, ia32_am_Source); set_ia32_op_type(new_op, ia32_AddrModeS); set_ia32_am_flavour(new_op, ia32_am_B); set_ia32_ls_mode(new_op, mode); @@ -3008,7 +2990,6 @@ static ir_node *gen_be_FrameStore(ir_node *node) { set_ia32_frame_ent(new_op, ent); set_ia32_use_frame(new_op); - set_ia32_am_support(new_op, ia32_am_Dest); set_ia32_op_type(new_op, ia32_AddrModeD); set_ia32_am_flavour(new_op, ia32_am_B); set_ia32_ls_mode(new_op, mode); @@ -3082,7 +3063,6 @@ static ir_node *gen_be_Return(ir_node *node) { set_ia32_op_type(sse_store, ia32_AddrModeD); set_ia32_use_frame(sse_store); set_ia32_am_flavour(sse_store, ia32_am_B); - set_ia32_am_support(sse_store, ia32_am_Dest); /* load into st0 */ fld = new_rd_ia32_SetST0(dbgi, irg, block, frame, noreg, sse_store); @@ -3090,7 +3070,6 @@ static ir_node *gen_be_Return(ir_node *node) { set_ia32_op_type(fld, ia32_AddrModeS); set_ia32_use_frame(fld); set_ia32_am_flavour(fld, ia32_am_B); - set_ia32_am_support(fld, ia32_am_Source); mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_SetST0_M); fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_SetST0_res); @@ -3148,7 +3127,7 @@ static ir_node *gen_be_AddSP(ir_node *node) { /* ia32 stack grows in reverse direction, make a SubSP */ new_op = new_rd_ia32_SubSP(dbgi, irg, block, noreg, noreg, new_sp, new_sz, nomem); - set_ia32_am_support(new_op, ia32_am_Source); + set_ia32_am_support(new_op, ia32_am_Source, ia32_am_binary); SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); return new_op; @@ -3176,7 +3155,7 @@ static ir_node *gen_be_SubSP(ir_node *node) { /* ia32 stack grows in reverse direction, make an AddSP */ new_op = new_rd_ia32_AddSP(dbgi, irg, block, noreg, noreg, new_sp, new_sz, nomem); - set_ia32_am_support(new_op, ia32_am_Source); + set_ia32_am_support(new_op, ia32_am_Source, ia32_am_binary); SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); return new_op; @@ -3284,7 +3263,6 @@ static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func, char f new_op = func(dbgi, irg, block, new_ptr, noreg, new_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_am_OB); set_ia32_am_offs_int(new_op, 0); @@ -3339,7 +3317,6 @@ static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func, char add_ia32_am_offs_int(new_op, am_offs); } - set_ia32_am_support(new_op, ia32_am_Dest); set_ia32_op_type(new_op, ia32_AddrModeD); set_ia32_am_flavour(new_op, am_flav); set_ia32_ls_mode(new_op, mode); @@ -3368,11 +3345,11 @@ static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func, char } #define GEN_LOWERED_x87_OP(op) \ - static ir_node *gen_ia32_l_##op(ir_node *node) {\ + static ir_node *gen_ia32_l_##op(ir_node *node) { \ ir_node *new_op; \ - FORCE_x87(env_cg); \ - new_op = gen_binop_float(node, get_binop_left(node), \ - get_binop_right(node), new_rd_ia32_##op); \ + FORCE_x87(env_cg); \ + new_op = gen_binop_x87_float(node, get_binop_left(node), \ + get_binop_right(node), new_rd_ia32_##op); \ return new_op; \ } @@ -3425,11 +3402,14 @@ static ir_node *gen_ia32_l_vfdiv(ir_node *node) { ir_node *noreg = ia32_new_NoReg_gp(env_cg); ir_graph *irg = current_ir_graph; dbg_info *dbgi = get_irn_dbg_info(node); + ir_node *fpcw = be_abi_get_ignore_irn(env_cg->birg->abi, + &ia32_fp_cw_regs[REG_FPCW]); ir_node *vfdiv; - vfdiv = new_rd_ia32_vfdiv(dbgi, irg, block, noreg, noreg, new_left, new_right, new_NoMem()); + vfdiv = new_rd_ia32_vfdiv(dbgi, irg, block, noreg, noreg, new_left, + new_right, new_NoMem(), fpcw); clear_ia32_commutative(vfdiv); - set_ia32_am_support(vfdiv, ia32_am_Source); + set_ia32_am_support(vfdiv, ia32_am_Source, ia32_am_binary); SET_IA32_ORIG_NODE(vfdiv, ia32_get_old_node_name(env_cg, node)); @@ -3457,9 +3437,10 @@ static ir_node *gen_ia32_l_Mul(ir_node *node) { /* l_Mul is already a mode_T node, so we create the Mul in the normal way */ /* and then skip the result Proj, because all needed Projs are already there. */ - ir_node *muls = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_left, new_right, new_NoMem()); + ir_node *muls = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_left, + new_right, new_NoMem()); clear_ia32_commutative(muls); - set_ia32_am_support(muls, ia32_am_Source); + set_ia32_am_support(muls, ia32_am_Source, ia32_am_binary); /* check if EAX and EDX proj exist, add missing one */ in[0] = new_rd_Proj(dbgi, irg, block, muls, mode_Iu, pn_EAX); @@ -3541,8 +3522,7 @@ static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *op1, } /* set AM support */ - // Matze: node has unsupported format (6inputs) - //set_ia32_am_support(new_op, ia32_am_Dest); + set_ia32_am_support(new_op, ia32_am_Dest, ia32_am_binary); SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node)); @@ -3591,7 +3571,6 @@ static ir_node *gen_ia32_l_X87toSSE(ir_node *node) { set_ia32_frame_ent(res, get_ia32_frame_ent(node)); set_ia32_use_frame(res); set_ia32_ls_mode(res, get_ia32_ls_mode(node)); - set_ia32_am_support(res, ia32_am_Dest); set_ia32_am_flavour(res, ia32_B); set_ia32_op_type(res, ia32_AddrModeD); @@ -3600,7 +3579,6 @@ static ir_node *gen_ia32_l_X87toSSE(ir_node *node) { set_ia32_frame_ent(res, get_ia32_frame_ent(node)); set_ia32_use_frame(res); set_ia32_ls_mode(res, get_ia32_ls_mode(node)); - set_ia32_am_support(res, ia32_am_Source); set_ia32_am_flavour(res, ia32_B); set_ia32_op_type(res, ia32_AddrModeS); res = new_rd_Proj(dbgi, irg, block, res, mode_xmm, pn_ia32_xLoad_res); @@ -3650,7 +3628,6 @@ static ir_node *gen_ia32_l_SSEtoX87(ir_node *node) { set_ia32_frame_ent(res, fent); set_ia32_use_frame(res); set_ia32_ls_mode(res, lsmode); - set_ia32_am_support(res, ia32_am_Dest); set_ia32_am_flavour(res, ia32_B); set_ia32_op_type(res, ia32_AddrModeD); mem = res; @@ -3661,7 +3638,6 @@ static ir_node *gen_ia32_l_SSEtoX87(ir_node *node) { set_ia32_frame_ent(res, fent); set_ia32_use_frame(res); add_ia32_am_offs_int(res, offs); - set_ia32_am_support(res, ia32_am_Source); set_ia32_am_flavour(res, ia32_B); set_ia32_op_type(res, ia32_AddrModeS); res = new_rd_Proj(dbgi, irg, block, res, mode_vfp, pn_ia32_vfld_res); @@ -3980,7 +3956,6 @@ static ir_node *gen_Proj_be_Call(ir_node *node) { set_ia32_op_type(fstp, ia32_AddrModeD); set_ia32_use_frame(fstp); set_ia32_am_flavour(fstp, ia32_am_B); - set_ia32_am_support(fstp, ia32_am_Dest); /* load into SSE register */ sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp); @@ -3988,7 +3963,6 @@ static ir_node *gen_Proj_be_Call(ir_node *node) { set_ia32_op_type(sse_load, ia32_AddrModeS); set_ia32_use_frame(sse_load); set_ia32_am_flavour(sse_load, ia32_am_B); - set_ia32_am_support(sse_load, ia32_am_Source); sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm, pn_ia32_xLoad_res); @@ -4057,10 +4031,8 @@ static ir_node *gen_Proj_Cmp(ir_node *node) } /* TODO: * (a == b) -> !(a ^ b) - * (a < 0) -> (a & 0x80000000) - * (a <= 0) -> !(a & 0x7fffffff) - * (a > 0) -> (a & 0x7fffffff) - * (a >= 0) -> !(a & 0x80000000) + * (a < 0) -> (a & 0x80000000) oder a >> 31 + * (a >= 0) -> (a >> 31) ^ 1 */ if(!mode_is_signed(cmp_mode)) { diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index cb17768e7..79a2b0654 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -1166,8 +1166,8 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) { } else { op2_idx = x87_on_stack(state, op2_reg_idx); live_after_node = is_vfp_live(arch_register_get_index(op2), live); - assert(op2_idx >= 0); DB((dbg, LEVEL_1, ">>> %+F %s ->\n", n, arch_register_get_name(op2))); + assert(op2_idx >= 0); } mode = get_ia32_ls_mode(n); @@ -1288,9 +1288,6 @@ GEN_BINOP(fprem) GEN_UNOP(fabs) GEN_UNOP(fchs) -GEN_UNOP(fsin) -GEN_UNOP(fcos) -GEN_UNOP(fsqrt) GEN_LOAD(fld) GEN_LOAD(fild) @@ -2006,6 +2003,43 @@ static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state * return state; } /* x87_kill_deads */ +/** + * If we have PhiEs with unknown operands then we have to make sure that some + * value is actually put onto the stack. + */ +static void fix_unknown_phis(x87_state *state, ir_node *block, + ir_node *pred_block, int pos) +{ + ir_node *node; + + sched_foreach(block, node) { + ir_node *zero; + const arch_register_t *reg; + ia32_x87_attr_t *attr; + + if(!is_Phi(node)) + break; + + ir_node *op = get_Phi_pred(node, pos); + if(!is_ia32_Unknown_VFP(op)) + continue; + + reg = arch_get_irn_register(state->sim->arch_env, node); + + /* create a zero at end of pred block */ + zero = new_rd_ia32_fldz(NULL, current_ir_graph, pred_block, mode_E); + x87_push(state, arch_register_get_index(reg), zero); + + attr = get_ia32_x87_attr(zero); + attr->x87[2] = &ia32_st_regs[0]; + + assert(is_ia32_fldz(zero)); + sched_add_before(sched_last(pred_block), zero); + + set_Phi_pred(node, pos, zero); + } +} + /** * Run a simulation and fix all virtual instructions for a block. * @@ -2074,8 +2108,11 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) { succ_state = x87_get_bl_state(sim, succ); + fix_unknown_phis(state, succ, block, get_edge_src_pos(edge)); + if (succ_state->begin == NULL) { succ_state->begin = state; + waitq_put(sim->worklist, succ); } else { /* There is already a begin state for the successor, bad. @@ -2128,9 +2165,6 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, ASSOC_IA32(fprem); ASSOC_IA32(fabs); ASSOC_IA32(fchs); - ASSOC_IA32(fsin); - ASSOC_IA32(fcos); - ASSOC_IA32(fsqrt); ASSOC_IA32(fist); ASSOC_IA32(fst); ASSOC_IA32(fCondJmp); diff --git a/ir/be/test/bad_ones b/ir/be/test/bad_ones deleted file mode 100644 index e69de29bb..000000000 diff --git a/ir/be/test/fehler22.c b/ir/be/test/fehler22.c index f71599c8f..370edf237 100644 --- a/ir/be/test/fehler22.c +++ b/ir/be/test/fehler22.c @@ -2,23 +2,8 @@ const wchar_t AmmoCaliber[][20] = { - L"0", + L"BlupBlupBlupBlupBlup", L".38 Kal", - L"9mm", - L".45 Kal", - L".357 Kal", - L"12 Kal", - L"CAWS", - L"5.45mm", - L"5.56mm", - L"7.62mm NATO", - L"7.62mm WP", - L"4.7mm", - L"5.7mm", - L"Monster", - L"Rakete", - L"", - L"", }; diff --git a/ir/be/test/good_ones b/ir/be/test/good_ones deleted file mode 100644 index d52e03a78..000000000 --- a/ir/be/test/good_ones +++ /dev/null @@ -1,117 +0,0 @@ -Args.c -Arrays.c -BinaryOpTest.c -BreakTest.c -ByteTest.c -CallingTest.c -CondExpr.c -ContinueTest.c -DeclTest.c -DivBug.c -Do.c -Doit.c -Empty.c -EmptyFor.c -Field.c -Float.c -ForTest.c -GlobalCseTest.c -Hanoi.c -HeapSort.c -HelloWorld.c -IfExpr.c -Int.c -Label.c -Local.c -MergeSort.c -Or.c -Pdg.c -Queens.c -QuickSort.c -RegallocBug.c -Return.c -SimpleExpr.c -Sieve.c -SieveBits.c -Strings.c -Swap.c -Switcher.c -Test.c -Thilo.c -While.c -XXEndless.c -adam_putt.c -addr_test.c -alloca.c -am_test.c -andtest.c -apfel.c -array_type.c -biggest_prime.c -bsp.c -callref.c -calls.c -cmp.c -compress95.c -conv.c -convtest.c -d.c -dblstruct.c -divtest.c -duffs.c -enum.c -fe_bug.c -fehler1.c -fehler10.c -fehler11.c -fehler12.c -fehler3.c -fehler4.c -fehler5.c -fehler6.c -fehler7.c -fehler8.c -fehler9.c -fbench.c -ffbench.c -func_arg.c -gcd.c -harness.c -iabs.c -if.c -ll_call.c -max.c -mul.c -multidim-array.c -nested_loops.c -nested_loops2.c -ns.c -nullnode.c -optest.c -pbqp_RedN.c -rotate.c -simd1-i.c -simd1.c -simd2.c -simple.c -sret.c -stmt_expr.c -strenght_red.c -struct.c -structtest.c -switch_test.c -switch_test2.c -tailrec.c -trivial_add.c -trivial_div.c -trivial_empty.c -trivial_extern_add.c -trivial_max.c -trivial_sum_upto.c -trivial_two_times.c -truth.c -types.c -types2.c -use_uninit_ptr.c -while-printf.c -wrong_cmp.c diff --git a/ir/ir/irnodeset.c b/ir/ir/irnodeset.c index 9ac762469..bac3fb00d 100644 --- a/ir/ir/irnodeset.c +++ b/ir/ir/irnodeset.c @@ -39,9 +39,9 @@ #define NullValue NULL #define DeletedValue ((ir_node*)-1) #ifdef DEBUG_libfirm -#define Hash(this,value) ((unsigned)((value)->node_nr)) +#define Hash(this,key) ((unsigned)((key)->node_nr)) #else -#define Hash(this,value) HASH_PTR(value) +#define Hash(this,key) HASH_PTR(key) #endif #define KeysEqual(this,key1,key2) (key1) == (key2) #define SetRangeEmpty(ptr,size) memset(ptr, 0, (size) * sizeof((ptr)[0])) @@ -66,5 +66,5 @@ void ir_nodeset_init(ir_nodeset_t *nodeset) int ir_nodeset_contains(const ir_nodeset_t *this, const ir_node *node) { - return _ir_nodeset_find(this, node) != NULL; + return _ir_nodeset_find(this, node); } diff --git a/ir/ir/irnodeset.h b/ir/ir/irnodeset.h index afbfac818..56a7df849 100644 --- a/ir/ir/irnodeset.h +++ b/ir/ir/irnodeset.h @@ -30,7 +30,7 @@ #ifndef _FIRM_IRNODESET_H_ #define _FIRM_IRNODESET_H_ -#include "irnode.h" +#include "firm_types.h" #include "xmalloc.h" #define HashSet ir_nodeset_t @@ -43,6 +43,9 @@ #undef HashSetIterator #undef HashSet +typedef struct ir_nodeset_t ir_nodeset_t; +typedef struct ir_nodeset_iterator_t ir_nodeset_iterator_t; + /** * Initializes a nodeset with default size. * diff --git a/ir/opt/reassoc.c b/ir/opt/reassoc.c index 2b3e10ce3..f42c6c126 100644 --- a/ir/opt/reassoc.c +++ b/ir/opt/reassoc.c @@ -182,6 +182,9 @@ static int reassoc_Sub(ir_node **in) DBG((dbg, LEVEL_5, "Applied: %n - %n => %n + (-%n)\n", get_Sub_left(n), c, get_Sub_left(n), c)); + if(n == irn) + return 0; + exchange(n, irn); *in = irn; diff --git a/ir/tv/tv.c b/ir/tv/tv.c index f7a8f22b3..f022fd68d 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -100,6 +100,8 @@ static struct set *tarvals = NULL; /* container for tarval structs */ static struct set *values = NULL; /* container for values */ static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP; +static int no_float = 1; + /**************************************************************************** * private functions ****************************************************************************/ @@ -747,6 +749,8 @@ pn_Cmp tarval_cmp(tarval *a, tarval *b) { return pn_Cmp_False; case irms_float_number: + if(no_float) + return pn_Cmp_False; /* * BEWARE: we cannot compare a == b here, because * a NaN is always Unordered to any other value, even to itself! @@ -967,6 +971,9 @@ tarval *tarval_neg(tarval *a) { return get_tarval_overflow(buffer, a->length, a->mode); case irms_float_number: + if(no_float) + return tarval_bad; + fc_neg(a->value, NULL); return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -999,6 +1006,9 @@ tarval *tarval_add(tarval *a, tarval *b) { return get_tarval_overflow(buffer, a->length, a->mode); case irms_float_number: + if(no_float) + return tarval_bad; + fc_add(a->value, b->value, NULL); return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -1030,6 +1040,9 @@ tarval *tarval_sub(tarval *a, tarval *b) { return get_tarval_overflow(buffer, a->length, a->mode); case irms_float_number: + if(no_float) + return tarval_bad; + fc_sub(a->value, b->value, NULL); return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -1061,6 +1074,9 @@ tarval *tarval_mul(tarval *a, tarval *b) { return get_tarval_overflow(buffer, a->length, a->mode); case irms_float_number: + if(no_float) + return tarval_bad; + fc_mul(a->value, b->value, NULL); return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -1077,6 +1093,9 @@ tarval *tarval_quo(tarval *a, tarval *b) { assert(b); assert((a->mode == b->mode) && mode_is_float(a->mode)); + if(no_float) + return tarval_bad; + if (get_mode_n_vector_elems(a->mode) > 1) { /* vector arithmetic not implemented yet */ return tarval_bad; @@ -1152,6 +1171,9 @@ tarval *tarval_abs(tarval *a) { return a; case irms_float_number: + if(no_float) + return tarval_bad; + if (fc_comp(a->value, get_mode_null(a->mode)->value) == -1) { fc_neg(a->value, NULL); return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);