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"
40 #include "iroptimize.h"
42 #include "lower_softfloat.h"
48 /** The debug handle */
49 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
51 typedef void (*lower_softfloat_func)(ir_node *node);
53 static ir_type *binop_tp_d;
54 static ir_type *binop_tp_f;
55 static ir_type *cmp_tp_d;
56 static ir_type *cmp_tp_f;
57 static ir_type *unop_tp_d;
58 static ir_type *unop_tp_f;
59 static ir_type *unop_tp_d_f;
60 static ir_type *unop_tp_d_is;
61 static ir_type *unop_tp_d_iu;
62 static ir_type *unop_tp_d_ls;
63 static ir_type *unop_tp_d_lu;
64 static ir_type *unop_tp_f_d;
65 static ir_type *unop_tp_f_is;
66 static ir_type *unop_tp_f_iu;
67 static ir_type *unop_tp_f_ls;
68 static ir_type *unop_tp_f_lu;
69 static ir_type *unop_tp_is_d;
70 static ir_type *unop_tp_is_f;
71 static ir_type *unop_tp_iu_d;
72 static ir_type *unop_tp_iu_f;
73 static ir_type *unop_tp_ls_d;
74 static ir_type *unop_tp_ls_f;
75 static ir_type *unop_tp_lu_d;
76 static ir_type *unop_tp_lu_f;
78 /** A map from a method type to its lowered type. */
79 static pmap *lowered_type;
81 static ir_nodeset_t created_mux_nodes;
84 * @return The lowered (floating point) mode.
86 static ir_mode *get_lowered_mode(ir_mode *mode)
88 if (! mode_is_float(mode))
93 else if (mode == mode_D)
96 panic("Unsupported floating point type");
100 * Adapts the mode of the given node.
102 static void lower_mode(ir_node *n, void *env)
104 ir_op *op = get_irn_op(n);
105 lower_softfloat_func lower_func = (lower_softfloat_func) op->ops.generic;
106 ir_mode *mode = get_irn_mode(n);
110 if (lower_func != NULL) {
115 set_irn_mode(n, get_lowered_mode(mode));
119 * Wrapper for specific lower function.
121 static void lower_node(ir_node *n, void *env)
123 ir_op *op = get_irn_op(n);
124 lower_softfloat_func lower_func = (lower_softfloat_func) op->ops.generic;
128 if (lower_func != NULL)
133 * @return The type of the function replacing the given node.
135 static ir_type *get_softfloat_type(const ir_node *n)
137 unsigned opcode = get_irn_opcode(n);
138 ir_mode *mode = get_irn_mode(n);
139 ir_node *operand = get_irn_n(n, 0);
140 ir_mode *operand_mode = get_irn_mode(operand);
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 = create_compilerlib_entity(id, method);
324 return new_r_SymConst(irg, mode_P_code, sym, symconst_addr_ent);
328 * Transforms an Add into the appropriate soft float function.
330 static void lower_Add(ir_node *n)
333 ir_node *block = get_nodes_block(n);
334 ir_node *call_result = NULL;
335 dbg_info *dbgi = get_irn_dbg_info(n);
336 ir_graph *irg = get_irn_irg(n);
337 ir_node *left = get_Add_left(n);
338 ir_node *right = get_Add_right(n);
339 ir_mode *mode = get_irn_mode(n);
341 if (! mode_is_float(mode))
344 symconst = create_softfloat_symconst(n, "add");
347 ir_node *call_results;
348 ir_node *in[2] = {left, right};
349 ir_node *nomem = get_irg_no_mem(irg);
350 ir_type *type = get_softfloat_type(n);
351 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
353 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
354 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
355 call_result = new_r_Proj(call_results, res_mode, 0);
357 exchange(n, call_result);
361 * @return The lowered (floating point) type.
363 static ir_type *lower_type(ir_type *tp)
365 ir_mode *mode = get_type_mode(tp);
366 ir_mode *lowered_mode = get_lowered_mode(mode);
368 return get_type_for_mode(lowered_mode);
372 * @return The lowered method type.
374 static ir_type *lower_method_type(ir_type *mtp)
381 res = pmap_get(ir_type, lowered_type, mtp);
385 n_param = get_method_n_params(mtp);
386 n_res = get_method_n_ress(mtp);
388 res = new_type_method(n_param, n_res);
390 /* set param types and result types */
391 for (i = 0; i < n_param; ++i) {
392 ir_type *ptp = get_method_param_type(mtp, i);
393 ir_mode *pmode = get_type_mode(ptp);
395 if (pmode != NULL && mode_is_float(pmode)) {
396 ptp = lower_type(ptp);
399 set_method_param_type(res, i, ptp);
401 for (i = 0; i < n_res; ++i) {
402 ir_type *rtp = get_method_res_type(mtp, i);
403 ir_mode *rmode = get_type_mode(rtp);
405 if (rmode != NULL && mode_is_float(rmode)) {
406 rtp = lower_type(rtp);
409 set_method_res_type(res, i, rtp);
412 set_method_variadicity(res, get_method_variadicity(mtp));
413 set_method_calling_convention(res, get_method_calling_convention(mtp));
414 set_method_additional_properties(res, get_method_additional_properties(mtp));
416 set_higher_type(res, mtp);
418 pmap_insert(lowered_type, mtp, res);
423 * Adapts the method type of a Call.
425 static void lower_Call(ir_node *node)
427 ir_type *tp = get_Call_type(node);
430 bool need_lower = false;
434 n_params = get_method_n_params(tp);
436 for (p = 0; p < n_params; ++p) {
437 ir_type *ptp = get_method_param_type(tp, p);
438 ir_mode *pmode = get_type_mode(ptp);
443 if (mode_is_float(pmode)) {
449 n_res = get_method_n_ress(tp);
451 for (i = 0; i < n_res; ++i) {
452 ir_type *rtp = get_method_res_type(tp, i);
453 ir_mode *rmode = get_type_mode(rtp);
458 if (mode_is_float(rmode)) {
467 tp = lower_method_type(tp);
468 set_Call_type(node, tp);
472 * Transforms a Cmp into the appropriate soft float function.
474 static void lower_Cmp(ir_node *n)
476 ir_node *symconst = NULL;
477 ir_node *block = get_nodes_block(n);
478 ir_node *call_result = NULL;
479 dbg_info *dbgi = get_irn_dbg_info(n);
480 ir_graph *irg = get_irn_irg(n);
481 ir_node *left = get_Cmp_left(n);
482 ir_relation relation = get_Cmp_relation(n);
483 ir_mode *op_mode = get_irn_mode(left);
484 ir_node *right = get_Cmp_right(n);
485 ir_node *symconst2 = NULL;
486 ir_node *zero = new_rd_Const(dbgi, irg, get_mode_null(mode_Is));
488 if (! mode_is_float(op_mode))
492 case ir_relation_false:
495 case ir_relation_equal:
496 symconst = create_softfloat_symconst(n, "eq");
498 case ir_relation_less:
499 symconst = create_softfloat_symconst(n, "lt");
501 case ir_relation_greater:
502 symconst = create_softfloat_symconst(n, "gt");
504 case ir_relation_unordered:
505 symconst = create_softfloat_symconst(n, "unord");
506 relation = ir_relation_less_greater;
508 case ir_relation_less_equal:
509 symconst = create_softfloat_symconst(n, "le");
511 case ir_relation_greater_equal:
512 symconst = create_softfloat_symconst(n, "ge");
514 case ir_relation_less_greater:
515 symconst = create_softfloat_symconst(n, "unord");
516 symconst2 = create_softfloat_symconst(n, "ne");
518 case ir_relation_less_equal_greater:
519 symconst = create_softfloat_symconst(n, "unord");
520 relation = ir_relation_equal;
522 case ir_relation_unordered_equal:
523 symconst = create_softfloat_symconst(n, "unord");
524 relation = ir_relation_less_greater;
525 symconst2 = create_softfloat_symconst(n, "ne");
527 case ir_relation_unordered_less:
528 symconst = create_softfloat_symconst(n, "ge");
529 relation = ir_relation_less;
531 case ir_relation_unordered_less_equal:
532 symconst = create_softfloat_symconst(n, "gt");
533 relation = ir_relation_less_equal;
535 case ir_relation_unordered_greater:
536 symconst = create_softfloat_symconst(n, "le");
537 relation = ir_relation_greater;
539 case ir_relation_unordered_greater_equal:
540 symconst = create_softfloat_symconst(n, "lt");
541 relation = ir_relation_greater_equal;
543 case ir_relation_unordered_less_greater:
544 symconst = create_softfloat_symconst(n, "eq");
545 relation = ir_relation_less_greater;
547 case ir_relation_true:
552 if (call_result == NULL) {
554 ir_node *call_results;
555 ir_node *in[2] = {left, right};
556 ir_node *nomem = get_irg_no_mem(irg);
557 ir_type *type = get_softfloat_type(n);
559 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
560 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
561 call_result = new_r_Proj(call_results, mode_Is, 0);
564 ir_node *cmp = new_r_Cmp(block, call_result, zero, relation);
566 /* We need two calls into the softfloat library */
567 if (symconst2 != NULL) {
569 ir_node *call_results;
571 arch_allow_ifconv_func allow_ifconv = be_get_backend_param()->allow_ifconv;
572 ir_node *in[2] = {left, right};
573 ir_node *nomem = get_irg_no_mem(irg);
574 ir_type *type = get_softfloat_type(n);
576 call = new_rd_Call(dbgi, block, nomem, symconst2, 2, in, type);
577 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
578 call_result = new_r_Proj(call_results, mode_Is, 0);
579 relation = get_Cmp_relation(n);
581 mux = new_rd_Mux(dbgi, block, cmp, call_result, zero, mode_Is);
583 if (! allow_ifconv(cmp, call_result, zero))
584 ir_nodeset_insert(&created_mux_nodes, mux);
586 cmp = new_r_Cmp(block, mux, zero, relation);
592 static const tarval_mode_info hex_output = {
599 * Adapts floating point constants.
601 static void lower_Const(ir_node *n)
603 ir_mode *mode = get_irn_mode(n);
604 if (!mode_is_float(mode))
607 ir_mode *lowered_mode = get_lowered_mode(mode);
608 set_irn_mode(n, lowered_mode);
610 set_tarval_mode_output_option(mode, &hex_output);
612 tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
614 size_t len = strlen(buf);
615 ir_tarval *tv = new_tarval_from_str(buf, len, lowered_mode);
616 set_Const_tarval(n, tv);
620 * Transforms a Conv into the appropriate soft float function.
622 static void lower_Conv(ir_node *n)
625 ir_node *block = get_nodes_block(n);
626 ir_node *call_result = NULL;
627 dbg_info *dbgi = get_irn_dbg_info(n);
628 ir_graph *irg = get_irn_irg(n);
629 ir_node *op = get_Conv_op(n);
630 ir_mode *mode = get_irn_mode(n);
631 ir_mode *op_mode = get_irn_mode(op);
633 if (! mode_is_float(mode) && ! mode_is_float(op_mode))
636 /* Remove unnecessary Convs. */
637 if (op_mode == mode) {
641 else if (op_mode == mode_Hs || op_mode == mode_Bs) {
643 op = new_rd_Conv(dbgi, block, op, op_mode);
645 else if (op_mode == mode_Hu || op_mode == mode_Bu) {
647 op = new_rd_Conv(dbgi, block, op, op_mode);
650 if (mode_is_float(op_mode) && mode_is_float(mode)) {
651 if (get_mode_size_bits(op_mode) > get_mode_size_bits(mode))
652 symconst = create_softfloat_symconst(n, "trunc");
654 symconst = create_softfloat_symconst(n, "extend");
656 else if (mode_is_float(op_mode)) {
657 if (mode_is_signed(mode))
658 symconst = create_softfloat_symconst(n, "fix");
660 symconst = create_softfloat_symconst(n, "fixuns");
663 if (mode_is_signed(op_mode))
664 symconst = create_softfloat_symconst(n, "float");
666 symconst = create_softfloat_symconst(n, "floatun");
670 ir_node *call_results;
671 ir_node *in[1] = {op};
672 ir_node *nomem = get_irg_no_mem(irg);
673 ir_type *type = get_softfloat_type(n);
674 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
676 call = new_rd_Call(dbgi, block, nomem, symconst, 1, in, type);
677 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
678 call_result = new_r_Proj(call_results, res_mode, 0);
680 /* Check whether we need a Conv for the result. */
681 if (res_mode != mode)
682 call_result = new_rd_Conv(dbgi, block, call_result, mode);
684 exchange(n, call_result);
688 * Transforms a Div into the appropriate soft float function.
690 static void lower_Div(ir_node *n)
693 ir_node *block = get_nodes_block(n);
694 ir_node *call_result = NULL;
695 dbg_info *dbgi = get_irn_dbg_info(n);
696 ir_graph *irg = get_irn_irg(n);
697 ir_node *left = get_Div_left(n);
698 ir_mode *mode = get_Div_resmode(n);
699 ir_node *right = get_Div_right(n);
701 if (! mode_is_float(mode))
704 symconst = create_softfloat_symconst(n, "div");
707 ir_node *call_results;
708 ir_node *in[2] = {left, right};
709 ir_node *nomem = get_irg_no_mem(irg);
710 ir_type *type = get_softfloat_type(n);
711 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
713 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
714 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
715 call_result = new_r_Proj(call_results, res_mode, 0);
717 set_irn_pinned(call, get_irn_pinned(n));
719 foreach_out_edge_safe(n, edge) {
720 ir_node *proj = get_edge_src_irn(edge);
724 switch (get_Proj_proj(proj)) {
726 set_Proj_pred(proj, call);
727 set_Proj_proj(proj, pn_Call_M);
729 case pn_Div_X_regular:
730 set_Proj_pred(proj, call);
731 set_Proj_proj(proj, pn_Call_X_regular);
733 case pn_Div_X_except:
734 set_Proj_pred(proj, call);
735 set_Proj_proj(proj, pn_Call_X_except);
738 exchange(proj, call_result);
741 assert(0 && "unexpected Proj number");
748 * Adapts the resmode of a Div.
750 static void lower_Div_mode(ir_node *n)
752 ir_mode *res_mode = get_Div_resmode(n);
753 ir_mode *lowered_res_mode = get_lowered_mode(res_mode);
754 ir_mode *mode = get_irn_mode(n);
755 ir_mode *lowered_mode = get_lowered_mode(mode);
757 set_irn_mode(n, lowered_mode);
758 set_Div_resmode(n, lowered_res_mode);
762 * Adapts the ls_mode of a Load.
764 static void lower_Load(ir_node *n)
766 ir_mode *ls_mode = get_Load_mode(n);
767 ir_mode *lowered_ls_mode = get_lowered_mode(ls_mode);
768 ir_mode *mode = get_irn_mode(n);
769 ir_mode *lowered_mode = get_lowered_mode(mode);
771 set_irn_mode(n, lowered_mode);
772 set_Load_mode(n, lowered_ls_mode);
776 * Transforms a Minus into the appropriate soft float function.
778 static void lower_Minus(ir_node *n)
781 ir_node *block = get_nodes_block(n);
782 ir_node *call_result = NULL;
783 dbg_info *dbgi = get_irn_dbg_info(n);
784 ir_graph *irg = get_irn_irg(n);
785 ir_mode *mode = get_irn_mode(n);
786 ir_node *op = get_Minus_op(n);
788 if (! mode_is_float(mode))
791 symconst = create_softfloat_symconst(n, "neg");
794 ir_node *call_results;
795 ir_node *in[1] = {op};
796 ir_node *nomem = get_irg_no_mem(irg);
797 ir_type *type = get_softfloat_type(n);
798 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
800 call = new_rd_Call(dbgi, block, nomem, symconst, 1, in, type);
801 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
802 call_result = new_r_Proj(call_results, res_mode, 0);
804 exchange(n, call_result);
808 * Transforms a Mul into the appropriate soft float function.
810 static void lower_Mul(ir_node *n)
813 ir_node *block = get_nodes_block(n);
814 ir_node *call_result = NULL;
815 dbg_info *dbgi = get_irn_dbg_info(n);
816 ir_graph *irg = get_irn_irg(n);
817 ir_node *left = get_Mul_left(n);
818 ir_mode *mode = get_irn_mode(n);
819 ir_node *right = get_Mul_right(n);
821 if (! mode_is_float(mode))
824 symconst = create_softfloat_symconst(n, "mul");
827 ir_node *call_results;
828 ir_node *in[2] = {left, right};
829 ir_node *nomem = get_irg_no_mem(irg);
830 ir_type *type = get_softfloat_type(n);
831 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
833 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
834 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
835 call_result = new_r_Proj(call_results, res_mode, 0);
837 exchange(n, call_result);
841 * Transforms a Sub into the appropriate soft float function.
843 static void lower_Sub(ir_node *n)
846 ir_node *block = get_nodes_block(n);
847 ir_node *call_result = NULL;
848 dbg_info *dbgi = get_irn_dbg_info(n);
849 ir_graph *irg = get_irn_irg(n);
850 ir_node *left = get_Sub_left(n);
851 ir_mode *mode = get_irn_mode(n);
852 ir_node *right = get_Sub_right(n);
854 if (! mode_is_float(mode))
857 symconst = create_softfloat_symconst(n, "sub");
860 ir_node *call_results;
861 ir_node *in[2] = {left, right};
862 ir_node *nomem = get_irg_no_mem(irg);
863 ir_type *type = get_softfloat_type(n);
864 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
866 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
867 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
868 call_result = new_r_Proj(call_results, res_mode, 0);
870 exchange(n, call_result);
874 * Enter a lowering function into an ir_op.
876 static void ir_register_softloat_lower_function(ir_op *op, lower_softfloat_func func)
878 op->ops.generic = (op_func)func;
882 * Initializes softfloat lowering.
884 static void ir_prepare_softfloat_lowering(void)
886 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
889 lowered_type = pmap_create();
892 binop_tp_d = new_type_method(2, 1);
893 set_method_param_type(binop_tp_d, 0, get_type_for_mode(mode_D));
894 set_method_param_type(binop_tp_d, 1, get_type_for_mode(mode_D));
895 set_method_res_type(binop_tp_d, 0, get_type_for_mode(mode_D));
899 binop_tp_f = new_type_method(2, 1);
900 set_method_param_type(binop_tp_f, 0, get_type_for_mode(mode_F));
901 set_method_param_type(binop_tp_f, 1, get_type_for_mode(mode_F));
902 set_method_res_type(binop_tp_f, 0, get_type_for_mode(mode_F));
906 cmp_tp_d = new_type_method(2, 1);
907 set_method_param_type(cmp_tp_d, 0, get_type_for_mode(mode_D));
908 set_method_param_type(cmp_tp_d, 1, get_type_for_mode(mode_D));
909 set_method_res_type(cmp_tp_d, 0, get_type_for_mode(mode_Is));
913 cmp_tp_f = new_type_method(2, 1);
914 set_method_param_type(cmp_tp_f, 0, get_type_for_mode(mode_F));
915 set_method_param_type(cmp_tp_f, 1, get_type_for_mode(mode_F));
916 set_method_res_type(cmp_tp_f, 0, get_type_for_mode(mode_Is));
920 unop_tp_d = new_type_method(1, 1);
921 set_method_param_type(unop_tp_d, 0, get_type_for_mode(mode_D));
922 set_method_res_type(unop_tp_d, 0, get_type_for_mode(mode_D));
926 unop_tp_f = new_type_method(1, 1);
927 set_method_param_type(unop_tp_f, 0, get_type_for_mode(mode_F));
928 set_method_res_type(unop_tp_f, 0, get_type_for_mode(mode_F));
932 unop_tp_d_f = new_type_method(1, 1);
933 set_method_param_type(unop_tp_d_f, 0, get_type_for_mode(mode_D));
934 set_method_res_type(unop_tp_d_f, 0, get_type_for_mode(mode_F));
937 if (! unop_tp_d_is) {
938 unop_tp_d_is = new_type_method(1, 1);
939 set_method_param_type(unop_tp_d_is, 0, get_type_for_mode(mode_D));
940 set_method_res_type(unop_tp_d_is, 0, get_type_for_mode(mode_Is));
943 if (! unop_tp_d_iu) {
944 unop_tp_d_iu = new_type_method(1, 1);
945 set_method_param_type(unop_tp_d_iu, 0, get_type_for_mode(mode_D));
946 set_method_res_type(unop_tp_d_iu, 0, get_type_for_mode(mode_Iu));
949 if (! unop_tp_d_ls) {
950 unop_tp_d_ls = new_type_method(1, 1);
951 set_method_param_type(unop_tp_d_ls, 0, get_type_for_mode(mode_D));
952 set_method_res_type(unop_tp_d_ls, 0, get_type_for_mode(mode_Ls));
955 if (! unop_tp_d_lu) {
956 unop_tp_d_lu = new_type_method(1, 1);
957 set_method_param_type(unop_tp_d_lu, 0, get_type_for_mode(mode_D));
958 set_method_res_type(unop_tp_d_lu, 0, get_type_for_mode(mode_Lu));
962 unop_tp_f_d = new_type_method(1, 1);
963 set_method_param_type(unop_tp_f_d, 0, get_type_for_mode(mode_F));
964 set_method_res_type(unop_tp_f_d, 0, get_type_for_mode(mode_D));
967 if (! unop_tp_f_is) {
968 unop_tp_f_is = new_type_method(1, 1);
969 set_method_param_type(unop_tp_f_is, 0, get_type_for_mode(mode_F));
970 set_method_res_type(unop_tp_f_is, 0, get_type_for_mode(mode_Is));
973 if (! unop_tp_f_iu) {
974 unop_tp_f_iu = new_type_method(1, 1);
975 set_method_param_type(unop_tp_f_iu, 0, get_type_for_mode(mode_F));
976 set_method_res_type(unop_tp_f_iu, 0, get_type_for_mode(mode_Iu));
979 if (! unop_tp_f_ls) {
980 unop_tp_f_ls = new_type_method(1, 1);
981 set_method_param_type(unop_tp_f_ls, 0, get_type_for_mode(mode_F));
982 set_method_res_type(unop_tp_f_ls, 0, get_type_for_mode(mode_Ls));
985 if (! unop_tp_f_lu) {
986 unop_tp_f_lu = new_type_method(1, 1);
987 set_method_param_type(unop_tp_f_lu, 0, get_type_for_mode(mode_F));
988 set_method_res_type(unop_tp_f_lu, 0, get_type_for_mode(mode_Lu));
991 if (! unop_tp_is_d) {
992 unop_tp_is_d = new_type_method(1, 1);
993 set_method_param_type(unop_tp_is_d, 0, get_type_for_mode(mode_Is));
994 set_method_res_type(unop_tp_is_d, 0, get_type_for_mode(mode_D));
997 if (! unop_tp_is_f) {
998 unop_tp_is_f = new_type_method(1, 1);
999 set_method_param_type(unop_tp_is_f, 0, get_type_for_mode(mode_Is));
1000 set_method_res_type(unop_tp_is_f, 0, get_type_for_mode(mode_F));
1003 if (! unop_tp_iu_d) {
1004 unop_tp_iu_d = new_type_method(1, 1);
1005 set_method_param_type(unop_tp_iu_d, 0, get_type_for_mode(mode_Iu));
1006 set_method_res_type(unop_tp_iu_d, 0, get_type_for_mode(mode_D));
1009 if (! unop_tp_iu_f) {
1010 unop_tp_iu_f = new_type_method(1, 1);
1011 set_method_param_type(unop_tp_iu_f, 0, get_type_for_mode(mode_Iu));
1012 set_method_res_type(unop_tp_iu_f, 0, get_type_for_mode(mode_F));
1015 if (! unop_tp_ls_d) {
1016 unop_tp_ls_d = new_type_method(1, 1);
1017 set_method_param_type(unop_tp_ls_d, 0, get_type_for_mode(mode_Ls));
1018 set_method_res_type(unop_tp_ls_d, 0, get_type_for_mode(mode_D));
1021 if (! unop_tp_ls_f) {
1022 unop_tp_ls_f = new_type_method(1, 1);
1023 set_method_param_type(unop_tp_ls_f, 0, get_type_for_mode(mode_Ls));
1024 set_method_res_type(unop_tp_ls_f, 0, get_type_for_mode(mode_F));
1027 if (! unop_tp_lu_d) {
1028 unop_tp_lu_d = new_type_method(1, 1);
1029 set_method_param_type(unop_tp_lu_d, 0, get_type_for_mode(mode_Lu));
1030 set_method_res_type(unop_tp_lu_d, 0, get_type_for_mode(mode_D));
1033 if (! unop_tp_lu_f) {
1034 unop_tp_lu_f = new_type_method(1, 1);
1035 set_method_param_type(unop_tp_lu_f, 0, get_type_for_mode(mode_Lu));
1036 set_method_res_type(unop_tp_lu_f, 0, get_type_for_mode(mode_F));
1041 * Callback to lower only the Mux nodes we created.
1043 static int lower_mux_cb(ir_node *mux)
1045 return ir_nodeset_contains(&created_mux_nodes, mux);
1048 void lower_floating_point(void)
1051 size_t n_irgs = get_irp_n_irgs();
1053 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
1055 ir_prepare_softfloat_lowering();
1057 ir_clear_opcodes_generic_func();
1058 ir_register_softloat_lower_function(op_Add, lower_Add);
1059 ir_register_softloat_lower_function(op_Cmp, lower_Cmp);
1060 ir_register_softloat_lower_function(op_Conv, lower_Conv);
1061 ir_register_softloat_lower_function(op_Div, lower_Div);
1062 ir_register_softloat_lower_function(op_Minus, lower_Minus);
1063 ir_register_softloat_lower_function(op_Mul, lower_Mul);
1064 ir_register_softloat_lower_function(op_Sub, lower_Sub);
1066 for (i = 0; i < n_irgs; ++i) {
1067 ir_graph *irg = get_irp_irg(i);
1069 ir_nodeset_init(&created_mux_nodes);
1073 irg_walk_graph(irg, NULL, lower_node, NULL);
1075 if (ir_nodeset_size(&created_mux_nodes) > 0)
1076 lower_mux(irg, lower_mux_cb);
1078 ir_nodeset_destroy(&created_mux_nodes);
1081 ir_clear_opcodes_generic_func();
1082 ir_register_softloat_lower_function(op_Call, lower_Call);
1083 ir_register_softloat_lower_function(op_Const, lower_Const);
1084 ir_register_softloat_lower_function(op_Div, lower_Div_mode);
1085 ir_register_softloat_lower_function(op_Load, lower_Load);
1087 for (i = 0; i < n_irgs; ++i) {
1088 ir_graph *irg = get_irp_irg(i);
1089 ir_entity *ent = get_irg_entity(irg);
1090 ir_type *mtp = get_entity_type(ent);
1091 ir_type *lowered_mtp = lower_method_type(mtp);
1092 ir_type *frame_tp = get_irg_frame_type(irg);
1096 if (lowered_mtp != mtp)
1097 set_entity_type(ent, lowered_mtp);
1099 irg_walk_graph(irg, NULL, lower_mode, NULL);
1101 /* fixup parameter entities */
1102 n_members = get_compound_n_members(frame_tp);
1103 for (i = 0; i < n_members; ++i) {
1104 ir_entity *member = get_compound_member(frame_tp, i);
1105 ir_type *type = get_entity_type(member);
1106 if (is_Primitive_type(type)) {
1107 ir_type *lowered = lower_type(type);
1108 set_entity_type(member, lowered);