2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Lower small CopyB nodes into a series of Load/store
23 * @author Matthias Braun, Michael Beck
37 #include "iredges_t.h"
41 static unsigned max_size;
42 static unsigned native_mode_bytes;
44 static ir_mode *get_ir_mode(unsigned bytes)
47 case 1: return mode_Bu;
48 case 2: return mode_Hu;
49 case 4: return mode_Iu;
50 case 8: return mode_Lu;
51 case 16: return mode_LLu;
53 panic("unexpected mode size requested in copyb lowering");
58 * Walker: lower small CopyB nodes.
60 static void lower_copyb_nodes(ir_node *irn, void *ctx) {
61 ir_graph *irg = current_ir_graph;
72 ir_node *proj_M = NULL;
73 const ir_edge_t *edge;
79 tp = get_CopyB_type(irn);
80 if (get_type_state(tp) != layout_fixed)
83 size = get_type_size_bytes(tp);
87 foreach_out_edge(irn, edge) {
88 ir_node *node = get_edge_src_irn(edge);
89 long pn = get_Proj_proj(node);
91 /* we don't lower copybs with exception edges (yet) */
92 if(pn == pn_CopyB_X_except)
94 if(pn == pn_CopyB_M_regular) {
95 assert(proj_M == NULL);
100 panic("no projM on copyb");
103 addr_src = get_CopyB_src(irn);
104 addr_dst = get_CopyB_dst(irn);
105 mem = get_CopyB_mem(irn);
106 addr_mode = get_irn_mode(addr_src);
107 block = get_nodes_block(irn);
110 mode_bytes = native_mode_bytes;
111 while(offset < size) {
112 mode = get_ir_mode(mode_bytes);
113 for( ; offset + mode_bytes <= size; offset += mode_bytes) {
114 /* construct offset */
123 addr_const = new_r_Const_long(irg, block, mode_Iu, offset);
124 add = new_r_Add(irg, block, addr_src, addr_const, addr_mode);
126 load = new_r_Load(irg, block, mem, add, mode);
127 load_res = new_r_Proj(irg, block, load, mode, pn_Load_res);
128 load_mem = new_r_Proj(irg, block, load, mode_M, pn_Load_M);
130 addr_const = new_r_Const_long(irg, block, mode_Iu, offset);
131 add = new_r_Add(irg, block, addr_dst, addr_const, addr_mode);
133 store = new_r_Store(irg, block, mem, add, load_res);
134 store_mem = new_r_Proj(irg, block, store, mode_M, pn_Store_M);
142 exchange(proj_M, mem);
145 void lower_CopyB(ir_graph *irg, unsigned new_max_size,
146 unsigned new_native_mode_bytes)
148 max_size = new_max_size;
149 native_mode_bytes = new_native_mode_bytes;
153 irg_walk_graph(irg, NULL, lower_copyb_nodes, NULL);
155 edges_deactivate(irg);