2 * Copyright (C) 1995-2011 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 floating point operations to function calls
23 * @author Sebastian Buchwald
30 #include "dbginfo_t.h"
36 #include "irnodeset.h"
39 #include "iropt_dbg.h"
41 #include "lower_softfloat.h"
47 /** The debug handle */
48 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
50 typedef void (*lower_softfloat_func)(ir_node *node);
52 static ir_type *binop_tp_d;
53 static ir_type *binop_tp_f;
54 static ir_type *cmp_tp_d;
55 static ir_type *cmp_tp_f;
56 static ir_type *unop_tp_d;
57 static ir_type *unop_tp_f;
58 static ir_type *unop_tp_d_f;
59 static ir_type *unop_tp_d_is;
60 static ir_type *unop_tp_d_iu;
61 static ir_type *unop_tp_d_ls;
62 static ir_type *unop_tp_d_lu;
63 static ir_type *unop_tp_f_d;
64 static ir_type *unop_tp_f_is;
65 static ir_type *unop_tp_f_iu;
66 static ir_type *unop_tp_f_ls;
67 static ir_type *unop_tp_f_lu;
68 static ir_type *unop_tp_is_d;
69 static ir_type *unop_tp_is_f;
70 static ir_type *unop_tp_iu_d;
71 static ir_type *unop_tp_iu_f;
72 static ir_type *unop_tp_ls_d;
73 static ir_type *unop_tp_ls_f;
74 static ir_type *unop_tp_lu_d;
75 static ir_type *unop_tp_lu_f;
77 /** A map from a method type to its lowered type. */
78 static pmap *lowered_type;
80 static ir_nodeset_t created_mux_nodes;
83 * @return The lowered (floating point) mode.
85 static ir_mode *get_lowered_mode(ir_mode *mode)
87 if (! mode_is_float(mode))
92 else if (mode == mode_D)
95 panic("Unsupported floating point type");
99 * Adapts the mode of the given node.
101 static void lower_mode(ir_node *n, void *env)
103 ir_op *op = get_irn_op(n);
104 lower_softfloat_func lower_func = (lower_softfloat_func) op->ops.generic;
105 ir_mode *mode = get_irn_mode(n);
109 if (lower_func != NULL) {
114 set_irn_mode(n, get_lowered_mode(mode));
118 * Wrapper for specific lower function.
120 static void lower_node(ir_node *n, void *env)
122 ir_op *op = get_irn_op(n);
123 lower_softfloat_func lower_func = (lower_softfloat_func) op->ops.generic;
127 if (lower_func != NULL)
132 * @return The type of the function replacing the given node.
134 static ir_type *get_softfloat_type(const ir_node *n)
136 unsigned opcode = get_irn_opcode(n);
137 ir_mode *mode = get_irn_mode(n);
138 ir_node *operand = get_irn_n(n, 0);
139 ir_mode *operand_mode = get_irn_mode(operand);
143 mode = get_Div_resmode(n);
144 operand_mode = get_irn_mode(get_Div_left(n));
149 if (operand_mode == mode_F)
151 else if (operand_mode == mode_D)
155 if (operand_mode == mode_F)
157 else if (operand_mode == mode_D)
161 if (operand_mode == mode_D) {
164 else if (mode == mode_Is || mode == mode_Hs || mode == mode_Bs)
166 else if (mode == mode_Iu || mode == mode_Hu || mode == mode_Bu)
168 else if (mode == mode_Ls)
170 else if (mode == mode_Lu)
173 else if (operand_mode == mode_F) {
176 else if (mode == mode_Is || mode == mode_Hs || mode == mode_Bs)
178 else if (mode == mode_Iu || mode == mode_Hu || mode == mode_Bu)
180 else if (mode == mode_Ls)
182 else if (mode == mode_Lu)
185 else if (operand_mode == mode_Is || operand_mode == mode_Hs || operand_mode == mode_Bs) {
188 else if (mode == mode_F)
191 else if (operand_mode == mode_Iu || operand_mode == mode_Hu || operand_mode == mode_Bu) {
194 else if (mode == mode_F)
197 else if (operand_mode == mode_Ls) {
200 else if (mode == mode_F)
203 else if (operand_mode == mode_Lu) {
206 else if (mode == mode_F)
211 if (operand_mode == mode_F)
213 else if (operand_mode == mode_D)
219 assert(0 && "Could not determine a suitable type");
225 * @return A SymConst representing the function that replaces the given node.
227 static ir_node *create_softfloat_symconst(const ir_node *n, const char *name)
230 const char *first_param = "";
231 const char *second_param = "";
232 const char *result = "";
237 unsigned float_types = 0;
238 unsigned double_types = 0;
239 ir_graph *irg = get_irn_irg(n);
240 ir_type *method = get_softfloat_type(n);
242 n_params = get_method_n_params(method);
244 /* Parameter types. */
248 ir_type *param_type = get_method_param_type(method, 1);
249 ir_mode *mode = get_type_mode(param_type);
251 if (mode == mode_F) {
255 else if (mode == mode_D) {
259 else if (mode == mode_Iu || mode == mode_Is)
261 else if (mode == mode_Lu || mode == mode_Ls)
267 ir_type *param_type = get_method_param_type(method, 0);
268 ir_mode *mode = get_type_mode(param_type);
270 if (mode == mode_F) {
271 first_param = float_types > 0 ? "" : "sf";
274 else if (mode == mode_D) {
275 first_param = double_types > 0 ? "" : "df";
278 else if (mode == mode_Iu || mode == mode_Is)
280 else if (mode == mode_Lu || mode == mode_Ls)
293 mode = get_Div_resmode(n);
295 mode = get_irn_mode(n);
297 if (mode == mode_F) {
298 result = float_types > 0 ? "" : "sf";
301 else if (mode == mode_D) {
302 result = double_types > 0 ? "" : "df";
305 else if (mode == mode_Iu || mode == mode_Hu || mode == mode_Bu
306 || mode == mode_Is || mode == mode_Hs || mode == mode_Bs)
308 else if (mode == mode_Lu || mode == mode_Ls)
312 assert(float_types <= 3);
313 assert(double_types <= 3);
315 if (float_types + double_types > 1)
316 snprintf(buf, sizeof(buf), "__%s%s%s%s%u", name, first_param, second_param, result, float_types + double_types);
318 snprintf(buf, sizeof(buf), "__%s%s%s%s", name, first_param, second_param, result);
320 id = new_id_from_str(buf);
321 ent = new_entity(get_glob_type(), id, method);
323 set_entity_ld_ident(ent, get_entity_ident(ent));
326 return new_r_SymConst(irg, mode_P_code, sym, symconst_addr_ent);
330 * Transforms an Add into the appropriate soft float function.
332 static void lower_Add(ir_node *n)
335 ir_node *block = get_nodes_block(n);
336 ir_node *call_result = NULL;
337 dbg_info *dbgi = get_irn_dbg_info(n);
338 ir_graph *irg = get_irn_irg(n);
339 ir_node *left = get_Add_left(n);
340 ir_node *right = get_Add_right(n);
341 ir_mode *mode = get_irn_mode(n);
343 if (! mode_is_float(mode))
346 symconst = create_softfloat_symconst(n, "add");
349 ir_node *call_results;
350 ir_node *in[2] = {left, right};
351 ir_node *nomem = get_irg_no_mem(irg);
352 ir_type *type = get_softfloat_type(n);
353 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
355 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
356 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
357 call_result = new_r_Proj(call_results, res_mode, 0);
359 exchange(n, call_result);
363 * @return The lowered (floating point) type.
365 static ir_type *lower_type(ir_type *tp)
367 ir_mode *mode = get_type_mode(tp);
368 ir_mode *lowered_mode = get_lowered_mode(mode);
370 return get_type_for_mode(lowered_mode);
374 * @return The lowered method type.
376 static ir_type *lower_method_type(ir_type *mtp)
383 res = (ir_type*)pmap_get(lowered_type, mtp);
387 n_param = get_method_n_params(mtp);
388 n_res = get_method_n_ress(mtp);
390 res = new_type_method(n_param, n_res);
392 /* set param types and result types */
393 for (i = 0; i < n_param; ++i) {
394 ir_type *ptp = get_method_param_type(mtp, i);
395 ir_mode *pmode = get_type_mode(ptp);
397 if (pmode != NULL && mode_is_float(pmode)) {
398 ptp = lower_type(ptp);
401 set_method_param_type(res, i, ptp);
403 for (i = 0; i < n_res; ++i) {
404 ir_type *rtp = get_method_res_type(mtp, i);
405 ir_mode *rmode = get_type_mode(rtp);
407 if (rmode != NULL && mode_is_float(rmode)) {
408 rtp = lower_type(rtp);
411 set_method_res_type(res, i, rtp);
414 set_method_variadicity(res, get_method_variadicity(mtp));
415 set_method_calling_convention(res, get_method_calling_convention(mtp));
416 set_method_additional_properties(res, get_method_additional_properties(mtp));
418 set_lowered_type(mtp, res);
420 pmap_insert(lowered_type, mtp, res);
425 * Adapts the method type of a Call.
427 static void lower_Call(ir_node *node)
429 ir_type *tp = get_Call_type(node);
432 bool need_lower = false;
436 n_params = get_method_n_params(tp);
438 for (p = 0; p < n_params; ++p) {
439 ir_type *ptp = get_method_param_type(tp, p);
440 ir_mode *pmode = get_type_mode(ptp);
445 if (mode_is_float(pmode)) {
451 n_res = get_method_n_ress(tp);
453 for (i = 0; i < n_res; ++i) {
454 ir_type *rtp = get_method_res_type(tp, i);
455 ir_mode *rmode = get_type_mode(rtp);
460 if (mode_is_float(rmode)) {
469 tp = lower_method_type(tp);
470 set_Call_type(node, tp);
474 * Transforms a Cmp into the appropriate soft float function.
476 static void lower_Cmp(ir_node *n)
478 ir_node *symconst = NULL;
479 ir_node *block = get_nodes_block(n);
480 ir_node *call_result = NULL;
481 dbg_info *dbgi = get_irn_dbg_info(n);
482 ir_graph *irg = get_irn_irg(n);
483 ir_node *left = get_Cmp_left(n);
484 ir_relation relation = get_Cmp_relation(n);
485 ir_mode *op_mode = get_irn_mode(left);
486 ir_node *right = get_Cmp_right(n);
487 ir_node *symconst2 = NULL;
488 ir_node *zero = new_rd_Const(dbgi, irg, get_mode_null(mode_Is));
490 if (! mode_is_float(op_mode))
494 case ir_relation_false:
497 case ir_relation_equal:
498 symconst = create_softfloat_symconst(n, "eq");
500 case ir_relation_less:
501 symconst = create_softfloat_symconst(n, "lt");
503 case ir_relation_greater:
504 symconst = create_softfloat_symconst(n, "gt");
506 case ir_relation_unordered:
507 symconst = create_softfloat_symconst(n, "unord");
508 relation = ir_relation_less_greater;
510 case ir_relation_less_equal:
511 symconst = create_softfloat_symconst(n, "le");
513 case ir_relation_greater_equal:
514 symconst = create_softfloat_symconst(n, "ge");
516 case ir_relation_less_greater:
517 symconst = create_softfloat_symconst(n, "unord");
518 symconst2 = create_softfloat_symconst(n, "ne");
520 case ir_relation_less_equal_greater:
521 symconst = create_softfloat_symconst(n, "unord");
522 relation = ir_relation_equal;
524 case ir_relation_unordered_equal:
525 symconst = create_softfloat_symconst(n, "unord");
526 relation = ir_relation_less_greater;
527 symconst2 = create_softfloat_symconst(n, "ne");
529 case ir_relation_unordered_less:
530 symconst = create_softfloat_symconst(n, "ge");
531 relation = ir_relation_less;
533 case ir_relation_unordered_less_equal:
534 symconst = create_softfloat_symconst(n, "gt");
535 relation = ir_relation_less_equal;
537 case ir_relation_unordered_greater:
538 symconst = create_softfloat_symconst(n, "le");
539 relation = ir_relation_greater;
541 case ir_relation_unordered_greater_equal:
542 symconst = create_softfloat_symconst(n, "lt");
543 relation = ir_relation_greater_equal;
545 case ir_relation_unordered_less_greater:
546 symconst = create_softfloat_symconst(n, "eq");
547 relation = ir_relation_less_greater;
549 case ir_relation_true:
554 if (call_result == NULL) {
556 ir_node *call_results;
557 ir_node *in[2] = {left, right};
558 ir_node *nomem = get_irg_no_mem(irg);
559 ir_type *type = get_softfloat_type(n);
561 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
562 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
563 call_result = new_r_Proj(call_results, mode_Is, 0);
566 ir_node *cmp = new_r_Cmp(block, call_result, zero, relation);
568 /* We need two calls into the softfloat library */
569 if (symconst2 != NULL) {
571 ir_node *call_results;
573 arch_allow_ifconv_func allow_ifconv = be_get_backend_param()->allow_ifconv;
574 ir_node *in[2] = {left, right};
575 ir_node *nomem = get_irg_no_mem(irg);
576 ir_type *type = get_softfloat_type(n);
578 call = new_rd_Call(dbgi, block, nomem, symconst2, 2, in, type);
579 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
580 call_result = new_r_Proj(call_results, mode_Is, 0);
581 relation = get_Cmp_relation(n);
583 mux = new_rd_Mux(dbgi, block, cmp, call_result, zero, mode_Is);
585 if (! allow_ifconv(cmp, call_result, zero))
586 ir_nodeset_insert(&created_mux_nodes, mux);
588 cmp = new_r_Cmp(block, mux, zero, relation);
594 static const tarval_mode_info hex_output = {
601 * Adapts floating point constants.
603 static void lower_Const(ir_node *n)
605 ir_mode *lowered_mode;
606 ir_mode *mode = get_irn_mode(n);
607 ir_tarval *tv = get_Const_tarval(n);
611 if (! mode_is_float(mode))
614 lowered_mode = get_lowered_mode(mode);
615 set_irn_mode(n, lowered_mode);
617 set_tarval_mode_output_option(mode, &hex_output);
618 tarval_snprintf(buf, 100, get_Const_tarval(n));
621 tv = new_tarval_from_str(buf, len, lowered_mode);
622 set_Const_tarval(n, tv);
626 * Transforms a Conv into the appropriate soft float function.
628 static void lower_Conv(ir_node *n)
631 ir_node *block = get_nodes_block(n);
632 ir_node *call_result = NULL;
633 dbg_info *dbgi = get_irn_dbg_info(n);
634 ir_graph *irg = get_irn_irg(n);
635 ir_node *op = get_Conv_op(n);
636 ir_mode *mode = get_irn_mode(n);
637 ir_mode *op_mode = get_irn_mode(op);
639 if (! mode_is_float(mode) && ! mode_is_float(op_mode))
642 /* Remove unnecessary Convs. */
643 if (op_mode == mode) {
647 else if (op_mode == mode_Hs || op_mode == mode_Bs) {
649 op = new_rd_Conv(dbgi, block, op, op_mode);
651 else if (op_mode == mode_Hu || op_mode == mode_Bu) {
653 op = new_rd_Conv(dbgi, block, op, op_mode);
656 if (mode_is_float(op_mode) && mode_is_float(mode)) {
657 if (get_mode_size_bits(op_mode) > get_mode_size_bits(mode))
658 symconst = create_softfloat_symconst(n, "trunc");
660 symconst = create_softfloat_symconst(n, "extend");
662 else if (mode_is_float(op_mode)) {
663 if (mode_is_signed(mode))
664 symconst = create_softfloat_symconst(n, "fix");
666 symconst = create_softfloat_symconst(n, "fixuns");
669 if (mode_is_signed(op_mode))
670 symconst = create_softfloat_symconst(n, "float");
672 symconst = create_softfloat_symconst(n, "floatun");
676 ir_node *call_results;
677 ir_node *in[1] = {op};
678 ir_node *nomem = get_irg_no_mem(irg);
679 ir_type *type = get_softfloat_type(n);
680 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
682 call = new_rd_Call(dbgi, block, nomem, symconst, 1, in, type);
683 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
684 call_result = new_r_Proj(call_results, res_mode, 0);
686 /* Check whether we need a Conv for the result. */
687 if (res_mode != mode)
688 call_result = new_rd_Conv(dbgi, block, call_result, mode);
690 exchange(n, call_result);
694 * Transforms a Div into the appropriate soft float function.
696 static void lower_Div(ir_node *n)
699 ir_node *block = get_nodes_block(n);
700 ir_node *call_result = NULL;
701 dbg_info *dbgi = get_irn_dbg_info(n);
702 ir_graph *irg = get_irn_irg(n);
703 ir_node *left = get_Div_left(n);
704 ir_mode *mode = get_Div_resmode(n);
705 ir_node *right = get_Div_right(n);
706 const ir_edge_t *edge;
707 const ir_edge_t *next;
709 if (! mode_is_float(mode))
712 symconst = create_softfloat_symconst(n, "div");
715 ir_node *call_results;
716 ir_node *in[2] = {left, right};
717 ir_node *nomem = get_irg_no_mem(irg);
718 ir_type *type = get_softfloat_type(n);
719 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
721 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
722 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
723 call_result = new_r_Proj(call_results, res_mode, 0);
725 set_irn_pinned(call, get_irn_pinned(n));
727 foreach_out_edge_safe(n, edge, next) {
728 ir_node *proj = get_edge_src_irn(edge);
732 switch (get_Proj_proj(proj)) {
734 set_Proj_pred(proj, call);
735 set_Proj_proj(proj, pn_Call_M);
737 case pn_Div_X_regular:
738 set_Proj_pred(proj, call);
739 set_Proj_proj(proj, pn_Call_X_regular);
741 case pn_Div_X_except:
742 set_Proj_pred(proj, call);
743 set_Proj_proj(proj, pn_Call_X_except);
746 exchange(proj, call_result);
749 assert(0 && "unexpected Proj number");
756 * Adapts the resmode of a Div.
758 static void lower_Div_mode(ir_node *n)
760 ir_mode *res_mode = get_Div_resmode(n);
761 ir_mode *lowered_res_mode = get_lowered_mode(res_mode);
762 ir_mode *mode = get_irn_mode(n);
763 ir_mode *lowered_mode = get_lowered_mode(mode);
765 set_irn_mode(n, lowered_mode);
766 set_Div_resmode(n, lowered_res_mode);
770 * Adapts the ls_mode of a Load.
772 static void lower_Load(ir_node *n)
774 ir_mode *ls_mode = get_Load_mode(n);
775 ir_mode *lowered_ls_mode = get_lowered_mode(ls_mode);
776 ir_mode *mode = get_irn_mode(n);
777 ir_mode *lowered_mode = get_lowered_mode(mode);
779 set_irn_mode(n, lowered_mode);
780 set_Load_mode(n, lowered_ls_mode);
784 * Transforms a Minus into the appropriate soft float function.
786 static void lower_Minus(ir_node *n)
789 ir_node *block = get_nodes_block(n);
790 ir_node *call_result = NULL;
791 dbg_info *dbgi = get_irn_dbg_info(n);
792 ir_graph *irg = get_irn_irg(n);
793 ir_mode *mode = get_irn_mode(n);
794 ir_node *op = get_Minus_op(n);
796 if (! mode_is_float(mode))
799 symconst = create_softfloat_symconst(n, "neg");
802 ir_node *call_results;
803 ir_node *in[1] = {op};
804 ir_node *nomem = get_irg_no_mem(irg);
805 ir_type *type = get_softfloat_type(n);
806 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
808 call = new_rd_Call(dbgi, block, nomem, symconst, 1, in, type);
809 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
810 call_result = new_r_Proj(call_results, res_mode, 0);
812 exchange(n, call_result);
816 * Transforms a Mul into the appropriate soft float function.
818 static void lower_Mul(ir_node *n)
821 ir_node *block = get_nodes_block(n);
822 ir_node *call_result = NULL;
823 dbg_info *dbgi = get_irn_dbg_info(n);
824 ir_graph *irg = get_irn_irg(n);
825 ir_node *left = get_Mul_left(n);
826 ir_mode *mode = get_irn_mode(n);
827 ir_node *right = get_Mul_right(n);
829 if (! mode_is_float(mode))
832 symconst = create_softfloat_symconst(n, "mul");
835 ir_node *call_results;
836 ir_node *in[2] = {left, right};
837 ir_node *nomem = get_irg_no_mem(irg);
838 ir_type *type = get_softfloat_type(n);
839 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
841 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
842 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
843 call_result = new_r_Proj(call_results, res_mode, 0);
845 exchange(n, call_result);
849 * Transforms a Sub into the appropriate soft float function.
851 static void lower_Sub(ir_node *n)
854 ir_node *block = get_nodes_block(n);
855 ir_node *call_result = NULL;
856 dbg_info *dbgi = get_irn_dbg_info(n);
857 ir_graph *irg = get_irn_irg(n);
858 ir_node *left = get_Sub_left(n);
859 ir_mode *mode = get_irn_mode(n);
860 ir_node *right = get_Sub_right(n);
862 if (! mode_is_float(mode))
865 symconst = create_softfloat_symconst(n, "sub");
868 ir_node *call_results;
869 ir_node *in[2] = {left, right};
870 ir_node *nomem = get_irg_no_mem(irg);
871 ir_type *type = get_softfloat_type(n);
872 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
874 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
875 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
876 call_result = new_r_Proj(call_results, res_mode, 0);
878 exchange(n, call_result);
882 * Enter a lowering function into an ir_op.
884 static void ir_register_softloat_lower_function(ir_op *op, lower_softfloat_func func)
886 op->ops.generic = (op_func)func;
890 * Initializes softfloat lowering.
892 static void ir_prepare_softfloat_lowering(void)
894 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
897 lowered_type = pmap_create();
900 binop_tp_d = new_type_method(2, 1);
901 set_method_param_type(binop_tp_d, 0, get_type_for_mode(mode_D));
902 set_method_param_type(binop_tp_d, 1, get_type_for_mode(mode_D));
903 set_method_res_type(binop_tp_d, 0, get_type_for_mode(mode_D));
907 binop_tp_f = new_type_method(2, 1);
908 set_method_param_type(binop_tp_f, 0, get_type_for_mode(mode_F));
909 set_method_param_type(binop_tp_f, 1, get_type_for_mode(mode_F));
910 set_method_res_type(binop_tp_f, 0, get_type_for_mode(mode_F));
914 cmp_tp_d = new_type_method(2, 1);
915 set_method_param_type(cmp_tp_d, 0, get_type_for_mode(mode_D));
916 set_method_param_type(cmp_tp_d, 1, get_type_for_mode(mode_D));
917 set_method_res_type(cmp_tp_d, 0, get_type_for_mode(mode_Is));
921 cmp_tp_f = new_type_method(2, 1);
922 set_method_param_type(cmp_tp_f, 0, get_type_for_mode(mode_F));
923 set_method_param_type(cmp_tp_f, 1, get_type_for_mode(mode_F));
924 set_method_res_type(cmp_tp_f, 0, get_type_for_mode(mode_Is));
928 unop_tp_d = new_type_method(1, 1);
929 set_method_param_type(unop_tp_d, 0, get_type_for_mode(mode_D));
930 set_method_res_type(unop_tp_d, 0, get_type_for_mode(mode_D));
934 unop_tp_f = new_type_method(1, 1);
935 set_method_param_type(unop_tp_f, 0, get_type_for_mode(mode_F));
936 set_method_res_type(unop_tp_f, 0, get_type_for_mode(mode_F));
940 unop_tp_d_f = new_type_method(1, 1);
941 set_method_param_type(unop_tp_d_f, 0, get_type_for_mode(mode_D));
942 set_method_res_type(unop_tp_d_f, 0, get_type_for_mode(mode_F));
945 if (! unop_tp_d_is) {
946 unop_tp_d_is = new_type_method(1, 1);
947 set_method_param_type(unop_tp_d_is, 0, get_type_for_mode(mode_D));
948 set_method_res_type(unop_tp_d_is, 0, get_type_for_mode(mode_Is));
951 if (! unop_tp_d_iu) {
952 unop_tp_d_iu = new_type_method(1, 1);
953 set_method_param_type(unop_tp_d_iu, 0, get_type_for_mode(mode_D));
954 set_method_res_type(unop_tp_d_iu, 0, get_type_for_mode(mode_Iu));
957 if (! unop_tp_d_ls) {
958 unop_tp_d_ls = new_type_method(1, 1);
959 set_method_param_type(unop_tp_d_ls, 0, get_type_for_mode(mode_D));
960 set_method_res_type(unop_tp_d_ls, 0, get_type_for_mode(mode_Ls));
963 if (! unop_tp_d_lu) {
964 unop_tp_d_lu = new_type_method(1, 1);
965 set_method_param_type(unop_tp_d_lu, 0, get_type_for_mode(mode_D));
966 set_method_res_type(unop_tp_d_lu, 0, get_type_for_mode(mode_Lu));
970 unop_tp_f_d = new_type_method(1, 1);
971 set_method_param_type(unop_tp_f_d, 0, get_type_for_mode(mode_F));
972 set_method_res_type(unop_tp_f_d, 0, get_type_for_mode(mode_D));
975 if (! unop_tp_f_is) {
976 unop_tp_f_is = new_type_method(1, 1);
977 set_method_param_type(unop_tp_f_is, 0, get_type_for_mode(mode_F));
978 set_method_res_type(unop_tp_f_is, 0, get_type_for_mode(mode_Is));
981 if (! unop_tp_f_iu) {
982 unop_tp_f_iu = new_type_method(1, 1);
983 set_method_param_type(unop_tp_f_iu, 0, get_type_for_mode(mode_F));
984 set_method_res_type(unop_tp_f_iu, 0, get_type_for_mode(mode_Iu));
987 if (! unop_tp_f_ls) {
988 unop_tp_f_ls = new_type_method(1, 1);
989 set_method_param_type(unop_tp_f_ls, 0, get_type_for_mode(mode_F));
990 set_method_res_type(unop_tp_f_ls, 0, get_type_for_mode(mode_Ls));
993 if (! unop_tp_f_lu) {
994 unop_tp_f_lu = new_type_method(1, 1);
995 set_method_param_type(unop_tp_f_lu, 0, get_type_for_mode(mode_F));
996 set_method_res_type(unop_tp_f_lu, 0, get_type_for_mode(mode_Lu));
999 if (! unop_tp_is_d) {
1000 unop_tp_is_d = new_type_method(1, 1);
1001 set_method_param_type(unop_tp_is_d, 0, get_type_for_mode(mode_Is));
1002 set_method_res_type(unop_tp_is_d, 0, get_type_for_mode(mode_D));
1005 if (! unop_tp_is_f) {
1006 unop_tp_is_f = new_type_method(1, 1);
1007 set_method_param_type(unop_tp_is_f, 0, get_type_for_mode(mode_Is));
1008 set_method_res_type(unop_tp_is_f, 0, get_type_for_mode(mode_F));
1011 if (! unop_tp_iu_d) {
1012 unop_tp_iu_d = new_type_method(1, 1);
1013 set_method_param_type(unop_tp_iu_d, 0, get_type_for_mode(mode_Iu));
1014 set_method_res_type(unop_tp_iu_d, 0, get_type_for_mode(mode_D));
1017 if (! unop_tp_iu_f) {
1018 unop_tp_iu_f = new_type_method(1, 1);
1019 set_method_param_type(unop_tp_iu_f, 0, get_type_for_mode(mode_Iu));
1020 set_method_res_type(unop_tp_iu_f, 0, get_type_for_mode(mode_F));
1023 if (! unop_tp_ls_d) {
1024 unop_tp_ls_d = new_type_method(1, 1);
1025 set_method_param_type(unop_tp_ls_d, 0, get_type_for_mode(mode_Ls));
1026 set_method_res_type(unop_tp_ls_d, 0, get_type_for_mode(mode_D));
1029 if (! unop_tp_ls_f) {
1030 unop_tp_ls_f = new_type_method(1, 1);
1031 set_method_param_type(unop_tp_ls_f, 0, get_type_for_mode(mode_Ls));
1032 set_method_res_type(unop_tp_ls_f, 0, get_type_for_mode(mode_F));
1035 if (! unop_tp_lu_d) {
1036 unop_tp_lu_d = new_type_method(1, 1);
1037 set_method_param_type(unop_tp_lu_d, 0, get_type_for_mode(mode_Lu));
1038 set_method_res_type(unop_tp_lu_d, 0, get_type_for_mode(mode_D));
1041 if (! unop_tp_lu_f) {
1042 unop_tp_lu_f = new_type_method(1, 1);
1043 set_method_param_type(unop_tp_lu_f, 0, get_type_for_mode(mode_Lu));
1044 set_method_res_type(unop_tp_lu_f, 0, get_type_for_mode(mode_F));
1049 * Callback to lower only the Mux nodes we created.
1051 static int lower_mux_cb(ir_node *mux)
1053 return ir_nodeset_contains(&created_mux_nodes, mux);
1056 void lower_floating_point(void)
1059 size_t n_irgs = get_irp_n_irgs();
1061 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
1063 ir_prepare_softfloat_lowering();
1065 clear_irp_opcodes_generic_func();
1066 ir_register_softloat_lower_function(op_Add, lower_Add);
1067 ir_register_softloat_lower_function(op_Cmp, lower_Cmp);
1068 ir_register_softloat_lower_function(op_Conv, lower_Conv);
1069 ir_register_softloat_lower_function(op_Div, lower_Div);
1070 ir_register_softloat_lower_function(op_Minus, lower_Minus);
1071 ir_register_softloat_lower_function(op_Mul, lower_Mul);
1072 ir_register_softloat_lower_function(op_Sub, lower_Sub);
1074 for (i = 0; i < n_irgs; ++i) {
1075 ir_graph *irg = get_irp_irg(i);
1077 ir_nodeset_init(&created_mux_nodes);
1081 irg_walk_graph(irg, NULL, lower_node, NULL);
1083 if (ir_nodeset_size(&created_mux_nodes) > 0)
1084 lower_mux(irg, lower_mux_cb);
1086 ir_nodeset_destroy(&created_mux_nodes);
1089 clear_irp_opcodes_generic_func();
1090 ir_register_softloat_lower_function(op_Call, lower_Call);
1091 ir_register_softloat_lower_function(op_Const, lower_Const);
1092 ir_register_softloat_lower_function(op_Div, lower_Div_mode);
1093 ir_register_softloat_lower_function(op_Load, lower_Load);
1095 for (i = 0; i < n_irgs; ++i) {
1096 ir_graph *irg = get_irp_irg(i);
1097 ir_entity *ent = get_irg_entity(irg);
1098 ir_type *mtp = get_entity_type(ent);
1099 ir_type *lowered_mtp = lower_method_type(mtp);
1101 if (lowered_mtp != mtp)
1102 set_entity_type(ent, lowered_mtp);
1104 irg_walk_graph(irg, NULL, lower_mode, NULL);