amd64_new_nodes.c 4.61 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
14
15
16
17
18
19
20
21
22
23
24
25
 */

/**
 * @file
 * @brief   This file implements the creation of the achitecture specific firm
 *          opcodes and the coresponding node constructors for the amd64
 *          assembler irg.
 */
#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"

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

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

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

38
39
40
/**
 * Dumper interface for dumping amd64 nodes in vcg.
 * @param F        the output file
41
 * @param n        the node to dump
42
43
 * @param reason   indicates which kind of information should be dumped
 */
44
static void amd64_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
45
{
46
	ir_mode *mode = NULL;
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
87

	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);
}

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

95
96
97
98
99
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;
100
101
}

102
103
104
105
106
107
108
109
110
/**
 * 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);
111
112
	amd64_attr_t *attr    = get_amd64_attr(node);

113
114
	backend_info_t  *info;

115
116
	arch_set_irn_flags(node, flags);
	arch_set_irn_register_reqs_in(node, in_reqs);
117
118

	info            = be_get_info(node);
119
	info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, n_res);
120

121
122
	attr->data.ins_permuted = 0;
	attr->data.cmp_unsigned = 0;
123
	attr->ext.relation      = ir_relation_false;
124
	attr->ext.imm_value     = 0;
125
126
}

127
128
129
130
131
/**
 * Initialize SymConst attributes.
 */
static void init_amd64_SymConst_attributes(ir_node *node, ir_entity *entity)
{
132
	amd64_SymConst_attr_t *attr = get_amd64_SymConst_attr(node);
133
134
	attr->entity    = entity;
	attr->fp_offset = 0;
135
136
137
}

/** Compare node attributes for SymConst. */
Michael Beck's avatar
Michael Beck committed
138
static int cmp_amd64_attr_SymConst(const ir_node *a, const ir_node *b)
139
140
141
142
{
	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);

143
144
	if (attr_a->entity != attr_b->entity
	    || attr_a->fp_offset != attr_b->fp_offset)
145
146
147
148
149
		return 1;

	return 0;
}

150
/** Compare common amd64 node attributes. */
Michael Beck's avatar
Michael Beck committed
151
static int cmp_amd64_attr(const ir_node *a, const ir_node *b)
152
153
154
155
{
	const amd64_attr_t *attr_a = get_amd64_attr_const(a);
	const amd64_attr_t *attr_b = get_amd64_attr_const(b);

156
	return attr_a->ext.imm_value != attr_b->ext.imm_value;
157
158
}

159
160
161
162
163
164
165
166
167
168
169
170
171
172
/** 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 */
173
	new_info->flags = old_info->flags;
174
175
	new_info->out_infos =
		DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
176
	new_info->in_reqs = old_info->in_reqs;
177
178
}

179
180
/* Include the generated constructor functions */
#include "gen_amd64_new_nodes.c.inl"