irargs.c 8.29 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Matthias Braun's avatar
Matthias Braun committed
20
21
22
23
24
/**
 * @file
 * @brief    Support for libcore IR object output.
 * @author   Sebastian Hack
 * @version  $Id$
25
 */
Matthias Braun's avatar
Matthias Braun committed
26
#include "config.h"
27

28
29
#include "bitset.h"

30
31
#include <ctype.h>

Matthias Braun's avatar
Matthias Braun committed
32
#include "lc_printf.h"
33
#include "firm_common.h"
34
35
36
37
#include "irnode_t.h"
#include "entity_t.h"
#include "irloop_t.h"
#include "tv_t.h"
38
#include "dbginfo_t.h"
39
40
41
42

/**
 * identify a firm object type
 */
Sebastian Hack's avatar
Sebastian Hack committed
43
static int firm_get_arg_type(const lc_arg_occ_t *occ) {
Michael Beck's avatar
Michael Beck committed
44
45
46
	(void) occ;
	/* Firm objects are always pointer */
	return lc_arg_type_ptr;
47
48
}

Sebastian Hack's avatar
Sebastian Hack committed
49
static int firm_get_arg_type_int(const lc_arg_occ_t *occ) {
Michael Beck's avatar
Michael Beck committed
50
51
	(void) occ;
	return lc_arg_type_int;
52
53
}

54

Sebastian Hack's avatar
Sebastian Hack committed
55
static int bitset_get_arg_type(const lc_arg_occ_t *occ) {
Michael Beck's avatar
Michael Beck committed
56
57
	(void) occ;
	return lc_arg_type_ptr;
58
59
}

Sebastian Hack's avatar
Sebastian Hack committed
60
61
static int bitset_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
62
{
Michael Beck's avatar
Michael Beck committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	int res = 2;
	bitset_t *b = arg->v_ptr;
	bitset_pos_t p;
	char buf[32];
	const char *prefix = "";

	lc_arg_append(app, occ, "[", 1);
	bitset_foreach(b, p) {
		int n;

		n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
		lc_arg_append(app, occ, buf, n);
		prefix = ", ";
		res += n;
	}
	lc_arg_append(app, occ, "]", 1);

	return res;
81
82
}

83
84
85
/**
 * emit an opaque Firm dbg_info object
 */
Sebastian Hack's avatar
Sebastian Hack committed
86
87
static int firm_emit_dbg(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
88
{
Michael Beck's avatar
Michael Beck committed
89
90
91
92
93
94
95
96
97
98
	char buf[1024];
	ir_node *irn = arg->v_ptr;
	dbg_info *dbg = get_irn_dbg_info(irn);

	buf[0] = '\0';
	if (dbg && __dbg_info_snprint) {
		if (__dbg_info_snprint(buf, sizeof(buf), dbg) <= 0)
			buf[0] = '\0';
	}
	return lc_arg_append(app, occ, buf, strlen(buf));
99
100
}

101
102
103
/**
 * Beware: do not set the entity ld_name
 */
104
static const char *get_entity_ld_name_ex(ir_entity *ent) {
Michael Beck's avatar
Michael Beck committed
105
106
107
	if (ent->ld_name)
		return get_entity_ld_name(ent);
	return get_entity_name(ent);
108
109
}

110
111
112
/**
 * emit a Firm object
 */
Sebastian Hack's avatar
Sebastian Hack committed
113
114
static int firm_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
115
{
116
#define A(s)    occ->flag_hash ? s " ": ""
117

Michael Beck's avatar
Michael Beck committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
	void *X = arg->v_ptr;
	firm_kind *obj = X;
	int i, n;
	ir_node *block;
	char add[64];
	char buf[256];
	char tv_buf[256];
	ir_entity *ent;

	buf[0] = '\0';
	add[0] = '\0';

	if (! X)
		strncpy(buf, "(null)", sizeof(buf));
	else {
		switch (*obj) {
	case k_BAD:
		snprintf(buf, sizeof(buf), "BAD");
		snprintf(add, sizeof(add), "[%p]", X);
		break;
	case k_entity:
		snprintf(buf, sizeof(buf), "%s%s", A("ent"),
			isupper(occ->conversion) ? get_entity_ld_name_ex(X): get_entity_name(X));
		snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
		break;
	case k_type:
		snprintf(buf, sizeof(buf), "%s%s:%s", A("type"), get_type_tpop_name(X), get_type_name(X));
		snprintf(add, sizeof(add), "[%ld]", get_type_nr(X));
		break;
	case k_ir_graph:
		if (X == get_const_code_irg())
			snprintf(buf, sizeof(buf), "%s<ConstCodeIrg>", A("irg"));
		else
			snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
		snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
		break;
	case k_ir_node:
		switch (occ->conversion) {
		case 'B':
			block = is_no_Block(X) ? get_nodes_block(X) : X;
			snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(block),
				get_mode_name(get_irn_mode(block)));
			snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(block));
			break;
		case 'N':
			snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
			break;
		default:
			if (is_Const(X)) {
				tarval *tv = get_Const_tarval(X);
				if (tv)
					tarval_snprintf(tv_buf, sizeof(tv_buf), tv);
				else
					strncpy(tv_buf, "(NULL)", sizeof(tv_buf));
				snprintf(buf, sizeof(buf), "%s%s%s<%s>", A("irn"), get_irn_opname(X),
					get_mode_name(get_irn_mode(X)), tv_buf);
174
175
176
177
178
179
180
			} else if (is_SymConst_addr_ent(X)) {
				snprintf(buf, sizeof(buf), "%s%s%s[%s]", A("irn"), get_irn_opname(X),
				get_mode_name(get_irn_mode(X)), get_entity_name(get_SymConst_entity(X)));
			} else if (is_Sel(X)) {
				snprintf(buf, sizeof(buf), "%s%s%s[%s]", A("irn"), get_irn_opname(X),
				get_mode_name(get_irn_mode(X)), get_entity_name(get_Sel_entity(X)));
			} else {
Michael Beck's avatar
Michael Beck committed
181
182
183
				snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
				get_mode_name(get_irn_mode(X)));
			}
184
185
186
			snprintf(add, sizeof(add), "[%ld:%d]", get_irn_node_nr(X), get_irn_idx(X));
		}
		break;
Michael Beck's avatar
Michael Beck committed
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
	case k_ir_mode:
		snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
		break;
	case k_tarval:
		tarval_snprintf(tv_buf, sizeof(tv_buf), X);
		snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv_buf);
		break;
	case k_ir_loop:
		snprintf(buf, sizeof(buf), "loop[%d:%d]", get_loop_loop_nr(X), get_loop_depth(X));
		break;
	case k_ir_op:
		snprintf(buf, sizeof(buf), "%s%s", A("op"), get_op_name(X));
		break;
	case k_ir_compound_graph_path:
		n = get_compound_graph_path_length(X);

		for (i = 0; i < n; ++i) {
			ent = get_compound_graph_path_node(X, i);

206
207
			strncat(buf, ".", sizeof(buf)-1);
			strncat(buf, get_entity_name(ent), sizeof(buf)-1);
Michael Beck's avatar
Michael Beck committed
208
209
210
			if (is_Array_type(get_entity_owner(ent))) {
				snprintf(add, sizeof(add), "[%d]",
					get_compound_graph_path_array_index(X, i));
211
				strncat(buf, add, sizeof(buf)-1);
Michael Beck's avatar
Michael Beck committed
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
			}
		}
		add[0] = '\0';
		break;
	case k_ir_extblk:
		snprintf(buf, sizeof(buf), "ExtBlock");
		snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(get_extbb_leader(X)));
		break;

	default:
		snprintf(buf, sizeof(buf), "UNKWN");
		snprintf(add, sizeof(add), "[%p]", X);
		}
	}

	if (occ->flag_plus)
228
		strncat(buf, add, sizeof(buf)-1);
Michael Beck's avatar
Michael Beck committed
229
230

	return lc_arg_append(app, occ, buf, strlen(buf));
231
232
233
234
235
236
237

#undef A
}

/**
 * emit an ident
 */
Sebastian Hack's avatar
Sebastian Hack committed
238
239
static int firm_emit_ident(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
240
{
Michael Beck's avatar
Michael Beck committed
241
242
	ident *id = (ident *)arg->v_ptr;
	const char *p = id ? get_id_str(id) : "(null)";
243

Michael Beck's avatar
Michael Beck committed
244
	return lc_arg_append(app, occ, p, strlen(p));
245
246
}

247
248
249
/**
 * Emit indent.
 */
Sebastian Hack's avatar
Sebastian Hack committed
250
251
static int firm_emit_indent(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
252
253
{
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
254
255
	int width  = occ->width > 0 ? occ->width : 1;
	int amount = arg->v_int * width;
256

Michael Beck's avatar
Michael Beck committed
257
	for (i = 0; i < amount; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
258
		lc_appendable_chadd(app, (i % width) == 0 ? '|' : ' ');
259
260
261
262

	return amount;
}

263
264
265
/**
 * Emit pnc.
 */
Sebastian Hack's avatar
Sebastian Hack committed
266
267
static int firm_emit_pnc(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
268
{
Michael Beck's avatar
Michael Beck committed
269
270
	int value = arg->v_int;
	const char *p = get_pnc_string(value);
271

Michael Beck's avatar
Michael Beck committed
272
	return lc_arg_append(app, occ, p, strlen(p));
273
274
}

Sebastian Hack's avatar
Sebastian Hack committed
275
lc_arg_env_t *firm_get_arg_env(void)
276
277
{

Michael Beck's avatar
Michael Beck committed
278
	static lc_arg_env_t *env = NULL;
279

Michael Beck's avatar
Michael Beck committed
280
281
282
283
284
285
	static lc_arg_handler_t firm_handler   = { firm_get_arg_type, firm_emit };
	static lc_arg_handler_t ident_handler  = { firm_get_arg_type, firm_emit_ident };
	static lc_arg_handler_t indent_handler = { firm_get_arg_type_int, firm_emit_indent };
	static lc_arg_handler_t pnc_handler    = { firm_get_arg_type_int, firm_emit_pnc };
	static lc_arg_handler_t bitset_handler = { bitset_get_arg_type, bitset_emit };
	static lc_arg_handler_t debug_handler  = { firm_get_arg_type, firm_emit_dbg };
286

Michael Beck's avatar
Michael Beck committed
287
288
289
290
	static struct {
		const char *name;
		char letter;
	} args[] = {
Sebastian Hack's avatar
Sebastian Hack committed
291
#define X(name, letter) {"firm:" name, letter}
Michael Beck's avatar
Michael Beck committed
292
293
294
295
296
297
298
299
300
301
		X("type",      't'),
		X("entity",    'e'),
		X("entity_ld", 'E'),
		X("tarval",    'T'),
		X("irn",       'n'),
		X("op",        'O'),
		X("irn_nr",    'N'),
		X("mode",      'm'),
		X("block",     'B'),
		X("cg_path",   'P'),
Sebastian Hack's avatar
Sebastian Hack committed
302
#undef X
Michael Beck's avatar
Michael Beck committed
303
	};
304

Michael Beck's avatar
Michael Beck committed
305
	size_t i;
306

Michael Beck's avatar
Michael Beck committed
307
308
309
	if (env == NULL) {
		env = lc_arg_new_env();
		lc_arg_add_std(env);
310

Michael Beck's avatar
Michael Beck committed
311
312
313
		lc_arg_register(env, "firm", 'F', &firm_handler);
		for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
			lc_arg_register(env, args[i].name, args[i].letter, &firm_handler);
314

Michael Beck's avatar
Michael Beck committed
315
316
317
318
319
320
		lc_arg_register(env, "firm:ident",    'I', &ident_handler);
		lc_arg_register(env, "firm:indent",   'D', &indent_handler);
		lc_arg_register(env, "firm:dbg_info", 'G', &debug_handler);
		lc_arg_register(env, "firm:bitset",   'B', &bitset_handler);
		lc_arg_register(env, "firm:pnc",      '=', &pnc_handler);
	}
321

Michael Beck's avatar
Michael Beck committed
322
	return env;
323
}