we don't need no stinking selfs
[libfirm] / ir / be / bemachnode.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
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.
10  *
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.
14  *
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
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       Support for machine nodes with machine operands.
23  * @author      Michael Beck
24  * @version     $Id$
25  */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "bemachnode.h"
31 #include "irnode_t.h"
32
33 /** Helper: fills in the array for machine ops */
34 static int fill_arr(ir_node *op, mirn_handle res) {
35         ir_node **ins = get_irn_in(op);
36         int i, j, l = ARR_LEN(ins);
37
38         for (i = j = 0; i <= l; ++i) {
39                 if (is_irn_machine_operand(ins[i]))
40                         j += fill_arr(ins[i], &res[j]);
41                 else
42                         res[j++] = &ins[i];
43         }
44         return j;
45 }
46
47 /*
48  * Returns the machine handle for a machine node with machine operands.
49  * The order of the predecessors in this handle is not guaranteed, except that
50  * lists of operands as predecessors of Block or arguments of a Call are
51  * consecutive.
52  */
53 mirn_handle get_mirn_in(ir_node *n) {
54         ir_node **ins = get_irn_in(n);
55         mirn_handle res = NULL;
56         int i, j, l = ARR_LEN(ins);
57         int lr = l + 8;
58
59         res = NEW_ARR_F(ir_node **, lr);
60
61         for (i = j = 0; i <= l; ++i) {
62                 if (is_irn_machine_operand(ins[i]))
63                         j += fill_arr(ins[i], &res[j]);
64                 else
65                         res[j++] = &ins[i];
66         }
67
68         assert(j > lr && "to many machine predecessors");
69
70         return res;
71 }
72
73 /* Frees a machine handle. */
74 void free_mirn_in(mirn_handle h) {
75         DEL_ARR_F(h);
76 }
77
78 /* Get the pos-th predecessor of a machine node represented by it's
79     handle. */
80 ir_node *get_mirn_n(mirn_handle h, int pos) {
81         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
82         return *(h[pos + 1]);
83 }
84
85 /* Get the pos-th predecessor of a machine node. */
86 ir_node *_get_mirn_n(ir_node *n, int pos) {
87         mirn_handle h = get_mirn_in(n);
88         ir_node *res = get_mirn_n(h, pos);
89         free_mirn_in(h);
90         return res;
91 }
92
93 /* Set the pos-th predecessor of a machine node represented by it's
94     handle. */
95 void set_mirn_n(mirn_handle h, int pos, ir_node *n) {
96         assert(-1 <= pos && pos < ARR_LEN(h) - 1);
97         *(h[pos + 1]) = n;
98 }
99
100 /* Set the pos-th predecessor of a machine node. */
101 void _set_mirn_n(ir_node *irn, int pos, ir_node *n) {
102         mirn_handle h = get_mirn_in(irn);
103         set_mirn_n(h, pos, n);
104         free_mirn_in(h);
105 }
106
107 /* Returns the arity of a machine node represented by it's
108     handle. */
109 int get_mirn_arity(mirn_handle h) {
110         return ARR_LEN(h) - 1;
111 }
112
113 /** Helper: calculate the arity for a machine ops */
114 static int arrity_of_op(ir_node *op) {
115         ir_node **ins = get_irn_in(op);
116         int i, j, l = ARR_LEN(ins);
117
118         for (i = j = 0; i <= l; ++i) {
119                 if (is_irn_machine_operand(ins[i]))
120                         j += arrity_of_op(ins[i]);
121                 else
122                         ++j;
123         }
124         return j;
125 }
126
127 /* Returns the arity of a machine node. */
128 int _get_mirn_arity(ir_node *n) {
129         ir_node **ins = get_irn_in(n);
130         int i, j, l = ARR_LEN(ins);
131
132         for (i = j = 0; i <= l; ++i) {
133                 if (is_irn_machine_operand(ins[i]))
134                         j += arrity_of_op(ins[i]);
135                 else
136                         ++j;
137         }
138
139         return j;
140 }