amd64_new_nodes.c 5.42 KB
Newer Older
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
4
5
6
7
8
9
10
11
12
13
 */

/**
 * @file
 * @brief   This file implements the creation of the achitecture specific firm
 *          opcodes and the coresponding node constructors for the amd64
 *          assembler irg.
 */
#include <stdlib.h>

14
#include "error.h"
15
16
17
18
19
20
21
22
23
24
#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"

25
#include "bearch.h"
26
27
28
29
30

#include "amd64_nodes_attr.h"
#include "amd64_new_nodes.h"
#include "gen_amd64_regalloc_if.h"

31
32
33
34
35
36
void set_amd64_ls_mode(ir_node *node, ir_mode *mode)
{
  amd64_attr_t *attr = get_amd64_attr(node);
  attr->ls_mode = mode;
}

37
38
39
/**
 * Dumper interface for dumping amd64 nodes in vcg.
 * @param F        the output file
40
 * @param n        the node to dump
41
42
 * @param reason   indicates which kind of information should be dumped
 */
43
static void amd64_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
44
{
45
	ir_mode *mode = NULL;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

	switch (reason) {
	case dump_node_opcode_txt:
		fprintf(F, "%s", get_irn_opname(n));
		break;

	case dump_node_mode_txt:
		mode = get_irn_mode(n);

		if (mode) {
			fprintf(F, "[%s]", get_mode_name(mode));
		} else {
			fprintf(F, "[?NOMODE?]");
		}
		break;

	case dump_node_nodeattr_txt:

		/* TODO: dump some attributes which should show up */
		/* in node name in dump (e.g. consts or the like)  */

		break;

	case dump_node_info_txt:
		arch_dump_reqs_and_registers(F, n);
		break;
	}
}

const amd64_attr_t *get_amd64_attr_const(const ir_node *node)
{
	assert(is_amd64_irn(node) && "need amd64 node to get attributes");
	return (const amd64_attr_t *)get_irn_generic_attr_const(node);
}

amd64_attr_t *get_amd64_attr(ir_node *node)
{
	assert(is_amd64_irn(node) && "need amd64 node to get attributes");
	return (amd64_attr_t *)get_irn_generic_attr(node);
}

87
88
const amd64_SymConst_attr_t *get_amd64_SymConst_attr_const(const ir_node *node)
{
89
90
91
92
	const amd64_SymConst_attr_t *attr
		= (const amd64_SymConst_attr_t*)get_irn_generic_attr_const(node);
	return attr;
}
93

94
95
96
97
98
amd64_SymConst_attr_t *get_amd64_SymConst_attr(ir_node *node)
{
	amd64_SymConst_attr_t *attr
		= (amd64_SymConst_attr_t*)get_irn_generic_attr(node);
	return attr;
99
100
}

101
102
103
104
105
106
107
108
109
110
111
112
113
114
const amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr_const(const ir_node *node)
{
	const amd64_switch_jmp_attr_t *attr
		= (const amd64_switch_jmp_attr_t*)get_irn_generic_attr_const(node);
	return attr;
}

amd64_switch_jmp_attr_t *get_amd64_switch_jmp_attr(ir_node *node)
{
	amd64_switch_jmp_attr_t *attr
		= (amd64_switch_jmp_attr_t*)get_irn_generic_attr(node);
	return attr;
}

115
116
117
118
119
120
121
122
123
/**
 * Initializes the nodes attributes.
 */
static void init_amd64_attributes(ir_node *node, arch_irn_flags_t flags,
                              const arch_register_req_t **in_reqs,
                              int n_res)
{
	ir_graph        *irg  = get_irn_irg(node);
	struct obstack  *obst = get_irg_obstack(irg);
124
125
	amd64_attr_t *attr    = get_amd64_attr(node);

126
127
	backend_info_t  *info;

128
129
	arch_set_irn_flags(node, flags);
	arch_set_irn_register_reqs_in(node, in_reqs);
130
131

	info            = be_get_info(node);
132
	info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, n_res);
133

134
135
	attr->data.ins_permuted = 0;
	attr->data.cmp_unsigned = 0;
136
	attr->ext.relation      = ir_relation_false;
137
	attr->ext.imm_value     = 0;
138
139
}

140
141
142
143
144
/**
 * Initialize SymConst attributes.
 */
static void init_amd64_SymConst_attributes(ir_node *node, ir_entity *entity)
{
145
	amd64_SymConst_attr_t *attr = get_amd64_SymConst_attr(node);
146
147
	attr->entity    = entity;
	attr->fp_offset = 0;
148
149
}

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
 * Initialize SwitchJmp attributes.
 */
static void init_amd64_switch_attributes(ir_node *node, const ir_switch_table *table, ir_entity *table_entity)
{
	unsigned n_outs = arch_get_irn_n_outs(node);
	unsigned o;

	amd64_switch_jmp_attr_t *attr = get_amd64_switch_jmp_attr(node);
	attr->table        = table;
	attr->table_entity = table_entity;

	for (o = 0; o < n_outs; o++) {
		arch_set_irn_register_req_out(node, o, arch_no_register_req);
	}
}

167
/** Compare node attributes for SymConst. */
Michael Beck's avatar
Michael Beck committed
168
static int cmp_amd64_attr_SymConst(const ir_node *a, const ir_node *b)
169
170
171
172
{
	const amd64_SymConst_attr_t *attr_a = get_amd64_SymConst_attr_const(a);
	const amd64_SymConst_attr_t *attr_b = get_amd64_SymConst_attr_const(b);

173
174
	if (attr_a->entity != attr_b->entity
	    || attr_a->fp_offset != attr_b->fp_offset)
175
176
177
178
179
		return 1;

	return 0;
}

180
/** Compare common amd64 node attributes. */
Michael Beck's avatar
Michael Beck committed
181
static int cmp_amd64_attr(const ir_node *a, const ir_node *b)
182
183
184
185
{
	const amd64_attr_t *attr_a = get_amd64_attr_const(a);
	const amd64_attr_t *attr_b = get_amd64_attr_const(b);

186
	return attr_a->ext.imm_value != attr_b->ext.imm_value;
187
188
}

189
190
191
192
193
194
195
196
197
198
199
200
201
202
/** copies the AMD64 attributes of a node. */
static void amd64_copy_attr(ir_graph *irg, const ir_node *old_node,
                          ir_node *new_node)
{
	struct obstack   *obst       = get_irg_obstack(irg);
	const amd64_attr_t *attr_old = get_amd64_attr_const(old_node);
	amd64_attr_t     *attr_new   = get_amd64_attr(new_node);
	backend_info_t   *old_info   = be_get_info(old_node);
	backend_info_t   *new_info   = be_get_info(new_node);

	/* copy the attributes */
	memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));

	/* copy out flags */
203
	new_info->flags = old_info->flags;
204
205
	new_info->out_infos =
		DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
206
	new_info->in_reqs = old_info->in_reqs;
207
208
}

209
210
/* Include the generated constructor functions */
#include "gen_amd64_new_nodes.c.inl"