use tv_t.h instead of tv.h
[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 Universit�t 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 <ctype.h>
18 #include <libcore/xprintf.h>
19
20 #include "firm_common.h"
21 #include "irnode_t.h"
22 #include "entity_t.h"
23 #include "irloop_t.h"
24 #include "tv_t.h"
25
26 /**
27  * identify a firm object type
28  */
29 static int firm_get_arg_type(const arg_occ_t *occ) {
30   /* Firm objects are always pointer */
31   return arg_type_ptr;
32 }
33
34 static int firm_get_arg_type_int(const arg_occ_t *occ) {
35   return arg_type_int;
36 }
37
38 /**
39  * emit a Firm object
40  */
41 static int firm_emit(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
42 {
43 #define A(s)    occ->flag_hash ? s " ": ""
44
45   void *X = arg->v_ptr;
46   firm_kind *obj = X;
47   int i, n;
48   ir_node *block;
49         char add[64];
50   char buf[256];
51   char tv[256];
52
53   buf[0] = '\0';
54   add[0] = '\0';
55
56   if (! X)
57     strncpy(buf, "(null)", sizeof(buf));
58   else {
59     switch (*obj) {
60     case k_BAD:
61       snprintf(buf, sizeof(buf), "BAD");
62       snprintf(add, sizeof(add), "[%p]", X);
63       break;
64     case k_entity:
65       snprintf(buf, sizeof(buf), "%s%s", A("ent"),
66           isupper(occ->conversion) ? get_entity_ld_name(X): get_entity_name(X));
67       snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
68       break;
69     case k_type:
70       snprintf(buf, sizeof(buf), "%s%s:%s", A("type"), get_type_tpop_name(X), get_type_name(X));
71       snprintf(add, sizeof(add), "[%ld]", get_type_nr(X));
72       break;
73     case k_ir_graph:
74       snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
75       snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
76       break;
77     case k_ir_node:
78       switch (occ->conversion) {
79       case 'B':
80         block = is_no_Block(X) ? get_nodes_block(X) : X;
81         snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(block),
82             get_mode_name(get_irn_mode(block)));
83         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(block));
84         break;
85       case 'N':
86         snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
87         break;
88       default:
89         snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
90             get_mode_name(get_irn_mode(X)));
91         snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(X));
92       }
93       break;
94     case k_ir_mode:
95       snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
96       break;
97     case k_tarval:
98       tarval_snprintf(tv, sizeof(tv), X);
99       snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv);
100       break;
101     case k_ir_loop:
102       snprintf(buf, sizeof(buf), "ldepth[%d]", get_loop_depth(X));
103       break;
104     case k_ir_op:
105       snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
106       break;
107     case k_ir_compound_graph_path:
108       strncat(buf, A("cgp"), sizeof(buf));
109
110       n = get_compound_graph_path_length(X);
111       for (i = 0; i < n; ++i) {
112         entity *ent = get_compound_graph_path_node(X, i);
113         strncat(buf, get_entity_name(ent), sizeof(buf));
114         if (i < n - 1)
115           strncat(buf, ".", sizeof(buf));
116       }
117       break;
118     default:
119       snprintf(buf, sizeof(buf), "UNKWN");
120       snprintf(add, sizeof(add), "[%p]", X);
121     }
122   }
123
124   if(occ->flag_plus)
125         strncat(buf, add, sizeof(buf));
126
127   return arg_append(app, occ, buf, strlen(buf));
128
129 #undef A
130 }
131
132 /**
133  * emit an ident
134  */
135 static int firm_emit_ident(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
136 {
137   ident *id = (ident *)arg->v_ptr;
138   const char *p = id ? get_id_str(id) : "(null)";
139
140   return arg_append(app, occ, p, strlen(p));
141 }
142
143
144
145 /**
146  * Emit indent.
147  */
148 static int firm_emit_indent(appendable_t *app, const arg_occ_t *occ, const arg_value_t *arg)
149 {
150         int i;
151         int amount = arg->v_int;
152
153         for(i = 0; i < amount; ++i)
154                 appendable_chadd(app, ' ');
155
156         return amount;
157 }
158
159 arg_env_t *firm_get_arg_env(void)
160 {
161 #define X(name, letter) {"firm:" name, letter}
162
163   static arg_env_t *env = NULL;
164
165   static arg_handler_t firm_handler   = { firm_get_arg_type, firm_emit };
166   static arg_handler_t ident_handler  = { firm_get_arg_type, firm_emit_ident };
167   static arg_handler_t indent_handler = { firm_get_arg_type_int, firm_emit_indent };
168
169   static struct {
170     const char *name;
171     char letter;
172   } args[] = {
173     X("type",      't'),
174     X("entity",    'e'),
175     X("entity_ld", 'E'),
176     X("tarval",    'T'),
177     X("irn",       'n'),
178     X("op",        'O'),
179     X("irn_nr",    'N'),
180     X("mode",      'm'),
181     X("block",     'B'),
182   };
183
184   int i;
185
186   if(env == NULL) {
187     env = arg_new_env();
188     arg_add_std(env);
189
190                 arg_register(env, "firm", 'F', &firm_handler);
191     for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
192       arg_register(env, args[i].name, args[i].letter, &firm_handler);
193
194     arg_register(env, "firm:ident", 'I', &ident_handler);
195                 arg_register(env, "firm:indent", 'D', &indent_handler);
196   }
197
198   return env;
199 }