irargs.c 7.94 KB
Newer Older
1
2
3
4
5
6
7
8
/*
 * Project:     libFIRM
 * File name:   ir/ir/irargs.c
 * Purpose:     Support for libcore IR object output.
 * Author:      Sebastian Hack
 * Modified by:
 * Created:
 * CVS-ID:      $Id$
9
 * Copyright:   (c) 1998-2005 Universitaet Karlsruhe
10
11
12
13
14
15
16
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

17
18
#ifdef WITH_LIBCORE

19
20
#include "bitset.h"

21
#include <ctype.h>
Sebastian Hack's avatar
Sebastian Hack committed
22
#include <libcore/lc_printf.h>
23
24

#include "firm_common.h"
25
26
27
28
#include "irnode_t.h"
#include "entity_t.h"
#include "irloop_t.h"
#include "tv_t.h"
29
#include "dbginfo_t.h"
30
31
32
33

/**
 * identify a firm object type
 */
Sebastian Hack's avatar
Sebastian Hack committed
34
static int firm_get_arg_type(const lc_arg_occ_t *occ) {
35
  /* Firm objects are always pointer */
Sebastian Hack's avatar
Sebastian Hack committed
36
  return lc_arg_type_ptr;
37
38
}

Sebastian Hack's avatar
Sebastian Hack committed
39
static int firm_get_arg_type_int(const lc_arg_occ_t *occ) {
Sebastian Hack's avatar
Sebastian Hack committed
40
  return lc_arg_type_int;
41
42
}

43

Sebastian Hack's avatar
Sebastian Hack committed
44
static int bitset_get_arg_type(const lc_arg_occ_t *occ) {
Sebastian Hack's avatar
Sebastian Hack committed
45
  return lc_arg_type_ptr;
46
47
}

Sebastian Hack's avatar
Sebastian Hack committed
48
49
static int bitset_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
50
51
52
53
54
55
56
{
  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
57
  lc_arg_append(app, occ, "[", 1);
Sebastian Hack's avatar
Sebastian Hack committed
58
  bitset_foreach(b, p) {
59
60
61
    int n;

    n = snprintf(buf, sizeof(buf), "%s%d", prefix, (int) p);
Sebastian Hack's avatar
Sebastian Hack committed
62
    lc_arg_append(app, occ, buf, n);
63
64
65
    prefix = ", ";
    res += n;
  }
Sebastian Hack's avatar
Sebastian Hack committed
66
  lc_arg_append(app, occ, "]", 1);
67
68
69
70

  return res;
}

71
72
73
/**
 * emit an opaque Firm dbg_info object
 */
Sebastian Hack's avatar
Sebastian Hack committed
74
75
static int firm_emit_dbg(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
76
77
78
79
80
81
82
83
84
85
{
  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
86
  return lc_arg_append(app, occ, buf, strlen(buf));
87
88
}

89
90
91
92
93
94
95
96
97
/**
 * Beware: do not set the entity ld_name
 */
static const char *get_entity_ld_name_ex(entity *ent) {
  if (ent->ld_name)
    return get_entity_ld_name(ent);
  return get_entity_name(ent);
}

98
99
100
/**
 * emit a Firm object
 */
Sebastian Hack's avatar
Sebastian Hack committed
101
102
static int firm_emit(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
103
{
104
#define A(s)    occ->flag_hash ? s " ": ""
105
106
107
108
109

  void *X = arg->v_ptr;
  firm_kind *obj = X;
  int i, n;
  ir_node *block;
110
  char add[64];
111
  char buf[256];
112
  char tv_buf[256];
113
  entity *ent;
114
115

  buf[0] = '\0';
116
  add[0] = '\0';
117
118
119
120
121
122

  if (! X)
    strncpy(buf, "(null)", sizeof(buf));
  else {
    switch (*obj) {
    case k_BAD:
123
124
      snprintf(buf, sizeof(buf), "BAD");
      snprintf(add, sizeof(add), "[%p]", X);
125
126
      break;
    case k_entity:
127
      snprintf(buf, sizeof(buf), "%s%s", A("ent"),
128
          isupper(occ->conversion) ? get_entity_ld_name_ex(X): get_entity_name(X));
129
      snprintf(add, sizeof(add), "[%ld]", get_entity_nr(X));
130
131
      break;
    case k_type:
132
133
      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));
134
135
      break;
    case k_ir_graph:
Michael Beck's avatar
Michael Beck committed
136
      if (X == get_const_code_irg())
Michael Beck's avatar
Michael Beck committed
137
138
139
        snprintf(buf, sizeof(buf), "%s<ConstCodeIrg>", A("irg"), get_entity_name(get_irg_entity(X)));
      else
        snprintf(buf, sizeof(buf), "%s%s", A("irg"), get_entity_name(get_irg_entity(X)));
140
      snprintf(add, sizeof(add), "[%ld]", get_irg_graph_nr(X));
141
142
143
144
145
      break;
    case k_ir_node:
      switch (occ->conversion) {
      case 'B':
        block = is_no_Block(X) ? get_nodes_block(X) : X;
146
147
148
        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));
149
150
151
152
153
        break;
      case 'N':
        snprintf(buf, sizeof(buf), "%ld", get_irn_node_nr(X));
        break;
      default:
Rubino Geiß's avatar
Rubino Geiß committed
154
        if (is_Const(X)) {
155
156
157
158
159
          tarval *tv = get_Const_tarval(X);
          if (tv)
            tarval_snprintf(tv_buf, sizeof(tv_buf), tv);
          else
            strncpy(tv_buf, "(NULL)", sizeof(tv_buf));
160
          snprintf(buf, sizeof(buf), "%s%s%s<%s>", A("irn"), get_irn_opname(X),
161
            get_mode_name(get_irn_mode(X)), tv_buf);
162
163
164
        }
        else
          snprintf(buf, sizeof(buf), "%s%s%s", A("irn"), get_irn_opname(X),
165
            get_mode_name(get_irn_mode(X)));
Sebastian Hack's avatar
Sebastian Hack committed
166
        snprintf(add, sizeof(add), "[%ld:%d]", get_irn_node_nr(X), get_irn_idx(X));
167
168
169
170
171
172
      }
      break;
    case k_ir_mode:
      snprintf(buf, sizeof(buf), "%s%s", A("mode"), get_mode_name(X));
      break;
    case k_tarval:
173
174
      tarval_snprintf(tv_buf, sizeof(tv_buf), X);
      snprintf(buf, sizeof(buf), "%s%s", A("tv"), tv_buf);
175
176
      break;
    case k_ir_loop:
Michael Beck's avatar
Michael Beck committed
177
      snprintf(buf, sizeof(buf), "loop[%d:%d]", get_loop_loop_nr(X), get_loop_depth(X));
178
179
180
181
182
183
      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);
184

185
      for (i = 0; i < n; ++i) {
186
187
188
        ent = get_compound_graph_path_node(X, i);

        strncat(buf, ".", sizeof(buf));
189
        strncat(buf, get_entity_name(ent), sizeof(buf));
190
191
192
193
194
        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));
        }
195
      }
196
      add[0] = '\0';
197
      break;
198
199
200
201
    case k_ir_extblk:
      snprintf(buf, sizeof(buf), "ExtBlock");
      snprintf(add, sizeof(add), "[%ld]", get_irn_node_nr(get_extbb_leader(X)));
      break;
202

203
    default:
204
205
      snprintf(buf, sizeof(buf), "UNKWN");
      snprintf(add, sizeof(add), "[%p]", X);
206
207
    }
  }
208

209
  if (occ->flag_plus)
210
211
  	strncat(buf, add, sizeof(buf));

Sebastian Hack's avatar
Sebastian Hack committed
212
  return lc_arg_append(app, occ, buf, strlen(buf));
213
214
215
216
217
218
219

#undef A
}

/**
 * emit an ident
 */
Sebastian Hack's avatar
Sebastian Hack committed
220
221
static int firm_emit_ident(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
222
223
224
225
{
  ident *id = (ident *)arg->v_ptr;
  const char *p = id ? get_id_str(id) : "(null)";

Sebastian Hack's avatar
Sebastian Hack committed
226
  return lc_arg_append(app, occ, p, strlen(p));
227
228
}

229
230
231
/**
 * Emit indent.
 */
Sebastian Hack's avatar
Sebastian Hack committed
232
233
static int firm_emit_indent(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
234
235
{
	int i;
236
	int amount = arg->v_int * (occ->width > 0 ? occ->width : 1);
237
238

	for(i = 0; i < amount; ++i)
Sebastian Hack's avatar
Sebastian Hack committed
239
		lc_appendable_chadd(app, ' ');
240
241
242
243

	return amount;
}

244
245
246
/**
 * Emit pnc.
 */
Sebastian Hack's avatar
Sebastian Hack committed
247
248
static int firm_emit_pnc(lc_appendable_t *app,
    const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
249
250
251
252
{
  int value = arg->v_int;
  const char *p = get_pnc_string(value);

Sebastian Hack's avatar
Sebastian Hack committed
253
  return lc_arg_append(app, occ, p, strlen(p));
254
255
}

Sebastian Hack's avatar
Sebastian Hack committed
256
lc_arg_env_t *firm_get_arg_env(void)
257
258
259
{
#define X(name, letter) {"firm:" name, letter}

Sebastian Hack's avatar
Sebastian Hack committed
260
  static lc_arg_env_t *env = NULL;
261

Sebastian Hack's avatar
Sebastian Hack committed
262
263
264
265
266
267
  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 };
268
269
270
271
272
273
274
275
276
277
278
279
280
281

  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'),
282
    X("cg_path",   'P'),
283
284
285
286
287
  };

  int i;

  if(env == NULL) {
Sebastian Hack's avatar
Sebastian Hack committed
288
289
    env = lc_arg_new_env();
    lc_arg_add_std(env);
290

Sebastian Hack's avatar
Sebastian Hack committed
291
    lc_arg_register(env, "firm", 'F', &firm_handler);
292
    for (i = 0; i < sizeof(args)/sizeof(args[0]); ++i)
Sebastian Hack's avatar
Sebastian Hack committed
293
      lc_arg_register(env, args[i].name, args[i].letter, &firm_handler);
294

Sebastian Hack's avatar
Sebastian Hack committed
295
296
    lc_arg_register(env, "firm:ident",    'I', &ident_handler);
    lc_arg_register(env, "firm:indent",   '>', &indent_handler);
297
    lc_arg_register(env, "firm:dbg_info", 'G', &debug_handler);
Sebastian Hack's avatar
Sebastian Hack committed
298
    lc_arg_register(env, "firm:bitset",   'B', &bitset_handler);
Sebastian Hack's avatar
Sebastian Hack committed
299
    lc_arg_register(env, "firm:pnc",      '=', &pnc_handler);
300
301
302
303
  }

  return env;
}
304
305

#endif /* WITH_LIBCORE */