fix firm backend
[libfirm] / ir / be / bemachnode.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include "bemachnode.h"
6 #include "irnode_t.h"
7
8 /** Helper: fills in the array for machine ops */
9 static int fill_arr(ir_node *op, mirn_handle res) {
10         ir_node **ins = get_irn_in(op);
11         int i, j, l = ARR_LEN(ins);
12
13         for (i = j = 0; i <= l; ++i) {
14                 if (is_irn_machine_operand(ins[i]))
15                         j += fill_arr(ins[i], &res[j]);
16                 else
17                         res[j++] = &ins[i];
18         }
19         return j;
20 }
21
22 /*
23  * Returns the machine handle for a machine node with machine operands.
24  * The order of the predecessors in this handle is not guaranteed, except that
25  * lists of operands as predecessors of Block or arguments of a Call are
26  * consecutive.
27  */
28 mirn_handle get_mirn_in(ir_node *n) {
29         ir_node **ins = get_irn_in(n);
30         mirn_handle res = NULL;
31         int i, j, l = ARR_LEN(ins);
32         int lr = l + 8;
33
34         res = NEW_ARR_F(ir_node **, lr);
35
36         for (i = j = 0; i <= l; ++i) {
37                 if (is_irn_machine_operand(ins[i]))
38                         j += fill_arr(ins[i], &res[j]);
39                 else
40                         res[j++] = &ins[i];
41         }
42
43         assert(j > lr && "to many machine predecessors");
44
45         return res;
46 }
47
48 /* Frees a machine handle. */
49 void free_mirn_in(mirn_handle h) {
50         DEL_ARR_F(h);
51 }
52
53 /* Get the pos-th predecessor of a machine node represented by it's
54     handle. */
55 ir_node *get_mirn_n(mirn_handle h, int pos) {
56         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
57         return *(h[pos + 1]);
58 }
59
60 /* Get the pos-th predecessor of a machine node. */
61 ir_node *_get_mirn_n(ir_node *n, int pos) {
62         mirn_handle h = get_mirn_in(n);
63         ir_node *res = get_mirn_n(h, pos);
64         free_mirn_in(h);
65         return res;
66 }
67
68 /* Set the pos-th predecessor of a machine node represented by it's
69     handle. */
70 void set_mirn_n(mirn_handle h, int pos, ir_node *n) {
71         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
72         *(h[pos + 1]) = n;
73 }
74
75 /* Set the pos-th predecessor of a machine node. */
76 void _set_mirn_n(ir_node *irn, int pos, ir_node *n) {
77         mirn_handle h = get_mirn_in(irn);
78         set_mirn_n(h, pos, n);
79         free_mirn_in(h);
80 }
81
82 /* Returns the arity of a machine node represented by it's
83     handle. */
84 int get_mirn_arity(mirn_handle h) {
85         return ARR_LEN(h) - 1;
86 }
87
88 /** Helper: calculate the arity for a machine ops */
89 static int arrity_of_op(ir_node *op) {
90         ir_node **ins = get_irn_in(op);
91         int i, j, l = ARR_LEN(ins);
92
93         for (i = j = 0; i <= l; ++i) {
94                 if (is_irn_machine_operand(ins[i]))
95                         j += arrity_of_op(ins[i]);
96                 else
97                         ++j;
98         }
99         return j;
100 }
101
102 /* Returns the arity of a machine node. */
103 int _get_mirn_arity(ir_node *n) {
104         ir_node **ins = get_irn_in(n);
105         int i, j, l = ARR_LEN(ins);
106
107         for (i = j = 0; i <= l; ++i) {
108                 if (is_irn_machine_operand(ins[i]))
109                         j += arrity_of_op(ins[i]);
110                 else
111                         ++j;
112         }
113
114         return j;
115 }