irargs.c 7.92 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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
	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);
			}
			else
				snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
				get_mode_name(get_irn_mode(X)));
			snprintf(add, sizeof(add), "[%ld:%d]", get_irn_node_nr(X), get_irn_idx(X));
			}
			break;
	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);

			strncat(buf, ".", sizeof(buf));
			strncat(buf, get_entity_name(ent), sizeof(buf));
			if (is_Array_type(get_entity_owner(ent))) {
				snprintf(add, sizeof(add), "[%d]",
					get_compound_graph_path_array_index(X, i));
				strncat(buf, add, sizeof(buf));
			}
		}
		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)
		strncat(buf, add, sizeof(buf));

	return lc_arg_append(app, occ, buf, strlen(buf));
225
226
227
228
229
230
231

#undef A
}

/**
 * emit an ident
 */
Sebastian Hack's avatar
Sebastian Hack committed
232
233
static int firm_emit_ident(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
234
{
Michael Beck's avatar
Michael Beck committed
235
236
	ident *id = (ident *)arg->v_ptr;
	const char *p = id ? get_id_str(id) : "(null)";
237

Michael Beck's avatar
Michael Beck committed
238
	return lc_arg_append(app, occ, p, strlen(p));
239
240
}

241
242
243
/**
 * Emit indent.
 */
Sebastian Hack's avatar
Sebastian Hack committed
244
245
static int firm_emit_indent(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
246
247
{
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
248
249
	int width  = occ->width > 0 ? occ->width : 1;
	int amount = arg->v_int * width;
250

Michael Beck's avatar
Michael Beck committed
251
	for (i = 0; i < amount; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
252
		lc_appendable_chadd(app, (i % width) == 0 ? '|' : ' ');
253
254
255
256

	return amount;
}

257
258
259
/**
 * Emit pnc.
 */
Sebastian Hack's avatar
Sebastian Hack committed
260
261
static int firm_emit_pnc(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
262
{
Michael Beck's avatar
Michael Beck committed
263
264
	int value = arg->v_int;
	const char *p = get_pnc_string(value);
265

Michael Beck's avatar
Michael Beck committed
266
	return lc_arg_append(app, occ, p, strlen(p));
267
268
}

Sebastian Hack's avatar
Sebastian Hack committed
269
lc_arg_env_t *firm_get_arg_env(void)
270
271
{

Michael Beck's avatar
Michael Beck committed
272
	static lc_arg_env_t *env = NULL;
273

Michael Beck's avatar
Michael Beck committed
274
275
276
277
278
279
	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 };
280

Michael Beck's avatar
Michael Beck committed
281
282
283
284
	static struct {
		const char *name;
		char letter;
	} args[] = {
Sebastian Hack's avatar
Sebastian Hack committed
285
#define X(name, letter) {"firm:" name, letter}
Michael Beck's avatar
Michael Beck committed
286
287
288
289
290
291
292
293
294
295
		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
296
#undef X
Michael Beck's avatar
Michael Beck committed
297
	};
298

Michael Beck's avatar
Michael Beck committed
299
	size_t i;
300

Michael Beck's avatar
Michael Beck committed
301
302
303
	if (env == NULL) {
		env = lc_arg_new_env();
		lc_arg_add_std(env);
304

Michael Beck's avatar
Michael Beck committed
305
306
307
		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);
308

Michael Beck's avatar
Michael Beck committed
309
310
311
312
313
314
		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);
	}
315

Michael Beck's avatar
Michael Beck committed
316
	return env;
317
}