added function for convertion debug info
[libfirm] / ir / ir / irargs.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irargs.c
4  * Purpose:     Support for libcore IR object output.
5  * Author:      Sebastian Hack
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2005 Universitaet Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include "bitset.h"
18
19 #include <ctype.h>
20 #include <libcore/xprintf.h>
21
22 #include "firm_common.h"
23 #include "irnode_t.h"
24 #include "entity_t.h"
25 #include "irloop_t.h"
26 #include "tv_t.h"
27
28 /**
29  * identify a firm object type
30  */
31 static int firm_get_arg_type(const arg_occ_t *occ) {
32   /* Firm objects are always pointer */
33   return arg_type_ptr;
34 }
35
36 static int firm_get_arg_type_int(const arg_occ_t *occ) {
37   return arg_type_int;
38 }
39
40
41 static int bitset_get_arg_type(const arg_occ_t *occ) {
42   return arg_type_ptr;
43 }
44
45 static int bitset_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
46 {
47   int res = 2;
48   bitset_t *b = arg->v_ptr;
49   bitset_pos_t p;
50   char buf[32];
51   const char *prefix = "";
52
53   arg_append(app, occ, "[", 1);
54   for(p = bitset_next_set(b, 0); p != -1; p = bitset_next_set(b, p)) {
55     int n;
56
57     n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
58     arg_append(app, occ, buf, n);
59     prefix = ", ";
60     res += n;
61   }
62   arg_append(app, occ, "]", 1);
63
64   return res;
65 }
66
67 /**
68  * emit a Firm object
69  */
70 static int firm_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
71 {
72 #define A(s)    occ->flag_hash ? s " ": ""
73
74   void *X = arg->v_ptr;
75   firm_kind *obj = X;
76   int i, n;
77   ir_node *block;
78         char add[64];
79   char buf[256];
80   char tv[256];
81
82   buf[0] = '\0';
83   add[0] = '\0';
84
85   if (! X)
86     strncpy(buf, "(null)", sizeof(buf));
87   else {
88     switch (*obj) {
89     case k_BAD:
90       snprintf(buf, sizeof(buf), "BAD");
91       snprintf(add, sizeof(add), "[%p]", X);
92       break;
93     case k_entity:
94       snprintf(buf, sizeof(buf), "%s%s", A("ent"),
95           isupper(occ->conversion) ? get_entity_ld_name(X): get_entity_name(X));
96       snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
97       break;
98     case k_type:
99       snprintf(buf, sizeof(buf), "%s%s:%s", A("type"), get_type_tpop_name(X), get_type_name(X));
100       snprintf(add, sizeof(add), "[%ld]", get_type_nr(X));
101       break;
102     case k_ir_graph:
103       snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
104       snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
105       break;
106     case k_ir_node:
107       switch (occ->conversion) {
108       case 'B':
109         block = is_no_Block(X) ? get_nodes_block(X) : X;
110         snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(block),
111             get_mode_name(get_irn_mode(block)));
112         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(block));
113         break;
114       case 'N':
115         snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
116         break;
117       default:
118         if (is_Const(irn)) {
119           char tbuf[128];
120           tarval_snprintf(tv, sizeof(tv), X);
121           snprintf(buf, sizeof(buf), "%s%s%s<%s>", A("irn"), get_irn_opname(X),
122             get_mode_name(get_irn_mode(X)), tbuf);
123         }
124         else
125           snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
126             get_mode_name(get_irn_mode(X)));
127         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(X));
128       }
129       break;
130     case k_ir_mode:
131       snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
132       break;
133     case k_tarval:
134       tarval_snprintf(tv, sizeof(tv), X);
135       snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv);
136       break;
137     case k_ir_loop:
138       snprintf(buf, sizeof(buf), "ldepth[%d]", get_loop_depth(X));
139       break;
140     case k_ir_op:
141       snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
142       break;
143     case k_ir_compound_graph_path:
144       strncat(buf, A("cgp"), sizeof(buf));
145
146       n = get_compound_graph_path_length(X);
147       for (i = 0; i < n; ++i) {
148         entity *ent = get_compound_graph_path_node(X, i);
149         strncat(buf, get_entity_name(ent), sizeof(buf));
150         if (i < n - 1)
151           strncat(buf, ".", sizeof(buf));
152       }
153       break;
154     default:
155       snprintf(buf, sizeof(buf), "UNKWN");
156       snprintf(add, sizeof(add), "[%p]", X);
157     }
158   }
159
160   if(occ->flag_plus)
161         strncat(buf, add, sizeof(buf));
162
163   return arg_append(app, occ, buf, strlen(buf));
164
165 #undef A
166 }
167
168 /**
169  * emit an ident
170  */
171 static int firm_emit_ident(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
172 {
173   ident *id = (ident *)arg->v_ptr;
174   const char *p = id ? get_id_str(id) : "(null)";
175
176   return arg_append(app, occ, p, strlen(p));
177 }
178
179 /**
180  * Emit indent.
181  */
182 static int firm_emit_indent(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
183 {
184         int i;
185         int amount = arg->v_int;
186
187         for(i = 0; i < amount; ++i)
188                 appendable_chadd(app, ' ');
189
190         return amount;
191 }
192
193 /**
194  * Emit pnc.
195  */
196 static int firm_emit_pnc(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
197 {
198   int i;
199   int value = arg->v_int;
200   const char *p = get_pnc_string(value);
201
202   return arg_append(app, occ, p, strlen(p));
203 }
204
205 arg_env_t *firm_get_arg_env(void)
206 {
207 #define X(name, letter) {"firm:" name, letter}
208
209   static arg_env_t *env = NULL;
210
211   static arg_handler_t firm_handler   = { firm_get_arg_type, firm_emit };
212   static arg_handler_t ident_handler  = { firm_get_arg_type, firm_emit_ident };
213   static arg_handler_t indent_handler = { firm_get_arg_type_int, firm_emit_indent };
214   static arg_handler_t pnc_handler    = { firm_get_arg_type_int, firm_emit_pnc };
215   static arg_handler_t bitset_handler = { bitset_get_arg_type, bitset_emit };
216
217   static struct {
218     const char *name;
219     char letter;
220   } args[] = {
221     X("type",      't'),
222     X("entity",    'e'),
223     X("entity_ld", 'E'),
224     X("tarval",    'T'),
225     X("irn",       'n'),
226     X("op",        'O'),
227     X("irn_nr",    'N'),
228     X("mode",      'm'),
229     X("block",     'B'),
230     X("pnc",       '='),
231   };
232
233   int i;
234
235   if(env == NULL) {
236     env = arg_new_env();
237     arg_add_std(env);
238
239                 arg_register(env, "firm", 'F', &firm_handler);
240     for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
241       arg_register(env, args[i].name, args[i].letter, &firm_handler);
242
243     arg_register(env, "firm:ident", 'I', &ident_handler);
244                 arg_register(env, "firm:indent", 'D', &indent_handler);
245                 /* arg_register(env, "firm:bitset", 'b', &bitset_handler); */
246   }
247
248   return env;
249 }