benode.h 8.15 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Sebastian Hack's avatar
Sebastian Hack committed
6
/**
Christian Würdig's avatar
Christian Würdig committed
7
8
9
10
 * @file
 * @brief       Backend node support for generic backend nodes.
 * @author      Sebastian Hack
 * @date        17.05.2005
Sebastian Hack's avatar
Sebastian Hack committed
11
 *
Christian Würdig's avatar
Christian Würdig committed
12
 * Backend node support for generic backend nodes.
13
 * This file provides Perm, and Copy nodes.
Sebastian Hack's avatar
Sebastian Hack committed
14
 */
15
16
#ifndef FIRM_BE_BENODE_H
#define FIRM_BE_BENODE_H
17

18
#include "be_types.h"
19
#include "firm_types.h"
20
#include "irnode_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
21

22
typedef enum be_opcode {
23
	beo_Asm,
Matthias Braun's avatar
Matthias Braun committed
24
	beo_first = beo_Asm,
25
26
27
	beo_Copy,
	beo_CopyKeep,
	beo_IncSP,
Matthias Braun's avatar
Matthias Braun committed
28
29
30
	beo_Keep,
	beo_MemPerm,
	beo_Perm,
31
	beo_Relocation,
Christoph Mallon's avatar
Christoph Mallon committed
32
33
	beo_Start,
	beo_last  = beo_Start
34
35
} be_opcode;

36
37
38
39
40
41
42
43
44
45
46
typedef struct be_node_attr_t {
	except_attr exc;
} be_node_attr_t;

typedef struct be_asm_attr_t {
	be_node_attr_t base;
	ident         *text;
	void          *operands;
} be_asm_attr_t;

extern ir_op *op_be_Asm;
47
extern ir_op *op_be_Copy;
Michael Beck's avatar
Michael Beck committed
48
extern ir_op *op_be_CopyKeep;
49
extern ir_op *op_be_IncSP;
Matthias Braun's avatar
Matthias Braun committed
50
51
52
extern ir_op *op_be_Keep;
extern ir_op *op_be_MemPerm;
extern ir_op *op_be_Perm;
53
extern ir_op *op_be_Relocation;
Christoph Mallon's avatar
Christoph Mallon committed
54
extern ir_op *op_be_Start;
55

56
57
58
/**
 * Determines if irn is a be_node.
 */
59
60
bool is_be_node(const ir_node *irn);

61
62
63
/**
 * Create all BE specific opcodes.
 */
64
void be_init_op(void);
65

Matthias Braun's avatar
Matthias Braun committed
66
67
void be_finish_op(void);

68
69
70
/**
 * Position numbers for the be_Copy inputs.
 */
71
enum {
72
	n_be_Copy_op = 0
73
};
74
75
76
77

/**
 * Make a new Copy node.
 */
78
ir_node *be_new_d_Copy(dbg_info *dbgi, ir_node *block, ir_node *op);
79
ir_node *be_new_Copy(ir_node *block, ir_node *in);
80
/** Returns the Copy Argument. */
81
82
ir_node *be_get_Copy_op(const ir_node *cpy);

83
84
85
86
87
/**
 * Insert a Copy of @p val into @p reg before @p before.
 */
ir_node *be_new_Copy_before_reg(ir_node *val, ir_node *before, arch_register_t const *reg);

88
89
90
/**
 * Make a new Perm node.
 */
Matthias Braun's avatar
Matthias Braun committed
91
92
ir_node *be_new_Perm(arch_register_class_t const *cls, ir_node *block, int n,
                     ir_node *const *in);
93

94
95
/**
 * Create a new MemPerm node.
96
97
98
 * A MemPerm node exchanges the values of memory locations. (Typically entities
 * used as spillslots). MemPerm nodes perform this operation without modifying
 * any register values.
99
 */
100
101
102
ir_node *be_new_MemPerm(ir_node *block, int n, ir_node *const *in);

ir_node *be_new_Keep(ir_node *block, int arity, ir_node *const *in);
103
ir_node *be_new_Keep_one(ir_node *kept);
Sebastian Hack's avatar
Sebastian Hack committed
104

105
106
107
108
enum {
	n_be_IncSP_pred
};

Sebastian Hack's avatar
Sebastian Hack committed
109
110
/**
 * Make a stack pointer increase/decrease node.
111
112
 * @param sp     The stack pointer register.
 * @param block  The block to insert the node into.
Sebastian Hack's avatar
Sebastian Hack committed
113
 * @param old_sp The node defining the former stack pointer.
114
115
116
117
 * @param offset amount the stack should expand (positive offset) or shrink
 *               (negative offset). Note that the offset is independent of the
 *               natural stack direction of the architecture but just specifies
 *               abstract expanding/shrinking of the stack area.
118
119
 * @param align  force stack alignment to this power of 2. (i.e. specifying 4
 *               results in a 2**4 = 16 bytes stack alignment)
Sebastian Hack's avatar
Sebastian Hack committed
120
 * @return       A new stack pointer increment/decrement node.
121
122
 * @note         This node sets a register constraint to the @p sp register on
 *               its output.
Sebastian Hack's avatar
Sebastian Hack committed
123
 */
124
ir_node *be_new_IncSP(const arch_register_t *sp, ir_node *block,
125
                      ir_node *old_sp, int offset, unsigned align);
Sebastian Hack's avatar
Sebastian Hack committed
126

Michael Beck's avatar
BugFix:    
Michael Beck committed
127
128
/** Returns the previous node that computes the stack pointer. */
ir_node *be_get_IncSP_pred(ir_node *incsp);
Sebastian Hack's avatar
Sebastian Hack committed
129

130
/** Sets the previous node that computes the stack pointer. */
Matthias Braun's avatar
Matthias Braun committed
131
void be_set_IncSP_pred(ir_node *incsp, ir_node *pred);
132

133
134
135
136
137
138
/**
 * Sets a new offset to a IncSP node.
 * A positive offset means expanding the stack, a negative offset shrinking
 * an offset is == BE_STACK_FRAME_SIZE will be replaced by the real size of the
 * stackframe in the fix_stack_offsets phase.
 */
Matthias Braun's avatar
Matthias Braun committed
139
void be_set_IncSP_offset(ir_node *irn, int offset);
Michael Beck's avatar
BugFix:    
Michael Beck committed
140
141

/** Gets the offset from a IncSP node. */
142
int be_get_IncSP_offset(const ir_node *irn);
143
144
145
/** Return requested stack alignment (as a logarithm of two, i.e. 4 means
 * the stack alignment will be 2**4=16 bytes) */
unsigned be_get_IncSP_align(const ir_node *irn);
Sebastian Hack's avatar
Sebastian Hack committed
146

Sebastian Hack's avatar
Sebastian Hack committed
147
enum {
Matthias Braun's avatar
Matthias Braun committed
148
149
	n_be_CopyKeep_op,
	n_be_CopyKeep_max = n_be_CopyKeep_op
Sebastian Hack's avatar
Sebastian Hack committed
150
};
151
ir_node *be_new_CopyKeep(ir_node *block, ir_node *src, int n, ir_node *const *in_keep);
152

153
ir_node *be_get_CopyKeep_op(const ir_node *cpy);
Sebastian Hack's avatar
Sebastian Hack committed
154

155
156
void be_set_MemPerm_in_entity(const ir_node *irn, unsigned n, ir_entity* ent);
ir_entity *be_get_MemPerm_in_entity(const ir_node *irn, unsigned n);
Matthias Braun's avatar
Matthias Braun committed
157

158
159
void be_set_MemPerm_out_entity(const ir_node *irn, unsigned n, ir_entity* ent);
ir_entity *be_get_MemPerm_out_entity(const ir_node *irn, unsigned n);
160

161
162
163
void be_set_MemPerm_offset(ir_node *irn, int offset);
int be_get_MemPerm_offset(const ir_node *irn);

164
unsigned be_get_MemPerm_entity_arity(const ir_node *irn);
165

166
167
arch_register_req_t const **be_allocate_in_reqs(ir_graph *irg, unsigned n);

168
const arch_register_req_t *be_create_reg_req(struct obstack *obst,
169
170
                                             const arch_register_t *reg,
                                             bool ignore);
171

172
173
174
/**
 * Set the register requirements for a phi node.
 */
175
176
void be_set_phi_reg_req(ir_node *phi, const arch_register_req_t *req);

177
178
179
180
/**
 * Creates a new phi with associated backend informations
 */
ir_node *be_new_Phi(ir_node *block, int n_ins, ir_node **ins, ir_mode *mode,
181
                    const arch_register_req_t *req);
182

183
184
185
186
187
188
189
190
191
192
193
/**
 * Create a new Phi with backend info and without inputs.
 * Inputs are added later with @see be_complete_Phi().
 */
ir_node *be_new_Phi0(ir_node *block, ir_mode *mode, arch_register_req_t const *req);

/**
 * Add inputs to a inputless Phi created by @see be_new_Phi0().
 */
ir_node *be_complete_Phi(ir_node *phi, unsigned n_ins, ir_node **ins);

194
ir_node *be_new_Asm(dbg_info *dbgi, ir_node *block, int n_ins, ir_node **ins, arch_register_req_t const **in_reqs, int n_outs, ident *text, void *operands);
195

196
197
198
199
200
201
/**
 * Create a new Relocation node. The node returns the reference to an entity
 * with a specific linker relocation kind. The relocation kind is backend
 * specific. This node is meant to be used in preparation phases for position
 * independent code.
 */
202
203
ir_node *be_new_Relocation(ir_graph *irg, unsigned kind, ir_entity *entity,
                           ir_mode *mode);
204
205
206
207
208

ir_entity *be_get_Relocation_entity(ir_node const* node);

unsigned be_get_Relocation_kind(ir_node const* node);

Christoph Mallon's avatar
Christoph Mallon committed
209
210
211
212
213
214
215
216
217
218
typedef enum be_start_out {
	BE_START_NO,
	BE_START_REG,
	BE_START_IGNORE,
} be_start_out;

ir_node *be_new_Start(ir_graph *irg, be_start_out const *outs);

ir_node *be_get_Start_mem(ir_graph *irg);

219
/**
Christoph Mallon's avatar
Christoph Mallon committed
220
 * Get Proj of start node with a specific register.
221
 */
Christoph Mallon's avatar
Christoph Mallon committed
222
ir_node *be_get_Start_proj(ir_graph *irg, arch_register_t const *reg);
223

224
/**
Christoph Mallon's avatar
Christoph Mallon committed
225
226
 * Create a new Proj node.  Its mode is determined from the out requirement
 * @p pos of @p pred.
227
 */
Christoph Mallon's avatar
Christoph Mallon committed
228
ir_node *be_new_Proj(ir_node *pred, unsigned pos);
229

230
231
ir_node *be_new_Proj_reg(ir_node *pred, unsigned pos, arch_register_t const *reg);

232
233
234
235
236
237
/**
 * Gets the Proj with number pn from irn.
 * Creates the Proj, if it does not exist, yet.
 */
ir_node *be_get_or_make_Proj_for_pn(ir_node *irn, unsigned pn);

238
239
240
241
242
243
244
245
static inline bool be_is_Asm       (const ir_node *irn) { return get_irn_op(irn) == op_be_Asm       ; }
static inline bool be_is_Copy      (const ir_node *irn) { return get_irn_op(irn) == op_be_Copy      ; }
static inline bool be_is_CopyKeep  (const ir_node *irn) { return get_irn_op(irn) == op_be_CopyKeep  ; }
static inline bool be_is_Perm      (const ir_node *irn) { return get_irn_op(irn) == op_be_Perm      ; }
static inline bool be_is_MemPerm   (const ir_node *irn) { return get_irn_op(irn) == op_be_MemPerm   ; }
static inline bool be_is_Keep      (const ir_node *irn) { return get_irn_op(irn) == op_be_Keep      ; }
static inline bool be_is_IncSP     (const ir_node *irn) { return get_irn_op(irn) == op_be_IncSP     ; }
static inline bool be_is_Relocation(const ir_node *irn) { return get_irn_op(irn) == op_be_Relocation; }
Christoph Mallon's avatar
Christoph Mallon committed
246
static inline bool be_is_Start     (const ir_node *irn) { return get_irn_op(irn) == op_be_Start     ; }
247

248
249
250
251
252
253
static inline be_asm_attr_t const *get_be_asm_attr_const(ir_node const *const asmn)
{
	assert(be_is_Asm(asmn));
	return (be_asm_attr_t const*)get_irn_generic_attr_const(asmn);
}

254
255
256
257
258
/**
 * Copies the backend specific attributes from old node to new node.
 */
void be_copy_attr(ir_graph *irg, ir_node const *old_node, ir_node *new_node);

259
#endif