sparc_new_nodes.c 10.8 KB
Newer Older
Hannes Rapp's avatar
Hannes Rapp committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Hannes Rapp's avatar
Hannes Rapp committed
4
5
6
7
8
9
10
 */

/**
 * @file
 * @brief   This file implements the creation of the achitecture specific firm
 *          opcodes and the coresponding node constructors for the sparc
 *          assembler irg.
Matthias Braun's avatar
Matthias Braun committed
11
 * @author  Hannes Rapp, Matthias Braun
Hannes Rapp's avatar
Hannes Rapp committed
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 */
#include "config.h"

#include <stdlib.h>

#include "irprog_t.h"
#include "irgraph_t.h"
#include "irnode_t.h"
#include "irmode_t.h"
#include "ircons_t.h"
#include "iropt_t.h"
#include "irop.h"
#include "irprintf.h"
#include "xmalloc.h"

27
#include "bearch.h"
28
#include "bearch_sparc_t.h"
Hannes Rapp's avatar
Hannes Rapp committed
29
30
31
32
33

#include "sparc_nodes_attr.h"
#include "sparc_new_nodes.h"
#include "gen_sparc_regalloc_if.h"

34
bool sparc_has_load_store_attr(const ir_node *node)
35
{
Matthias Braun's avatar
Matthias Braun committed
36
37
	return is_sparc_Ld(node) || is_sparc_St(node) || is_sparc_Ldf(node)
	    || is_sparc_Stf(node);
38
39
40
41
}

static bool has_jmp_cond_attr(const ir_node *node)
{
42
	return is_sparc_Bicc(node) || is_sparc_fbfcc(node);
43
44
}

yb9976's avatar
yb9976 committed
45
#ifndef NDEBUG
46
static bool has_switch_jmp_attr(const ir_node *node)
47
48
49
{
	return is_sparc_SwitchJmp(node);
}
yb9976's avatar
yb9976 committed
50
#endif
51

52
53
54
55
56
static bool has_fp_attr(const ir_node *node)
{
	return is_sparc_fadd(node) || is_sparc_fsub(node)
	    || is_sparc_fmul(node) || is_sparc_fdiv(node)
	    || is_sparc_fftoi(node) || is_sparc_fitof(node)
57
	    || is_sparc_fneg(node) || is_sparc_fcmp(node);
58
59
60
61
62
63
64
}

static bool has_fp_conv_attr(const ir_node *node)
{
	return is_sparc_fftof(node);
}

Hannes Rapp's avatar
Hannes Rapp committed
65
66
67
/**
 * Dumper interface for dumping sparc nodes in vcg.
 * @param F        the output file
68
 * @param n        the node to dump
Hannes Rapp's avatar
Hannes Rapp committed
69
70
 * @param reason   indicates which kind of information should be dumped
 */
71
static void sparc_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
Hannes Rapp's avatar
Hannes Rapp committed
72
73
{
	switch (reason) {
74
75
	case dump_node_opcode_txt:
		fprintf(F, "%s", get_irn_opname(n));
Hannes Rapp's avatar
Hannes Rapp committed
76
77
		break;

78
	case dump_node_mode_txt:
Hannes Rapp's avatar
Hannes Rapp committed
79
80
		break;

81
82
	case dump_node_info_txt:
		arch_dump_reqs_and_registers(F, n);
Matthias Braun's avatar
Matthias Braun committed
83
		const sparc_attr_t *sparc_attr = get_sparc_attr_const(n);
84
		if (sparc_attr->immediate_value_entity) {
85
			ir_fprintf(F, "entity: %+F (offset %d)\n",
86
87
			           sparc_attr->immediate_value_entity,
			           sparc_attr->immediate_value);
88
		} else {
89
			ir_fprintf(F, "immediate value: %d\n", sparc_attr->immediate_value);
90
		}
91
		if (sparc_has_load_store_attr(n)) {
92
			const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(n);
93
94
95
96
97
98
99
			ir_fprintf(F, "load store mode: %+F\n", attr->load_store_mode);
			fprintf(F, "is frame entity: %s\n",
			        attr->is_frame_entity ? "true" : "false");
		}
		if (has_jmp_cond_attr(n)) {
			const sparc_jmp_cond_attr_t *attr
				= get_sparc_jmp_cond_attr_const(n);
Matthias Braun's avatar
Matthias Braun committed
100
			fprintf(F, "relation: %d (%s)\n", (int)attr->relation,
101
			        get_relation_string(attr->relation));
102
			fprintf(F, "unsigned: %s\n", attr->is_unsigned ? "true" : "false");
103
		}
104
105
106
107
108
109
110
111
112
		if (has_fp_attr(n)) {
			const sparc_fp_attr_t *attr = get_sparc_fp_attr_const(n);
			ir_fprintf(F, "fp_mode: %+F\n", attr->fp_mode);
		}
		if (has_fp_conv_attr(n)) {
			const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(n);
			ir_fprintf(F, "conv from: %+F\n", attr->src_mode);
			ir_fprintf(F, "conv to: %+F\n", attr->dest_mode);
		}
113
114
115
		break;

	case dump_node_nodeattr_txt:
Hannes Rapp's avatar
Hannes Rapp committed
116
117
118
119
		break;
	}
}

120
121
static void sparc_set_attr_imm(ir_node *res, ir_entity *entity,
                               int32_t immediate_value)
Hannes Rapp's avatar
Hannes Rapp committed
122
{
123
	sparc_attr_t *attr           = (sparc_attr_t*)get_irn_generic_attr(res);
124
125
	attr->immediate_value_entity = entity;
	attr->immediate_value        = immediate_value;
126
	arch_add_irn_flags(res, (arch_irn_flags_t)sparc_arch_irn_flag_immediate_form);
Hannes Rapp's avatar
Hannes Rapp committed
127
128
}

129
130
static void init_sparc_jmp_cond_attr(ir_node *node, ir_relation relation,
                                     bool is_unsigned)
Hannes Rapp's avatar
Hannes Rapp committed
131
132
{
	sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr(node);
133
	attr->relation    = relation;
134
	attr->is_unsigned = is_unsigned;
Hannes Rapp's avatar
Hannes Rapp committed
135
136
137
138
}

sparc_attr_t *get_sparc_attr(ir_node *node)
{
139
140
	assert(is_sparc_irn(node));
	return (sparc_attr_t*) get_irn_generic_attr(node);
Hannes Rapp's avatar
Hannes Rapp committed
141
142
143
144
}

const sparc_attr_t *get_sparc_attr_const(const ir_node *node)
{
145
146
	assert(is_sparc_irn(node));
	return (const sparc_attr_t*) get_irn_generic_attr_const(node);
Hannes Rapp's avatar
Hannes Rapp committed
147
148
149
150
}

sparc_load_store_attr_t *get_sparc_load_store_attr(ir_node *node)
{
151
	assert(sparc_has_load_store_attr(node));
152
	return (sparc_load_store_attr_t*) get_irn_generic_attr_const(node);
Hannes Rapp's avatar
Hannes Rapp committed
153
154
155
156
}

const sparc_load_store_attr_t *get_sparc_load_store_attr_const(const ir_node *node)
{
157
	assert(sparc_has_load_store_attr(node));
158
	return (const sparc_load_store_attr_t*) get_irn_generic_attr_const(node);
Hannes Rapp's avatar
Hannes Rapp committed
159
160
161
162
}

sparc_jmp_cond_attr_t *get_sparc_jmp_cond_attr(ir_node *node)
{
163
164
	assert(has_jmp_cond_attr(node));
	return (sparc_jmp_cond_attr_t*) get_irn_generic_attr_const(node);
Hannes Rapp's avatar
Hannes Rapp committed
165
166
167
168
}

const sparc_jmp_cond_attr_t *get_sparc_jmp_cond_attr_const(const ir_node *node)
{
169
170
	assert(has_jmp_cond_attr(node));
	return (const sparc_jmp_cond_attr_t*) get_irn_generic_attr_const(node);
Hannes Rapp's avatar
Hannes Rapp committed
171
172
}

173
sparc_switch_jmp_attr_t *get_sparc_switch_jmp_attr(ir_node *node)
Hannes Rapp's avatar
Hannes Rapp committed
174
{
175
176
	assert(has_switch_jmp_attr(node));
	return (sparc_switch_jmp_attr_t*) get_irn_generic_attr_const(node);
Hannes Rapp's avatar
Hannes Rapp committed
177
178
}

179
const sparc_switch_jmp_attr_t *get_sparc_switch_jmp_attr_const(const ir_node *node)
Hannes Rapp's avatar
Hannes Rapp committed
180
{
181
182
	assert(has_switch_jmp_attr(node));
	return (const sparc_switch_jmp_attr_t*) get_irn_generic_attr_const(node);
Hannes Rapp's avatar
Hannes Rapp committed
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
sparc_fp_attr_t *get_sparc_fp_attr(ir_node *node)
{
	assert(has_fp_attr(node));
	return (sparc_fp_attr_t*) get_irn_generic_attr(node);
}

const sparc_fp_attr_t *get_sparc_fp_attr_const(const ir_node *node)
{
	assert(has_fp_attr(node));
	return (const sparc_fp_attr_t*) get_irn_generic_attr_const(node);
}

sparc_fp_conv_attr_t *get_sparc_fp_conv_attr(ir_node *node)
{
	assert(has_fp_conv_attr(node));
	return (sparc_fp_conv_attr_t*) get_irn_generic_attr(node);
}

const sparc_fp_conv_attr_t *get_sparc_fp_conv_attr_const(const ir_node *node)
{
	assert(has_fp_conv_attr(node));
	return (const sparc_fp_conv_attr_t*) get_irn_generic_attr_const(node);
}

209
210
211
212
213
214
215
216
217
218
219
220
sparc_asm_attr_t *get_sparc_asm_attr(ir_node *node)
{
	assert(is_sparc_ASM(node));
	return (sparc_asm_attr_t*)get_irn_generic_attr(node);
}

const sparc_asm_attr_t *get_sparc_asm_attr_const(const ir_node *node)
{
	assert(is_sparc_ASM(node));
	return (const sparc_asm_attr_t*)get_irn_generic_attr_const(node);
}

Hannes Rapp's avatar
Hannes Rapp committed
221
222
223
/**
 * Initializes the nodes attributes.
 */
224
225
226
static void init_sparc_attributes(ir_node *node, arch_irn_flags_t flags,
                                  const arch_register_req_t **in_reqs,
                                  int n_res)
Hannes Rapp's avatar
Hannes Rapp committed
227
{
228
229
	arch_set_irn_flags(node, flags);
	arch_set_irn_register_reqs_in(node, in_reqs);
Hannes Rapp's avatar
Hannes Rapp committed
230

Matthias Braun's avatar
Matthias Braun committed
231
232
233
	backend_info_t  *info = be_get_info(node);
	ir_graph        *irg  = get_irn_irg(node);
	struct obstack  *obst = get_irg_obstack(irg);
234
	info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, n_res);
Hannes Rapp's avatar
Hannes Rapp committed
235
236
237
}

static void init_sparc_load_store_attributes(ir_node *res, ir_mode *ls_mode,
238
											ir_entity *entity, int32_t offset,
239
240
											bool is_frame_entity,
											bool is_reg_reg)
Hannes Rapp's avatar
Hannes Rapp committed
241
{
242
243
244
245
246
	sparc_load_store_attr_t *attr     = get_sparc_load_store_attr(res);
	attr->base.immediate_value_entity = entity;
	attr->base.immediate_value        = offset;
	attr->load_store_mode             = ls_mode;
	attr->is_frame_entity             = is_frame_entity;
247
	attr->is_reg_reg                  = is_reg_reg;
Hannes Rapp's avatar
Hannes Rapp committed
248
249
}

250
251
252
253
254
255
256
257
258
259
260
261
262
263
static void init_sparc_fp_attributes(ir_node *res, ir_mode *fp_mode)
{
	sparc_fp_attr_t *attr = get_sparc_fp_attr(res);
	attr->fp_mode = fp_mode;
}

static void init_sparc_fp_conv_attributes(ir_node *res, ir_mode *src_mode,
                                          ir_mode *dest_mode)
{
	sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr(res);
	attr->src_mode = src_mode;
	attr->dest_mode = dest_mode;
}

Matthias Braun's avatar
Matthias Braun committed
264
265
266
static void init_sparc_switch_jmp_attributes(ir_node *node,
                                             const ir_switch_table *table,
                                             ir_entity *table_entity)
267
{
Matthias Braun's avatar
Matthias Braun committed
268
269
270
271
	sparc_switch_jmp_attr_t *attr = get_sparc_switch_jmp_attr(node);
	attr->table        = table;
	attr->table_entity = table_entity;

272
	be_foreach_out(node, o) {
Matthias Braun's avatar
Matthias Braun committed
273
274
		arch_set_irn_register_req_out(node, o, arch_no_register_req);
	}
275
276
}

277
278
279
280
281
282
static void init_sparc_asm_attributes(ir_node *node, ident *text)
{
	sparc_asm_attr_t *attr = get_sparc_asm_attr(node);
	attr->text = text;
}

Hannes Rapp's avatar
Hannes Rapp committed
283
284
285
/**
 * copies sparc attributes of  node
 */
286
287
static void sparc_copy_attr(ir_graph *irg, const ir_node *old_node,
                            ir_node *new_node)
288
{
Matthias Braun's avatar
Matthias Braun committed
289
	struct obstack     *obst     = get_irg_obstack(irg);
290
	const sparc_attr_t *attr_old = get_sparc_attr_const(old_node);
Hannes Rapp's avatar
Hannes Rapp committed
291
	sparc_attr_t       *attr_new = get_sparc_attr(new_node);
292
293
	backend_info_t     *old_info = be_get_info(old_node);
	backend_info_t     *new_info = be_get_info(new_node);
Hannes Rapp's avatar
Hannes Rapp committed
294
295
296
297

	/* copy the attributes */
	memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
	/* copy out flags */
298
	new_info->flags = old_info->flags;
Hannes Rapp's avatar
Hannes Rapp committed
299
300
	new_info->out_infos =
		DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
301
	new_info->in_reqs = old_info->in_reqs;
Hannes Rapp's avatar
Hannes Rapp committed
302
303
304
305
306
}

/**
 * compare some node's attributes
 */
Michael Beck's avatar
Michael Beck committed
307
static int cmp_attr_sparc(const ir_node *a, const ir_node *b)
Hannes Rapp's avatar
Hannes Rapp committed
308
309
310
311
{
	const sparc_attr_t *attr_a = get_sparc_attr_const(a);
	const sparc_attr_t *attr_b = get_sparc_attr_const(b);

Hannes Rapp's avatar
Hannes Rapp committed
312
	return attr_a->immediate_value != attr_b->immediate_value
313
		|| attr_a->immediate_value_entity != attr_b->immediate_value_entity;
Hannes Rapp's avatar
Hannes Rapp committed
314
315
}

Michael Beck's avatar
Michael Beck committed
316
static int cmp_attr_sparc_load_store(const ir_node *a, const ir_node *b)
Hannes Rapp's avatar
Hannes Rapp committed
317
{
Hannes Rapp's avatar
Hannes Rapp committed
318
319
320
321
	const sparc_load_store_attr_t *attr_a = get_sparc_load_store_attr_const(a);
	const sparc_load_store_attr_t *attr_b = get_sparc_load_store_attr_const(b);

	if (cmp_attr_sparc(a, b))
322
		return 1;
Hannes Rapp's avatar
Hannes Rapp committed
323

324
325
	return attr_a->is_frame_entity != attr_b->is_frame_entity
			|| attr_a->load_store_mode != attr_b->load_store_mode;
Hannes Rapp's avatar
Hannes Rapp committed
326
327
}

Michael Beck's avatar
Michael Beck committed
328
static int cmp_attr_sparc_jmp_cond(const ir_node *a, const ir_node *b)
Hannes Rapp's avatar
Hannes Rapp committed
329
{
Hannes Rapp's avatar
Hannes Rapp committed
330
331
332
333
	const sparc_jmp_cond_attr_t *attr_a = get_sparc_jmp_cond_attr_const(a);
	const sparc_jmp_cond_attr_t *attr_b = get_sparc_jmp_cond_attr_const(b);

	if (cmp_attr_sparc(a, b))
334
		return 1;
Hannes Rapp's avatar
Hannes Rapp committed
335

336
	return attr_a->relation != attr_b->relation
337
	    || attr_a->is_unsigned != attr_b->is_unsigned;
Hannes Rapp's avatar
Hannes Rapp committed
338
339
}

Michael Beck's avatar
Michael Beck committed
340
static int cmp_attr_sparc_fp(const ir_node *a, const ir_node *b)
341
342
343
344
345
346
347
348
349
350
{
	const sparc_fp_attr_t *attr_a = get_sparc_fp_attr_const(a);
	const sparc_fp_attr_t *attr_b = get_sparc_fp_attr_const(b);

	if (cmp_attr_sparc(a, b))
		return 1;

	return attr_a->fp_mode != attr_b->fp_mode;
}

Michael Beck's avatar
Michael Beck committed
351
static int cmp_attr_sparc_fp_conv(const ir_node *a, const ir_node *b)
352
353
354
355
356
357
358
359
{
	const sparc_fp_conv_attr_t *attr_a = get_sparc_fp_conv_attr_const(a);
	const sparc_fp_conv_attr_t *attr_b = get_sparc_fp_conv_attr_const(b);

	if (cmp_attr_sparc(a, b))
		return 1;

	return attr_a->src_mode != attr_b->src_mode
360
	    || attr_a->dest_mode != attr_b->dest_mode;
361
362
}

363
364
365
366
367
368
369
370
371
372
static int cmp_attr_sparc_asm(const ir_node *a, const ir_node *b)
{
	if (cmp_attr_sparc(a, b))
		return 1;

	const sparc_asm_attr_t *attr_a = get_sparc_asm_attr_const(a);
	const sparc_asm_attr_t *attr_b = get_sparc_asm_attr_const(b);
	return attr_a->text != attr_b->text;
}

Hannes Rapp's avatar
Hannes Rapp committed
373
374
/* Include the generated constructor functions */
#include "gen_sparc_new_nodes.c.inl"