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 mode = get_Div_resmode(n);
145 operand_mode = get_irn_mode(get_Div_left(n));
150 if (operand_mode == mode_F)
152 else if (operand_mode == mode_D)
156 if (operand_mode == mode_F)
158 else if (operand_mode == mode_D)
162 if (operand_mode == mode_D) {
165 else if (mode == mode_Is || mode == mode_Hs || mode == mode_Bs)
167 else if (mode == mode_Iu || mode == mode_Hu || mode == mode_Bu)
169 else if (mode == mode_Ls)
171 else if (mode == mode_Lu)
174 else if (operand_mode == mode_F) {
177 else if (mode == mode_Is || mode == mode_Hs || mode == mode_Bs)
179 else if (mode == mode_Iu || mode == mode_Hu || mode == mode_Bu)
181 else if (mode == mode_Ls)
183 else if (mode == mode_Lu)
186 else if (operand_mode == mode_Is || operand_mode == mode_Hs || operand_mode == mode_Bs) {
189 else if (mode == mode_F)
192 else if (operand_mode == mode_Iu || operand_mode == mode_Hu || operand_mode == mode_Bu) {
195 else if (mode == mode_F)
198 else if (operand_mode == mode_Ls) {
201 else if (mode == mode_F)
204 else if (operand_mode == mode_Lu) {
207 else if (mode == mode_F)
212 if (operand_mode == mode_F)
214 else if (operand_mode == mode_D)
220 assert(0 && "Could not determine a suitable type");
226 * @return A SymConst representing the function that replaces the given node.
228 static ir_node *create_softfloat_symconst(const ir_node *n, const char *name)
231 const char *first_param = "";
232 const char *second_param = "";
233 const char *result = "";
238 unsigned float_types = 0;
239 unsigned double_types = 0;
240 ir_graph *irg = get_irn_irg(n);
241 ir_type *method = get_softfloat_type(n);
243 n_params = get_method_n_params(method);
245 /* Parameter types. */
249 ir_type *param_type = get_method_param_type(method, 1);
250 ir_mode *mode = get_type_mode(param_type);
252 if (mode == mode_F) {
256 else if (mode == mode_D) {
260 else if (mode == mode_Iu || mode == mode_Is)
262 else if (mode == mode_Lu || mode == mode_Ls)
268 ir_type *param_type = get_method_param_type(method, 0);
269 ir_mode *mode = get_type_mode(param_type);
271 if (mode == mode_F) {
272 first_param = float_types > 0 ? "" : "sf";
275 else if (mode == mode_D) {
276 first_param = double_types > 0 ? "" : "df";
279 else if (mode == mode_Iu || mode == mode_Is)
281 else if (mode == mode_Lu || mode == mode_Ls)
294 mode = get_Div_resmode(n);
296 mode = get_irn_mode(n);
298 if (mode == mode_F) {
299 result = float_types > 0 ? "" : "sf";
302 else if (mode == mode_D) {
303 result = double_types > 0 ? "" : "df";
306 else if (mode == mode_Iu || mode == mode_Hu || mode == mode_Bu
307 || mode == mode_Is || mode == mode_Hs || mode == mode_Bs)
309 else if (mode == mode_Lu || mode == mode_Ls)
313 assert(float_types <= 3);
314 assert(double_types <= 3);
316 if (float_types + double_types > 1)
317 snprintf(buf, sizeof(buf), "__%s%s%s%s%u", name, first_param, second_param, result, float_types + double_types);
319 snprintf(buf, sizeof(buf), "__%s%s%s%s", name, first_param, second_param, result);
321 id = new_id_from_str(buf);
322 ent = create_compilerlib_entity(id, method);
325 return new_r_SymConst(irg, mode_P_code, sym, symconst_addr_ent);
329 * Transforms an Add into the appropriate soft float function.
331 static void lower_Add(ir_node *n)
334 ir_node *block = get_nodes_block(n);
335 ir_node *call_result = NULL;
336 dbg_info *dbgi = get_irn_dbg_info(n);
337 ir_graph *irg = get_irn_irg(n);
338 ir_node *left = get_Add_left(n);
339 ir_node *right = get_Add_right(n);
340 ir_mode *mode = get_irn_mode(n);
342 if (! mode_is_float(mode))
345 symconst = create_softfloat_symconst(n, "add");
348 ir_node *call_results;
349 ir_node *in[2] = {left, right};
350 ir_node *nomem = get_irg_no_mem(irg);
351 ir_type *type = get_softfloat_type(n);
352 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
354 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
355 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
356 call_result = new_r_Proj(call_results, res_mode, 0);
358 exchange(n, call_result);
362 * @return The lowered (floating point) type.
364 static ir_type *lower_type(ir_type *tp)
366 ir_mode *mode = get_type_mode(tp);
367 ir_mode *lowered_mode = get_lowered_mode(mode);
369 return get_type_for_mode(lowered_mode);
373 * @return The lowered method type.
375 static ir_type *lower_method_type(ir_type *mtp)
382 res = pmap_get(ir_type, lowered_type, mtp);
386 n_param = get_method_n_params(mtp);
387 n_res = get_method_n_ress(mtp);
389 res = new_type_method(n_param, n_res);
391 /* set param types and result types */
392 for (i = 0; i < n_param; ++i) {
393 ir_type *ptp = get_method_param_type(mtp, i);
394 ir_mode *pmode = get_type_mode(ptp);
396 if (pmode != NULL && mode_is_float(pmode)) {
397 ptp = lower_type(ptp);
400 set_method_param_type(res, i, ptp);
402 for (i = 0; i < n_res; ++i) {
403 ir_type *rtp = get_method_res_type(mtp, i);
404 ir_mode *rmode = get_type_mode(rtp);
406 if (rmode != NULL && mode_is_float(rmode)) {
407 rtp = lower_type(rtp);
410 set_method_res_type(res, i, rtp);
413 set_method_variadicity(res, get_method_variadicity(mtp));
414 set_method_calling_convention(res, get_method_calling_convention(mtp));
415 set_method_additional_properties(res, get_method_additional_properties(mtp));
417 set_higher_type(res, mtp);
419 pmap_insert(lowered_type, mtp, res);
424 * Adapts the method type of a Call.
426 static void lower_Call(ir_node *node)
428 ir_type *tp = get_Call_type(node);
431 bool need_lower = false;
435 n_params = get_method_n_params(tp);
437 for (p = 0; p < n_params; ++p) {
438 ir_type *ptp = get_method_param_type(tp, p);
439 ir_mode *pmode = get_type_mode(ptp);
444 if (mode_is_float(pmode)) {
450 n_res = get_method_n_ress(tp);
452 for (i = 0; i < n_res; ++i) {
453 ir_type *rtp = get_method_res_type(tp, i);
454 ir_mode *rmode = get_type_mode(rtp);
459 if (mode_is_float(rmode)) {
468 tp = lower_method_type(tp);
469 set_Call_type(node, tp);
473 * Transforms a Cmp into the appropriate soft float function.
475 static void lower_Cmp(ir_node *n)
477 ir_node *symconst = NULL;
478 ir_node *block = get_nodes_block(n);
479 ir_node *call_result = NULL;
480 dbg_info *dbgi = get_irn_dbg_info(n);
481 ir_graph *irg = get_irn_irg(n);
482 ir_node *left = get_Cmp_left(n);
483 ir_relation relation = get_Cmp_relation(n);
484 ir_mode *op_mode = get_irn_mode(left);
485 ir_node *right = get_Cmp_right(n);
486 ir_node *symconst2 = NULL;
487 ir_node *zero = new_rd_Const(dbgi, irg, get_mode_null(mode_Is));
489 if (! mode_is_float(op_mode))
493 case ir_relation_false:
496 case ir_relation_equal:
497 symconst = create_softfloat_symconst(n, "eq");
499 case ir_relation_less:
500 symconst = create_softfloat_symconst(n, "lt");
502 case ir_relation_greater:
503 symconst = create_softfloat_symconst(n, "gt");
505 case ir_relation_unordered:
506 symconst = create_softfloat_symconst(n, "unord");
507 relation = ir_relation_less_greater;
509 case ir_relation_less_equal:
510 symconst = create_softfloat_symconst(n, "le");
512 case ir_relation_greater_equal:
513 symconst = create_softfloat_symconst(n, "ge");
515 case ir_relation_less_greater:
516 symconst = create_softfloat_symconst(n, "unord");
517 symconst2 = create_softfloat_symconst(n, "ne");
519 case ir_relation_less_equal_greater:
520 symconst = create_softfloat_symconst(n, "unord");
521 relation = ir_relation_equal;
523 case ir_relation_unordered_equal:
524 symconst = create_softfloat_symconst(n, "unord");
525 relation = ir_relation_less_greater;
526 symconst2 = create_softfloat_symconst(n, "ne");
528 case ir_relation_unordered_less:
529 symconst = create_softfloat_symconst(n, "ge");
530 relation = ir_relation_less;
532 case ir_relation_unordered_less_equal:
533 symconst = create_softfloat_symconst(n, "gt");
534 relation = ir_relation_less_equal;
536 case ir_relation_unordered_greater:
537 symconst = create_softfloat_symconst(n, "le");
538 relation = ir_relation_greater;
540 case ir_relation_unordered_greater_equal:
541 symconst = create_softfloat_symconst(n, "lt");
542 relation = ir_relation_greater_equal;
544 case ir_relation_unordered_less_greater:
545 symconst = create_softfloat_symconst(n, "eq");
546 relation = ir_relation_less_greater;
548 case ir_relation_true:
553 if (call_result == NULL) {
555 ir_node *call_results;
556 ir_node *in[2] = {left, right};
557 ir_node *nomem = get_irg_no_mem(irg);
558 ir_type *type = get_softfloat_type(n);
560 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
561 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
562 call_result = new_r_Proj(call_results, mode_Is, 0);
565 ir_node *cmp = new_r_Cmp(block, call_result, zero, relation);
567 /* We need two calls into the softfloat library */
568 if (symconst2 != NULL) {
570 ir_node *call_results;
572 arch_allow_ifconv_func allow_ifconv = be_get_backend_param()->allow_ifconv;
573 ir_node *in[2] = {left, right};
574 ir_node *nomem = get_irg_no_mem(irg);
575 ir_type *type = get_softfloat_type(n);
577 call = new_rd_Call(dbgi, block, nomem, symconst2, 2, in, type);
578 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
579 call_result = new_r_Proj(call_results, mode_Is, 0);
580 relation = get_Cmp_relation(n);
582 mux = new_rd_Mux(dbgi, block, cmp, call_result, zero, mode_Is);
584 if (! allow_ifconv(cmp, call_result, zero))
585 ir_nodeset_insert(&created_mux_nodes, mux);
587 cmp = new_r_Cmp(block, mux, zero, relation);
593 static const tarval_mode_info hex_output = {
600 * Adapts floating point constants.
602 static void lower_Const(ir_node *n)
604 ir_mode *lowered_mode;
605 ir_mode *mode = get_irn_mode(n);
606 ir_tarval *tv = get_Const_tarval(n);
610 if (! mode_is_float(mode))
613 lowered_mode = get_lowered_mode(mode);
614 set_irn_mode(n, lowered_mode);
616 set_tarval_mode_output_option(mode, &hex_output);
617 tarval_snprintf(buf, 100, get_Const_tarval(n));
620 tv = new_tarval_from_str(buf, len, lowered_mode);
621 set_Const_tarval(n, tv);
625 * Transforms a Conv into the appropriate soft float function.
627 static void lower_Conv(ir_node *n)
630 ir_node *block = get_nodes_block(n);
631 ir_node *call_result = NULL;
632 dbg_info *dbgi = get_irn_dbg_info(n);
633 ir_graph *irg = get_irn_irg(n);
634 ir_node *op = get_Conv_op(n);
635 ir_mode *mode = get_irn_mode(n);
636 ir_mode *op_mode = get_irn_mode(op);
638 if (! mode_is_float(mode) && ! mode_is_float(op_mode))
641 /* Remove unnecessary Convs. */
642 if (op_mode == mode) {
646 else if (op_mode == mode_Hs || op_mode == mode_Bs) {
648 op = new_rd_Conv(dbgi, block, op, op_mode);
650 else if (op_mode == mode_Hu || op_mode == mode_Bu) {
652 op = new_rd_Conv(dbgi, block, op, op_mode);
655 if (mode_is_float(op_mode) && mode_is_float(mode)) {
656 if (get_mode_size_bits(op_mode) > get_mode_size_bits(mode))
657 symconst = create_softfloat_symconst(n, "trunc");
659 symconst = create_softfloat_symconst(n, "extend");
661 else if (mode_is_float(op_mode)) {
662 if (mode_is_signed(mode))
663 symconst = create_softfloat_symconst(n, "fix");
665 symconst = create_softfloat_symconst(n, "fixuns");
668 if (mode_is_signed(op_mode))
669 symconst = create_softfloat_symconst(n, "float");
671 symconst = create_softfloat_symconst(n, "floatun");
675 ir_node *call_results;
676 ir_node *in[1] = {op};
677 ir_node *nomem = get_irg_no_mem(irg);
678 ir_type *type = get_softfloat_type(n);
679 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
681 call = new_rd_Call(dbgi, block, nomem, symconst, 1, in, type);
682 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
683 call_result = new_r_Proj(call_results, res_mode, 0);
685 /* Check whether we need a Conv for the result. */
686 if (res_mode != mode)
687 call_result = new_rd_Conv(dbgi, block, call_result, mode);
689 exchange(n, call_result);
693 * Transforms a Div into the appropriate soft float function.
695 static void lower_Div(ir_node *n)
698 ir_node *block = get_nodes_block(n);
699 ir_node *call_result = NULL;
700 dbg_info *dbgi = get_irn_dbg_info(n);
701 ir_graph *irg = get_irn_irg(n);
702 ir_node *left = get_Div_left(n);
703 ir_mode *mode = get_Div_resmode(n);
704 ir_node *right = get_Div_right(n);
706 if (! mode_is_float(mode))
709 symconst = create_softfloat_symconst(n, "div");
712 ir_node *call_results;
713 ir_node *in[2] = {left, right};
714 ir_node *nomem = get_irg_no_mem(irg);
715 ir_type *type = get_softfloat_type(n);
716 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
718 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
719 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
720 call_result = new_r_Proj(call_results, res_mode, 0);
722 set_irn_pinned(call, get_irn_pinned(n));
724 foreach_out_edge_safe(n, edge) {
725 ir_node *proj = get_edge_src_irn(edge);
729 switch (get_Proj_proj(proj)) {
731 set_Proj_pred(proj, call);
732 set_Proj_proj(proj, pn_Call_M);
734 case pn_Div_X_regular:
735 set_Proj_pred(proj, call);
736 set_Proj_proj(proj, pn_Call_X_regular);
738 case pn_Div_X_except:
739 set_Proj_pred(proj, call);
740 set_Proj_proj(proj, pn_Call_X_except);
743 exchange(proj, call_result);
746 assert(0 && "unexpected Proj number");
753 * Adapts the resmode of a Div.
755 static void lower_Div_mode(ir_node *n)
757 ir_mode *res_mode = get_Div_resmode(n);
758 ir_mode *lowered_res_mode = get_lowered_mode(res_mode);
759 ir_mode *mode = get_irn_mode(n);
760 ir_mode *lowered_mode = get_lowered_mode(mode);
762 set_irn_mode(n, lowered_mode);
763 set_Div_resmode(n, lowered_res_mode);
767 * Adapts the ls_mode of a Load.
769 static void lower_Load(ir_node *n)
771 ir_mode *ls_mode = get_Load_mode(n);
772 ir_mode *lowered_ls_mode = get_lowered_mode(ls_mode);
773 ir_mode *mode = get_irn_mode(n);
774 ir_mode *lowered_mode = get_lowered_mode(mode);
776 set_irn_mode(n, lowered_mode);
777 set_Load_mode(n, lowered_ls_mode);
781 * Transforms a Minus into the appropriate soft float function.
783 static void lower_Minus(ir_node *n)
786 ir_node *block = get_nodes_block(n);
787 ir_node *call_result = NULL;
788 dbg_info *dbgi = get_irn_dbg_info(n);
789 ir_graph *irg = get_irn_irg(n);
790 ir_mode *mode = get_irn_mode(n);
791 ir_node *op = get_Minus_op(n);
793 if (! mode_is_float(mode))
796 symconst = create_softfloat_symconst(n, "neg");
799 ir_node *call_results;
800 ir_node *in[1] = {op};
801 ir_node *nomem = get_irg_no_mem(irg);
802 ir_type *type = get_softfloat_type(n);
803 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
805 call = new_rd_Call(dbgi, block, nomem, symconst, 1, in, type);
806 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
807 call_result = new_r_Proj(call_results, res_mode, 0);
809 exchange(n, call_result);
813 * Transforms a Mul into the appropriate soft float function.
815 static void lower_Mul(ir_node *n)
818 ir_node *block = get_nodes_block(n);
819 ir_node *call_result = NULL;
820 dbg_info *dbgi = get_irn_dbg_info(n);
821 ir_graph *irg = get_irn_irg(n);
822 ir_node *left = get_Mul_left(n);
823 ir_mode *mode = get_irn_mode(n);
824 ir_node *right = get_Mul_right(n);
826 if (! mode_is_float(mode))
829 symconst = create_softfloat_symconst(n, "mul");
832 ir_node *call_results;
833 ir_node *in[2] = {left, right};
834 ir_node *nomem = get_irg_no_mem(irg);
835 ir_type *type = get_softfloat_type(n);
836 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
838 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
839 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
840 call_result = new_r_Proj(call_results, res_mode, 0);
842 exchange(n, call_result);
846 * Transforms a Sub into the appropriate soft float function.
848 static void lower_Sub(ir_node *n)
851 ir_node *block = get_nodes_block(n);
852 ir_node *call_result = NULL;
853 dbg_info *dbgi = get_irn_dbg_info(n);
854 ir_graph *irg = get_irn_irg(n);
855 ir_node *left = get_Sub_left(n);
856 ir_mode *mode = get_irn_mode(n);
857 ir_node *right = get_Sub_right(n);
859 if (! mode_is_float(mode))
862 symconst = create_softfloat_symconst(n, "sub");
865 ir_node *call_results;
866 ir_node *in[2] = {left, right};
867 ir_node *nomem = get_irg_no_mem(irg);
868 ir_type *type = get_softfloat_type(n);
869 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
871 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
872 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
873 call_result = new_r_Proj(call_results, res_mode, 0);
875 exchange(n, call_result);
879 * Enter a lowering function into an ir_op.
881 static void ir_register_softloat_lower_function(ir_op *op, lower_softfloat_func func)
883 op->ops.generic = (op_func)func;
887 * Initializes softfloat lowering.
889 static void ir_prepare_softfloat_lowering(void)
891 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
894 lowered_type = pmap_create();
897 binop_tp_d = new_type_method(2, 1);
898 set_method_param_type(binop_tp_d, 0, get_type_for_mode(mode_D));
899 set_method_param_type(binop_tp_d, 1, get_type_for_mode(mode_D));
900 set_method_res_type(binop_tp_d, 0, get_type_for_mode(mode_D));
904 binop_tp_f = new_type_method(2, 1);
905 set_method_param_type(binop_tp_f, 0, get_type_for_mode(mode_F));
906 set_method_param_type(binop_tp_f, 1, get_type_for_mode(mode_F));
907 set_method_res_type(binop_tp_f, 0, get_type_for_mode(mode_F));
911 cmp_tp_d = new_type_method(2, 1);
912 set_method_param_type(cmp_tp_d, 0, get_type_for_mode(mode_D));
913 set_method_param_type(cmp_tp_d, 1, get_type_for_mode(mode_D));
914 set_method_res_type(cmp_tp_d, 0, get_type_for_mode(mode_Is));
918 cmp_tp_f = new_type_method(2, 1);
919 set_method_param_type(cmp_tp_f, 0, get_type_for_mode(mode_F));
920 set_method_param_type(cmp_tp_f, 1, get_type_for_mode(mode_F));
921 set_method_res_type(cmp_tp_f, 0, get_type_for_mode(mode_Is));
925 unop_tp_d = new_type_method(1, 1);
926 set_method_param_type(unop_tp_d, 0, get_type_for_mode(mode_D));
927 set_method_res_type(unop_tp_d, 0, get_type_for_mode(mode_D));
931 unop_tp_f = new_type_method(1, 1);
932 set_method_param_type(unop_tp_f, 0, get_type_for_mode(mode_F));
933 set_method_res_type(unop_tp_f, 0, get_type_for_mode(mode_F));
937 unop_tp_d_f = new_type_method(1, 1);
938 set_method_param_type(unop_tp_d_f, 0, get_type_for_mode(mode_D));
939 set_method_res_type(unop_tp_d_f, 0, get_type_for_mode(mode_F));
942 if (! unop_tp_d_is) {
943 unop_tp_d_is = new_type_method(1, 1);
944 set_method_param_type(unop_tp_d_is, 0, get_type_for_mode(mode_D));
945 set_method_res_type(unop_tp_d_is, 0, get_type_for_mode(mode_Is));
948 if (! unop_tp_d_iu) {
949 unop_tp_d_iu = new_type_method(1, 1);
950 set_method_param_type(unop_tp_d_iu, 0, get_type_for_mode(mode_D));
951 set_method_res_type(unop_tp_d_iu, 0, get_type_for_mode(mode_Iu));
954 if (! unop_tp_d_ls) {
955 unop_tp_d_ls = new_type_method(1, 1);
956 set_method_param_type(unop_tp_d_ls, 0, get_type_for_mode(mode_D));
957 set_method_res_type(unop_tp_d_ls, 0, get_type_for_mode(mode_Ls));
960 if (! unop_tp_d_lu) {
961 unop_tp_d_lu = new_type_method(1, 1);
962 set_method_param_type(unop_tp_d_lu, 0, get_type_for_mode(mode_D));
963 set_method_res_type(unop_tp_d_lu, 0, get_type_for_mode(mode_Lu));
967 unop_tp_f_d = new_type_method(1, 1);
968 set_method_param_type(unop_tp_f_d, 0, get_type_for_mode(mode_F));
969 set_method_res_type(unop_tp_f_d, 0, get_type_for_mode(mode_D));
972 if (! unop_tp_f_is) {
973 unop_tp_f_is = new_type_method(1, 1);
974 set_method_param_type(unop_tp_f_is, 0, get_type_for_mode(mode_F));
975 set_method_res_type(unop_tp_f_is, 0, get_type_for_mode(mode_Is));
978 if (! unop_tp_f_iu) {
979 unop_tp_f_iu = new_type_method(1, 1);
980 set_method_param_type(unop_tp_f_iu, 0, get_type_for_mode(mode_F));
981 set_method_res_type(unop_tp_f_iu, 0, get_type_for_mode(mode_Iu));
984 if (! unop_tp_f_ls) {
985 unop_tp_f_ls = new_type_method(1, 1);
986 set_method_param_type(unop_tp_f_ls, 0, get_type_for_mode(mode_F));
987 set_method_res_type(unop_tp_f_ls, 0, get_type_for_mode(mode_Ls));
990 if (! unop_tp_f_lu) {
991 unop_tp_f_lu = new_type_method(1, 1);
992 set_method_param_type(unop_tp_f_lu, 0, get_type_for_mode(mode_F));
993 set_method_res_type(unop_tp_f_lu, 0, get_type_for_mode(mode_Lu));
996 if (! unop_tp_is_d) {
997 unop_tp_is_d = new_type_method(1, 1);
998 set_method_param_type(unop_tp_is_d, 0, get_type_for_mode(mode_Is));
999 set_method_res_type(unop_tp_is_d, 0, get_type_for_mode(mode_D));
1002 if (! unop_tp_is_f) {
1003 unop_tp_is_f = new_type_method(1, 1);
1004 set_method_param_type(unop_tp_is_f, 0, get_type_for_mode(mode_Is));
1005 set_method_res_type(unop_tp_is_f, 0, get_type_for_mode(mode_F));
1008 if (! unop_tp_iu_d) {
1009 unop_tp_iu_d = new_type_method(1, 1);
1010 set_method_param_type(unop_tp_iu_d, 0, get_type_for_mode(mode_Iu));
1011 set_method_res_type(unop_tp_iu_d, 0, get_type_for_mode(mode_D));
1014 if (! unop_tp_iu_f) {
1015 unop_tp_iu_f = new_type_method(1, 1);
1016 set_method_param_type(unop_tp_iu_f, 0, get_type_for_mode(mode_Iu));
1017 set_method_res_type(unop_tp_iu_f, 0, get_type_for_mode(mode_F));
1020 if (! unop_tp_ls_d) {
1021 unop_tp_ls_d = new_type_method(1, 1);
1022 set_method_param_type(unop_tp_ls_d, 0, get_type_for_mode(mode_Ls));
1023 set_method_res_type(unop_tp_ls_d, 0, get_type_for_mode(mode_D));
1026 if (! unop_tp_ls_f) {
1027 unop_tp_ls_f = new_type_method(1, 1);
1028 set_method_param_type(unop_tp_ls_f, 0, get_type_for_mode(mode_Ls));
1029 set_method_res_type(unop_tp_ls_f, 0, get_type_for_mode(mode_F));
1032 if (! unop_tp_lu_d) {
1033 unop_tp_lu_d = new_type_method(1, 1);
1034 set_method_param_type(unop_tp_lu_d, 0, get_type_for_mode(mode_Lu));
1035 set_method_res_type(unop_tp_lu_d, 0, get_type_for_mode(mode_D));
1038 if (! unop_tp_lu_f) {
1039 unop_tp_lu_f = new_type_method(1, 1);
1040 set_method_param_type(unop_tp_lu_f, 0, get_type_for_mode(mode_Lu));
1041 set_method_res_type(unop_tp_lu_f, 0, get_type_for_mode(mode_F));
1046 * Callback to lower only the Mux nodes we created.
1048 static int lower_mux_cb(ir_node *mux)
1050 return ir_nodeset_contains(&created_mux_nodes, mux);
1053 void lower_floating_point(void)
1056 size_t n_irgs = get_irp_n_irgs();
1058 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
1060 ir_prepare_softfloat_lowering();
1062 ir_clear_opcodes_generic_func();
1063 ir_register_softloat_lower_function(op_Add, lower_Add);
1064 ir_register_softloat_lower_function(op_Cmp, lower_Cmp);
1065 ir_register_softloat_lower_function(op_Conv, lower_Conv);
1066 ir_register_softloat_lower_function(op_Div, lower_Div);
1067 ir_register_softloat_lower_function(op_Minus, lower_Minus);
1068 ir_register_softloat_lower_function(op_Mul, lower_Mul);
1069 ir_register_softloat_lower_function(op_Sub, lower_Sub);
1071 for (i = 0; i < n_irgs; ++i) {
1072 ir_graph *irg = get_irp_irg(i);
1074 ir_nodeset_init(&created_mux_nodes);
1078 irg_walk_graph(irg, NULL, lower_node, NULL);
1080 if (ir_nodeset_size(&created_mux_nodes) > 0)
1081 lower_mux(irg, lower_mux_cb);
1083 ir_nodeset_destroy(&created_mux_nodes);
1086 ir_clear_opcodes_generic_func();
1087 ir_register_softloat_lower_function(op_Call, lower_Call);
1088 ir_register_softloat_lower_function(op_Const, lower_Const);
1089 ir_register_softloat_lower_function(op_Div, lower_Div_mode);
1090 ir_register_softloat_lower_function(op_Load, lower_Load);
1092 for (i = 0; i < n_irgs; ++i) {
1093 ir_graph *irg = get_irp_irg(i);
1094 ir_entity *ent = get_irg_entity(irg);
1095 ir_type *mtp = get_entity_type(ent);
1096 ir_type *lowered_mtp = lower_method_type(mtp);
1097 ir_type *frame_tp = get_irg_frame_type(irg);
1101 if (lowered_mtp != mtp)
1102 set_entity_type(ent, lowered_mtp);
1104 irg_walk_graph(irg, NULL, lower_mode, NULL);
1106 /* fixup parameter entities */
1107 n_members = get_compound_n_members(frame_tp);
1108 for (i = 0; i < n_members; ++i) {
1109 ir_entity *member = get_compound_member(frame_tp, i);
1110 ir_type *type = get_entity_type(member);
1111 if (is_Primitive_type(type)) {
1112 ir_type *lowered = lower_type(type);
1113 set_entity_type(member, lowered);