irargs.c 8.46 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
 *
 * 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
26
27
28
29
 */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

Matthias Braun's avatar
Matthias Braun committed
30
31
#include "firm_config.h"

32
33
#ifdef WITH_LIBCORE

34
35
#include "bitset.h"

36
#include <ctype.h>
Sebastian Hack's avatar
Sebastian Hack committed
37
#include <libcore/lc_printf.h>
38
39

#include "firm_common.h"
40
41
42
43
#include "irnode_t.h"
#include "entity_t.h"
#include "irloop_t.h"
#include "tv_t.h"
44
#include "dbginfo_t.h"
45
46
47
48

/**
 * identify a firm object type
 */
Sebastian Hack's avatar
Sebastian Hack committed
49
static int firm_get_arg_type(const lc_arg_occ_t *occ) {
50
  (void) occ;
51
  /* Firm objects are always pointer */
Sebastian Hack's avatar
Sebastian Hack committed
52
  return lc_arg_type_ptr;
53
54
}

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

60

Sebastian Hack's avatar
Sebastian Hack committed
61
static int bitset_get_arg_type(const lc_arg_occ_t *occ) {
62
  (void) occ;
Sebastian Hack's avatar
Sebastian Hack committed
63
  return lc_arg_type_ptr;
64
65
}

Sebastian Hack's avatar
Sebastian Hack committed
66
67
static int bitset_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
68
69
70
71
72
73
74
{
  int res = 2;
  bitset_t *b = arg->v_ptr;
  bitset_pos_t p;
  char buf[32];
  const char *prefix = "";

Sebastian Hack's avatar
Sebastian Hack committed
75
  lc_arg_append(app, occ, "[", 1);
Sebastian Hack's avatar
Sebastian Hack committed
76
  bitset_foreach(b, p) {
77
78
79
    int n;

    n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
Sebastian Hack's avatar
Sebastian Hack committed
80
    lc_arg_append(app, occ, buf, n);
81
82
83
    prefix = ", ";
    res += n;
  }
Sebastian Hack's avatar
Sebastian Hack committed
84
  lc_arg_append(app, occ, "]", 1);
85
86
87
88

  return res;
}

89
90
91
/**
 * emit an opaque Firm dbg_info object
 */
Sebastian Hack's avatar
Sebastian Hack committed
92
93
static int firm_emit_dbg(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
94
95
96
97
98
99
100
101
102
103
{
  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';
  }
Sebastian Hack's avatar
Sebastian Hack committed
104
  return lc_arg_append(app, occ, buf, strlen(buf));
105
106
}

107
108
109
/**
 * Beware: do not set the entity ld_name
 */
110
static const char *get_entity_ld_name_ex(ir_entity *ent) {
111
112
113
114
115
  if (ent->ld_name)
    return get_entity_ld_name(ent);
  return get_entity_name(ent);
}

116
117
118
/**
 * emit a Firm object
 */
Sebastian Hack's avatar
Sebastian Hack committed
119
120
static int firm_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
121
{
122
#define A(s)    occ->flag_hash ? s " ": ""
123
124
125
126
127

  void *X = arg->v_ptr;
  firm_kind *obj = X;
  int i, n;
  ir_node *block;
128
  char add[64];
129
  char buf[256];
130
  char tv_buf[256];
131
  ir_entity *ent;
132
133

  buf[0] = '\0';
134
  add[0] = '\0';
135
136
137
138
139
140

  if (! X)
    strncpy(buf, "(null)", sizeof(buf));
  else {
    switch (*obj) {
    case k_BAD:
141
142
      snprintf(buf, sizeof(buf), "BAD");
      snprintf(add, sizeof(add), "[%p]", X);
143
144
      break;
    case k_entity:
145
      snprintf(buf, sizeof(buf), "%s%s", A("ent"),
146
          isupper(occ->conversion) ? get_entity_ld_name_ex(X): get_entity_name(X));
147
      snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
148
149
      break;
    case k_type:
150
151
      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));
152
153
      break;
    case k_ir_graph:
Michael Beck's avatar
Michael Beck committed
154
      if (X == get_const_code_irg())
155
        snprintf(buf, sizeof(buf), "%s<ConstCodeIrg>", A("irg"));
Michael Beck's avatar
Michael Beck committed
156
157
      else
        snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
158
      snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
159
160
161
162
163
      break;
    case k_ir_node:
      switch (occ->conversion) {
      case 'B':
        block = is_no_Block(X) ? get_nodes_block(X) : X;
164
165
166
        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));
167
168
169
170
171
        break;
      case 'N':
        snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
        break;
      default:
Rubino Geiß's avatar
Rubino Geiß committed
172
        if (is_Const(X)) {
173
174
175
176
177
          tarval *tv = get_Const_tarval(X);
          if (tv)
            tarval_snprintf(tv_buf, sizeof(tv_buf), tv);
          else
            strncpy(tv_buf, "(NULL)", sizeof(tv_buf));
178
          snprintf(buf, sizeof(buf), "%s%s%s<%s>", A("irn"), get_irn_opname(X),
179
            get_mode_name(get_irn_mode(X)), tv_buf);
180
181
182
        }
        else
          snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
183
            get_mode_name(get_irn_mode(X)));
Sebastian Hack's avatar
Sebastian Hack committed
184
        snprintf(add, sizeof(add), "[%ld:%d]", get_irn_node_nr(X), get_irn_idx(X));
185
186
187
188
189
190
      }
      break;
    case k_ir_mode:
      snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
      break;
    case k_tarval:
191
192
      tarval_snprintf(tv_buf, sizeof(tv_buf), X);
      snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv_buf);
193
194
      break;
    case k_ir_loop:
Michael Beck's avatar
Michael Beck committed
195
      snprintf(buf, sizeof(buf), "loop[%d:%d]", get_loop_loop_nr(X), get_loop_depth(X));
196
197
198
199
200
201
      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);
202

203
      for (i = 0; i < n; ++i) {
204
205
206
        ent = get_compound_graph_path_node(X, i);

        strncat(buf, ".", sizeof(buf));
207
        strncat(buf, get_entity_name(ent), sizeof(buf));
208
209
210
211
212
        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));
        }
213
      }
214
      add[0] = '\0';
215
      break;
216
217
218
219
    case k_ir_extblk:
      snprintf(buf, sizeof(buf), "ExtBlock");
      snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(get_extbb_leader(X)));
      break;
220

221
    default:
222
223
      snprintf(buf, sizeof(buf), "UNKWN");
      snprintf(add, sizeof(add), "[%p]", X);
224
225
    }
  }
226

227
  if (occ->flag_plus)
228
229
  	strncat(buf, add, sizeof(buf));

Sebastian Hack's avatar
Sebastian Hack committed
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
241
242
243
{
  ident *id = (ident *)arg->v_ptr;
  const char *p = id ? get_id_str(id) : "(null)";

Sebastian Hack's avatar
Sebastian Hack 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;
254
	int amount = arg->v_int * (occ->width > 0 ? occ->width : 1);
255
256

	for(i = 0; i < amount; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
257
		lc_appendable_chadd(app, ' ');
258
259
260
261

	return amount;
}

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

Sebastian Hack's avatar
Sebastian Hack committed
271
  return lc_arg_append(app, occ, p, strlen(p));
272
273
}

Sebastian Hack's avatar
Sebastian Hack committed
274
lc_arg_env_t *firm_get_arg_env(void)
275
276
277
{
#define X(name, letter) {"firm:" name, letter}

Sebastian Hack's avatar
Sebastian Hack committed
278
  static lc_arg_env_t *env = NULL;
279

Sebastian Hack's avatar
Sebastian Hack 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
287
288
289
290
291
292
293
294
295
296
297
298
299

  static struct {
    const char *name;
    char letter;
  } args[] = {
    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'),
300
    X("cg_path",   'P'),
301
302
  };

303
  size_t i;
304
305

  if(env == NULL) {
Sebastian Hack's avatar
Sebastian Hack committed
306
307
    env = lc_arg_new_env();
    lc_arg_add_std(env);
308

Sebastian Hack's avatar
Sebastian Hack committed
309
    lc_arg_register(env, "firm", 'F', &firm_handler);
310
    for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
Sebastian Hack's avatar
Sebastian Hack committed
311
      lc_arg_register(env, args[i].name, args[i].letter, &firm_handler);
312

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

  return env;
}
322
323

#endif /* WITH_LIBCORE */