X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Flower%2Flower_copyb.c;h=eac96a36c838da2fd1323c516c3f158fd73c60e2;hb=8057f671ea7f286a27e40bfe1aa45d85e0990cbe;hp=b4b114cad952b414340f9f3672c1a25708cd7da6;hpb=6638be02a7a97559707fe3c70c1759eb030b74f6;p=libfirm diff --git a/ir/lower/lower_copyb.c b/ir/lower/lower_copyb.c index b4b114cad..eac96a36c 100644 --- a/ir/lower/lower_copyb.c +++ b/ir/lower/lower_copyb.c @@ -21,7 +21,6 @@ * @file * @brief Lower small CopyB nodes into a series of Load/Store nodes * @author Michael Beck, Matthias Braun, Manuel Mohr - * @version $Id$ */ #include "config.h" @@ -86,6 +85,8 @@ static unsigned max_small_size; /**< The maximum size of a CopyB node static unsigned min_large_size; /**< The minimum size of a CopyB node so that it is regarded as 'large'. */ static unsigned native_mode_bytes; /**< The size of the native mode in bytes. */ +static int allow_misalignments; /**< Whether backend can handle misaligned + loads and stores. */ typedef struct walk_env { struct obstack obst; /**< the obstack where data is allocated @@ -112,27 +113,17 @@ static ir_mode *get_ir_mode(unsigned mode_bytes) static void lower_small_copyb_node(ir_node *irn) { ir_graph *irg = get_irn_irg(irn); - unsigned mode_bytes = native_mode_bytes; - unsigned size; - unsigned offset; + ir_node *block = get_nodes_block(irn); + ir_type *tp = get_CopyB_type(irn); + ir_node *addr_src = get_CopyB_src(irn); + ir_node *addr_dst = get_CopyB_dst(irn); + ir_node *mem = get_CopyB_mem(irn); + ir_mode *addr_mode = get_irn_mode(addr_src); + unsigned mode_bytes = allow_misalignments ? native_mode_bytes : tp->align; + unsigned size = get_type_size_bytes(tp); + unsigned offset = 0; ir_mode *mode; - ir_mode *addr_mode; - ir_node *mem; - ir_node *addr_src; - ir_node *addr_dst; - ir_node *block; - ir_type *tp; - - addr_src = get_CopyB_src(irn); - addr_dst = get_CopyB_dst(irn); - mem = get_CopyB_mem(irn); - addr_mode = get_irn_mode(addr_src); - block = get_nodes_block(irn); - - tp = get_CopyB_type(irn); - size = get_type_size_bytes(tp); - - offset = 0; + while (offset < size) { mode = get_ir_mode(mode_bytes); for (; offset + mode_bytes <= size; offset += mode_bytes) { @@ -280,17 +271,18 @@ static void find_copyb_nodes(ir_node *irn, void *ctx) list_add_tail(&entry->list, &env->list); } -void lower_CopyB(ir_graph *irg, unsigned max_small_sz, unsigned min_large_sz) +void lower_CopyB(ir_graph *irg, unsigned max_small_sz, unsigned min_large_sz, + int allow_misaligns) { const backend_params *bparams = be_get_backend_param(); walk_env_t env; - entry_t *entry; assert(max_small_sz < min_large_sz && "CopyB size ranges must not overlap"); - max_small_size = max_small_sz; - min_large_size = min_large_sz; - native_mode_bytes = bparams->machine_size / 8; + max_small_size = max_small_sz; + min_large_size = min_large_sz; + native_mode_bytes = bparams->machine_size / 8; + allow_misalignments = allow_misaligns; obstack_init(&env.obst); INIT_LIST_HEAD(&env.list);