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 = (ir_type*)pmap_get(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);
705 const ir_edge_t *edge;
706 const ir_edge_t *next;
708 if (! mode_is_float(mode))
711 symconst = create_softfloat_symconst(n, "div");
714 ir_node *call_results;
715 ir_node *in[2] = {left, right};
716 ir_node *nomem = get_irg_no_mem(irg);
717 ir_type *type = get_softfloat_type(n);
718 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
720 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
721 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
722 call_result = new_r_Proj(call_results, res_mode, 0);
724 set_irn_pinned(call, get_irn_pinned(n));
726 foreach_out_edge_safe(n, edge, next) {
727 ir_node *proj = get_edge_src_irn(edge);
731 switch (get_Proj_proj(proj)) {
733 set_Proj_pred(proj, call);
734 set_Proj_proj(proj, pn_Call_M);
736 case pn_Div_X_regular:
737 set_Proj_pred(proj, call);
738 set_Proj_proj(proj, pn_Call_X_regular);
740 case pn_Div_X_except:
741 set_Proj_pred(proj, call);
742 set_Proj_proj(proj, pn_Call_X_except);
745 exchange(proj, call_result);
748 assert(0 && "unexpected Proj number");
755 * Adapts the resmode of a Div.
757 static void lower_Div_mode(ir_node *n)
759 ir_mode *res_mode = get_Div_resmode(n);
760 ir_mode *lowered_res_mode = get_lowered_mode(res_mode);
761 ir_mode *mode = get_irn_mode(n);
762 ir_mode *lowered_mode = get_lowered_mode(mode);
764 set_irn_mode(n, lowered_mode);
765 set_Div_resmode(n, lowered_res_mode);
769 * Adapts the ls_mode of a Load.
771 static void lower_Load(ir_node *n)
773 ir_mode *ls_mode = get_Load_mode(n);
774 ir_mode *lowered_ls_mode = get_lowered_mode(ls_mode);
775 ir_mode *mode = get_irn_mode(n);
776 ir_mode *lowered_mode = get_lowered_mode(mode);
778 set_irn_mode(n, lowered_mode);
779 set_Load_mode(n, lowered_ls_mode);
783 * Transforms a Minus into the appropriate soft float function.
785 static void lower_Minus(ir_node *n)
788 ir_node *block = get_nodes_block(n);
789 ir_node *call_result = NULL;
790 dbg_info *dbgi = get_irn_dbg_info(n);
791 ir_graph *irg = get_irn_irg(n);
792 ir_mode *mode = get_irn_mode(n);
793 ir_node *op = get_Minus_op(n);
795 if (! mode_is_float(mode))
798 symconst = create_softfloat_symconst(n, "neg");
801 ir_node *call_results;
802 ir_node *in[1] = {op};
803 ir_node *nomem = get_irg_no_mem(irg);
804 ir_type *type = get_softfloat_type(n);
805 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
807 call = new_rd_Call(dbgi, block, nomem, symconst, 1, in, type);
808 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
809 call_result = new_r_Proj(call_results, res_mode, 0);
811 exchange(n, call_result);
815 * Transforms a Mul into the appropriate soft float function.
817 static void lower_Mul(ir_node *n)
820 ir_node *block = get_nodes_block(n);
821 ir_node *call_result = NULL;
822 dbg_info *dbgi = get_irn_dbg_info(n);
823 ir_graph *irg = get_irn_irg(n);
824 ir_node *left = get_Mul_left(n);
825 ir_mode *mode = get_irn_mode(n);
826 ir_node *right = get_Mul_right(n);
828 if (! mode_is_float(mode))
831 symconst = create_softfloat_symconst(n, "mul");
834 ir_node *call_results;
835 ir_node *in[2] = {left, right};
836 ir_node *nomem = get_irg_no_mem(irg);
837 ir_type *type = get_softfloat_type(n);
838 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
840 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
841 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
842 call_result = new_r_Proj(call_results, res_mode, 0);
844 exchange(n, call_result);
848 * Transforms a Sub into the appropriate soft float function.
850 static void lower_Sub(ir_node *n)
853 ir_node *block = get_nodes_block(n);
854 ir_node *call_result = NULL;
855 dbg_info *dbgi = get_irn_dbg_info(n);
856 ir_graph *irg = get_irn_irg(n);
857 ir_node *left = get_Sub_left(n);
858 ir_mode *mode = get_irn_mode(n);
859 ir_node *right = get_Sub_right(n);
861 if (! mode_is_float(mode))
864 symconst = create_softfloat_symconst(n, "sub");
867 ir_node *call_results;
868 ir_node *in[2] = {left, right};
869 ir_node *nomem = get_irg_no_mem(irg);
870 ir_type *type = get_softfloat_type(n);
871 ir_mode *res_mode = get_type_mode(get_method_res_type(type, 0));
873 call = new_rd_Call(dbgi, block, nomem, symconst, 2, in, type);
874 call_results = new_r_Proj(call, mode_T, pn_Call_T_result);
875 call_result = new_r_Proj(call_results, res_mode, 0);
877 exchange(n, call_result);
881 * Enter a lowering function into an ir_op.
883 static void ir_register_softloat_lower_function(ir_op *op, lower_softfloat_func func)
885 op->ops.generic = (op_func)func;
889 * Initializes softfloat lowering.
891 static void ir_prepare_softfloat_lowering(void)
893 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
896 lowered_type = pmap_create();
899 binop_tp_d = new_type_method(2, 1);
900 set_method_param_type(binop_tp_d, 0, get_type_for_mode(mode_D));
901 set_method_param_type(binop_tp_d, 1, get_type_for_mode(mode_D));
902 set_method_res_type(binop_tp_d, 0, get_type_for_mode(mode_D));
906 binop_tp_f = new_type_method(2, 1);
907 set_method_param_type(binop_tp_f, 0, get_type_for_mode(mode_F));
908 set_method_param_type(binop_tp_f, 1, get_type_for_mode(mode_F));
909 set_method_res_type(binop_tp_f, 0, get_type_for_mode(mode_F));
913 cmp_tp_d = new_type_method(2, 1);
914 set_method_param_type(cmp_tp_d, 0, get_type_for_mode(mode_D));
915 set_method_param_type(cmp_tp_d, 1, get_type_for_mode(mode_D));
916 set_method_res_type(cmp_tp_d, 0, get_type_for_mode(mode_Is));
920 cmp_tp_f = new_type_method(2, 1);
921 set_method_param_type(cmp_tp_f, 0, get_type_for_mode(mode_F));
922 set_method_param_type(cmp_tp_f, 1, get_type_for_mode(mode_F));
923 set_method_res_type(cmp_tp_f, 0, get_type_for_mode(mode_Is));
927 unop_tp_d = new_type_method(1, 1);
928 set_method_param_type(unop_tp_d, 0, get_type_for_mode(mode_D));
929 set_method_res_type(unop_tp_d, 0, get_type_for_mode(mode_D));
933 unop_tp_f = new_type_method(1, 1);
934 set_method_param_type(unop_tp_f, 0, get_type_for_mode(mode_F));
935 set_method_res_type(unop_tp_f, 0, get_type_for_mode(mode_F));
939 unop_tp_d_f = new_type_method(1, 1);
940 set_method_param_type(unop_tp_d_f, 0, get_type_for_mode(mode_D));
941 set_method_res_type(unop_tp_d_f, 0, get_type_for_mode(mode_F));
944 if (! unop_tp_d_is) {
945 unop_tp_d_is = new_type_method(1, 1);
946 set_method_param_type(unop_tp_d_is, 0, get_type_for_mode(mode_D));
947 set_method_res_type(unop_tp_d_is, 0, get_type_for_mode(mode_Is));
950 if (! unop_tp_d_iu) {
951 unop_tp_d_iu = new_type_method(1, 1);
952 set_method_param_type(unop_tp_d_iu, 0, get_type_for_mode(mode_D));
953 set_method_res_type(unop_tp_d_iu, 0, get_type_for_mode(mode_Iu));
956 if (! unop_tp_d_ls) {
957 unop_tp_d_ls = new_type_method(1, 1);
958 set_method_param_type(unop_tp_d_ls, 0, get_type_for_mode(mode_D));
959 set_method_res_type(unop_tp_d_ls, 0, get_type_for_mode(mode_Ls));
962 if (! unop_tp_d_lu) {
963 unop_tp_d_lu = new_type_method(1, 1);
964 set_method_param_type(unop_tp_d_lu, 0, get_type_for_mode(mode_D));
965 set_method_res_type(unop_tp_d_lu, 0, get_type_for_mode(mode_Lu));
969 unop_tp_f_d = new_type_method(1, 1);
970 set_method_param_type(unop_tp_f_d, 0, get_type_for_mode(mode_F));
971 set_method_res_type(unop_tp_f_d, 0, get_type_for_mode(mode_D));
974 if (! unop_tp_f_is) {
975 unop_tp_f_is = new_type_method(1, 1);
976 set_method_param_type(unop_tp_f_is, 0, get_type_for_mode(mode_F));
977 set_method_res_type(unop_tp_f_is, 0, get_type_for_mode(mode_Is));
980 if (! unop_tp_f_iu) {
981 unop_tp_f_iu = new_type_method(1, 1);
982 set_method_param_type(unop_tp_f_iu, 0, get_type_for_mode(mode_F));
983 set_method_res_type(unop_tp_f_iu, 0, get_type_for_mode(mode_Iu));
986 if (! unop_tp_f_ls) {
987 unop_tp_f_ls = new_type_method(1, 1);
988 set_method_param_type(unop_tp_f_ls, 0, get_type_for_mode(mode_F));
989 set_method_res_type(unop_tp_f_ls, 0, get_type_for_mode(mode_Ls));
992 if (! unop_tp_f_lu) {
993 unop_tp_f_lu = new_type_method(1, 1);
994 set_method_param_type(unop_tp_f_lu, 0, get_type_for_mode(mode_F));
995 set_method_res_type(unop_tp_f_lu, 0, get_type_for_mode(mode_Lu));
998 if (! unop_tp_is_d) {
999 unop_tp_is_d = new_type_method(1, 1);
1000 set_method_param_type(unop_tp_is_d, 0, get_type_for_mode(mode_Is));
1001 set_method_res_type(unop_tp_is_d, 0, get_type_for_mode(mode_D));
1004 if (! unop_tp_is_f) {
1005 unop_tp_is_f = new_type_method(1, 1);
1006 set_method_param_type(unop_tp_is_f, 0, get_type_for_mode(mode_Is));
1007 set_method_res_type(unop_tp_is_f, 0, get_type_for_mode(mode_F));
1010 if (! unop_tp_iu_d) {
1011 unop_tp_iu_d = new_type_method(1, 1);
1012 set_method_param_type(unop_tp_iu_d, 0, get_type_for_mode(mode_Iu));
1013 set_method_res_type(unop_tp_iu_d, 0, get_type_for_mode(mode_D));
1016 if (! unop_tp_iu_f) {
1017 unop_tp_iu_f = new_type_method(1, 1);
1018 set_method_param_type(unop_tp_iu_f, 0, get_type_for_mode(mode_Iu));
1019 set_method_res_type(unop_tp_iu_f, 0, get_type_for_mode(mode_F));
1022 if (! unop_tp_ls_d) {
1023 unop_tp_ls_d = new_type_method(1, 1);
1024 set_method_param_type(unop_tp_ls_d, 0, get_type_for_mode(mode_Ls));
1025 set_method_res_type(unop_tp_ls_d, 0, get_type_for_mode(mode_D));
1028 if (! unop_tp_ls_f) {
1029 unop_tp_ls_f = new_type_method(1, 1);
1030 set_method_param_type(unop_tp_ls_f, 0, get_type_for_mode(mode_Ls));
1031 set_method_res_type(unop_tp_ls_f, 0, get_type_for_mode(mode_F));
1034 if (! unop_tp_lu_d) {
1035 unop_tp_lu_d = new_type_method(1, 1);
1036 set_method_param_type(unop_tp_lu_d, 0, get_type_for_mode(mode_Lu));
1037 set_method_res_type(unop_tp_lu_d, 0, get_type_for_mode(mode_D));
1040 if (! unop_tp_lu_f) {
1041 unop_tp_lu_f = new_type_method(1, 1);
1042 set_method_param_type(unop_tp_lu_f, 0, get_type_for_mode(mode_Lu));
1043 set_method_res_type(unop_tp_lu_f, 0, get_type_for_mode(mode_F));
1048 * Callback to lower only the Mux nodes we created.
1050 static int lower_mux_cb(ir_node *mux)
1052 return ir_nodeset_contains(&created_mux_nodes, mux);
1055 void lower_floating_point(void)
1058 size_t n_irgs = get_irp_n_irgs();
1060 FIRM_DBG_REGISTER(dbg, "firm.lower.softfloat");
1062 ir_prepare_softfloat_lowering();
1064 ir_clear_opcodes_generic_func();
1065 ir_register_softloat_lower_function(op_Add, lower_Add);
1066 ir_register_softloat_lower_function(op_Cmp, lower_Cmp);
1067 ir_register_softloat_lower_function(op_Conv, lower_Conv);
1068 ir_register_softloat_lower_function(op_Div, lower_Div);
1069 ir_register_softloat_lower_function(op_Minus, lower_Minus);
1070 ir_register_softloat_lower_function(op_Mul, lower_Mul);
1071 ir_register_softloat_lower_function(op_Sub, lower_Sub);
1073 for (i = 0; i < n_irgs; ++i) {
1074 ir_graph *irg = get_irp_irg(i);
1076 ir_nodeset_init(&created_mux_nodes);
1080 irg_walk_graph(irg, NULL, lower_node, NULL);
1082 if (ir_nodeset_size(&created_mux_nodes) > 0)
1083 lower_mux(irg, lower_mux_cb);
1085 ir_nodeset_destroy(&created_mux_nodes);
1088 ir_clear_opcodes_generic_func();
1089 ir_register_softloat_lower_function(op_Call, lower_Call);
1090 ir_register_softloat_lower_function(op_Const, lower_Const);
1091 ir_register_softloat_lower_function(op_Div, lower_Div_mode);
1092 ir_register_softloat_lower_function(op_Load, lower_Load);
1094 for (i = 0; i < n_irgs; ++i) {
1095 ir_graph *irg = get_irp_irg(i);
1096 ir_entity *ent = get_irg_entity(irg);
1097 ir_type *mtp = get_entity_type(ent);
1098 ir_type *lowered_mtp = lower_method_type(mtp);
1099 ir_type *frame_tp = get_irg_frame_type(irg);
1103 if (lowered_mtp != mtp)
1104 set_entity_type(ent, lowered_mtp);
1106 irg_walk_graph(irg, NULL, lower_mode, NULL);
1108 /* fixup parameter entities */
1109 n_members = get_compound_n_members(frame_tp);
1110 for (i = 0; i < n_members; ++i) {
1111 ir_entity *member = get_compound_member(frame_tp, i);
1112 ir_type *type = get_entity_type(member);
1113 if (is_Primitive_type(type)) {
1114 ir_type *lowered = lower_type(type);
1115 set_entity_type(member, lowered);