Add temporary fix for conv-problems
[libfirm] / ir / be / bedump_minir.c
1 /*
2  * Copyright (C) 2010 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       Dump MinIR format for register coalescing
23  * @author      Matthias Braun
24  * @version     $Id$
25  */
26 #include "config.h"
27
28 #include <stdbool.h>
29
30 #include "irgwalk.h"
31 #include "bearch.h"
32
33 static const arch_env_t *arch_env;
34 static FILE             *out;
35 static int               indent;
36 static int               item_indent_add;
37 static bool              had_list_item;
38 static bool              no_newline;
39
40 static void newline(void)
41 {
42         int i;
43
44         if (no_newline) {
45                 no_newline = false;
46                 return;
47         }
48
49         fputc('\n', out);
50         for (i = 0; i < indent + item_indent_add; ++i) {
51                 fputs("  ", out);
52         }
53 }
54
55 static void begin_key(const char *name)
56 {
57         newline();
58         fprintf(out, "%s: ", name);
59 }
60
61 static void end_key(const char *name)
62 {
63         /* TODO verify */
64         (void) name;
65 }
66
67 static void begin_block_sequence(const char *name)
68 {
69         begin_key(name);
70         indent++;
71 }
72
73 static void end_block_sequence(const char *name)
74 {
75         end_key(name);
76         indent--;
77         item_indent_add = 0;
78 }
79
80 static void block_sequence_item(void)
81 {
82         item_indent_add = 0;
83         newline();
84         fputs("- ", out);
85         item_indent_add = 1;
86         no_newline = true;
87 }
88
89 static void begin_mapping(const char *name)
90 {
91         begin_key(name);
92         indent++;
93 }
94
95 static void end_maping(const char *name)
96 {
97         end_key(name);
98         indent--;
99 }
100
101 static void value(const char *val)
102 {
103         fputs(val, out);
104 }
105
106 static void key_value(const char *name, const char *val)
107 {
108         begin_key(name);
109         value(val);
110         end_key(name);
111 }
112
113 static void begin_list(const char *name)
114 {
115         begin_key(name);
116         fputs("[", out);
117         had_list_item = false;
118 }
119
120 static void end_list(const char *name)
121 {
122         /* TODO: verify that we started a list */
123         fputs("]", out);
124         end_key(name);
125 }
126
127 static void list_item(void)
128 {
129         if (had_list_item)
130                 fputs(", ", out);
131         had_list_item = true;
132 }
133
134 static void list_item_value(const char *val)
135 {
136         list_item();
137         value(val);
138 }
139
140 static void print_regclasses(void)
141 {
142         int n_classes = arch_env_get_n_reg_class(arch_env);
143         int c;
144
145         begin_block_sequence("regclasses");
146         for (c = 0; c < n_classes; ++c) {
147                 int                          n_regs;
148                 int                          r;
149                 const arch_register_class_t *cls = arch_env_get_reg_class(arch_env, c);
150                 if (arch_register_class_flags(cls) & arch_register_class_flag_manual_ra)
151                         continue;
152
153                 n_regs = arch_register_class_n_regs(cls);
154
155                 block_sequence_item();
156
157                 key_value("name", cls->name);
158                 begin_list("registers");
159                 for (r = 0; r < n_regs; ++r) {
160                         const arch_register_t *reg = arch_register_for_index(cls, r);
161                         list_item_value(reg->name);
162                 }
163                 end_list("registers");
164
165                 begin_mapping("flags");
166                         for (r = 0; r < n_regs; ++r) {
167                                 const arch_register_t *reg  = arch_register_for_index(cls, r);
168                                 unsigned               type = reg->type;
169                                 if (type & arch_register_type_ignore) {
170                                         begin_list(reg->name);
171                                         list_item_value("reserved");
172                                         list_item_value("nossa"); /* do we need this? */
173                                         end_list(reg->name);
174                                 }
175                         }
176                 end_maping("flags");
177         }
178         end_block_sequence("regclasses");
179 }
180
181 static void dump_block(ir_node *block, void *data)
182 {
183         ir_graph *irg = get_irn_irg(block);
184         (void) data;
185
186         block_sequence_item();
187         if (block == get_irg_start_block(irg)) {
188                 key_value("label", "start");
189         } else if (block == get_irg_end_block(irg)) {
190                 key_value("label", "end");
191         } else {
192                 char name[128];
193                 snprintf(name, sizeof(name), "bb%ld", get_irn_node_nr(block));
194                 key_value("label", name);
195         }
196
197         begin_block_sequence("ops");
198         end_block_sequence("ops");
199 }
200
201 static void print_function(ir_graph *irg)
202 {
203         ir_entity *entity = get_irg_entity(irg);
204
205         block_sequence_item();
206
207         key_value("label", get_entity_name(entity));
208         begin_list("entries"); list_item_value("start"); end_list("entries");
209         begin_list("exit"); list_item_value("end"); end_list("entries");
210
211         begin_block_sequence("bbs");
212         irg_block_walk_graph(irg, dump_block, NULL, NULL);
213         end_block_sequence("bbs");
214 }
215
216 void be_export_minir(const arch_env_t *new_arch_env, FILE *new_out, ir_graph *irg)
217 {
218         arch_env = new_arch_env;
219         out      = new_out;
220
221         no_newline = true;
222
223         print_regclasses();
224
225         begin_block_sequence("functions");
226         print_function(irg);
227         end_block_sequence("functions");
228
229         assert(indent == 0);
230         fputs("\n", out);
231
232 }