3 * File name: ir/arch/archop.c
4 * Purpose: Architecture dependand IR operations
8 * Copyright: (c) 1998-2005 Universität Karlsruhe
9 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
20 #include "irgraph_t.h"
25 #include "firm_common_t.h"
27 #include "iropt_dbg.h"
30 /* when we need verifying */
32 # define IRN_VRFY_IRG(res, irg)
34 # define IRN_VRFY_IRG(res, irg) irn_vrfy_irg(res, irg)
37 /** current settings */
38 static arch_ops_info settings;
40 /** default settings */
41 static const arch_ops_info default_settings = {
46 /** The Min operation */
49 /** The Max operation */
52 ir_op *get_op_Min(void) { return op_Min; }
53 ir_op *get_op_Max(void) { return op_Max; }
56 * construct a Min: Min(a,b) = a < b ? a : b
59 new_rd_Min(dbg_info *db, ir_graph *irg, ir_node *block,
60 ir_node *op1, ir_node *op2, ir_mode *mode)
72 res = new_ir_node(db, irg, block, op_Min, mode, 2, in);
73 res = optimize_node(res);
74 IRN_VRFY_IRG(res, irg);
79 * construct a Max: Max(a,b) = a > b ? a : b
82 new_rd_Max(dbg_info *db, ir_graph *irg, ir_node *block,
83 ir_node *op1, ir_node *op2, ir_mode *mode)
95 res = new_ir_node(db, irg, block, op_Max, mode, 2, in);
96 res = optimize_node(res);
97 IRN_VRFY_IRG(res, irg);
102 new_r_Min(ir_graph *irg, ir_node *block,
103 ir_node *op1, ir_node *op2, ir_mode *mode) {
104 return new_rd_Min(NULL, irg, block, op1, op2, mode);
108 new_r_Max(ir_graph *irg, ir_node *block,
109 ir_node *op1, ir_node *op2, ir_mode *mode) {
110 return new_rd_Max(NULL, irg, block, op1, op2, mode);
114 new_d_Min(dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) {
115 return new_rd_Min(db, current_ir_graph, current_ir_graph->current_block,
120 new_d_Max(dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) {
121 return new_rd_Max(db, current_ir_graph, current_ir_graph->current_block,
126 new_Min(ir_node *op1, ir_node *op2, ir_mode *mode) {
127 return new_d_Min(NULL, op1, op2, mode);
131 new_Max(ir_node *op1, ir_node *op2, ir_mode *mode) {
132 return new_d_Max(NULL, op1, op2, mode);
138 * return the value of a Min
140 static tarval *computed_value_Min(ir_node *n)
142 ir_node *a = get_binop_left(n);
143 ir_node *b = get_binop_right(n);
145 tarval *ta = value_of(a);
146 tarval *tb = value_of(b);
148 if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
149 pn_Cmp res = tarval_cmp(ta, tb);
151 /* beware: there might be Unordered tarvals here, in that
152 * case let the backend decide, do NOT optimize */
153 if (res == pn_Cmp_Lt)
155 if (res == pn_Cmp_Gt || res == pn_Cmp_Eq)
162 * return the value of a Max
164 static tarval *computed_value_Max(ir_node *n)
166 ir_node *a = get_binop_left(n);
167 ir_node *b = get_binop_right(n);
169 tarval *ta = value_of(a);
170 tarval *tb = value_of(b);
172 if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
173 pn_Cmp res = tarval_cmp(ta, tb);
175 /* beware: there might be Unordered tarvals here, in that
176 * case let the backend decide, do NOT optimize */
177 if (res == pn_Cmp_Gt)
179 if (res == pn_Cmp_Lt || res == pn_Cmp_Eq)
186 * Returns an equivalent node for a Min/Max node.
187 * We do not allow Exceptions in our Min/Max, so there will be always
189 * The problem is Min(NaN, NaN) == NaN ???.
191 static ir_node *equivalent_node_MinMax(ir_node *n)
195 if (settings.minmax_handle_NaN == 0 && mode_is_float(get_irn_mode(n)))
198 a = get_binop_left(n);
199 b = get_binop_right(n);
202 DBG_OPT_ALGSIM0(n, a);
209 #define equivalent_node_Min equivalent_node_MinMax
210 #define equivalent_node_Max equivalent_node_MinMax
213 * Create Min and Mux from Mux nodes
215 ir_node *arch_transform_node_Mux(ir_node *n)
217 if (settings.enabled_ops & ARCH_OPS_MINMAX) {
218 ir_node *oldn = n, *cmp, *proj = get_Mux_sel(n);
221 if (get_irn_op(proj) != op_Proj)
224 cmp = get_Proj_pred(proj);
225 if (get_irn_op(cmp) == op_Cmp) {
226 ir_node *a = get_Cmp_left(cmp);
227 ir_node *b = get_Cmp_right(cmp);
228 ir_node *t = get_Mux_true(n);
229 ir_node *f = get_Mux_false(n);
231 proj_nr = get_Proj_proj(proj);
233 if (proj_nr == pn_Cmp_Lt || proj_nr == pn_Cmp_Le) {
234 if (a == t && b == f) {
235 /* a </<= b ? a : b ==> Min(a,b) */
236 n = new_rd_Min(get_irn_dbg_info(n),
242 DBG_OPT_ALGSIM1(oldn, cmp, proj, n);
245 else if (a == f && b == t) {
246 /* a </<= b ? b : a ==> Max(a,b) */
247 n = new_rd_Max(get_irn_dbg_info(n),
253 DBG_OPT_ALGSIM1(oldn, cmp, proj, n);
257 else if (proj_nr == pn_Cmp_Gt || proj_nr == pn_Cmp_Ge) {
258 if (a == t && b == f) {
259 /* a >/>= b ? a : b ==> Max(a,b) */
260 n = new_rd_Max(get_irn_dbg_info(n),
266 DBG_OPT_ALGSIM1(oldn, cmp, proj, n);
269 else if (a == f && b == t) {
270 /* a >/>= b ? b : a ==> Min(a,b) */
271 n = new_rd_Min(get_irn_dbg_info(n),
277 DBG_OPT_ALGSIM1(oldn, cmp, proj, n);
287 * verify a MinMax node
289 static int verify_node_MinMax(ir_node *n, ir_graph *irg) {
290 ir_mode *mymode = get_irn_mode(n);
291 ir_mode *op1mode = get_irn_mode(get_binop_left(n));
292 ir_mode *op2mode = get_irn_mode(get_binop_right(n));
295 /* MinMax: BB x numP x numP --> numP */
298 mode_is_numP(mymode),
305 * initialize the ops.
307 void firm_archops_init(const arch_ops_info *info)
310 info = &default_settings;
312 memcpy(&settings, info, sizeof(settings));
314 if (info->enabled_ops & ARCH_OPS_MINMAX) {
315 op_Min = new_ir_op(get_next_ir_opcode(), "Min", op_pin_state_floats, irop_flag_commutative, oparity_binary, 0, 0);
316 op_Min->computed_value = computed_value_Min;
317 op_Min->equivalent_node = equivalent_node_Min;
318 op_Min->verify_node = verify_node_MinMax;
320 op_Max = new_ir_op(get_next_ir_opcode(), "Max", op_pin_state_floats, irop_flag_commutative, oparity_binary, 0, 0);
321 op_Max->computed_value = computed_value_Max;
322 op_Max->equivalent_node = equivalent_node_Max;
323 op_Max->verify_node = verify_node_MinMax;