ia32_nodes_attr.h 13.4 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Christian Würdig's avatar
Christian Würdig committed
20
/**
Christian Würdig's avatar
Christian Würdig committed
21
22
23
 * @file
 * @brief       Type definitions for ia32 node attributes.
 * @author      Christian Wuerdig
Christian Würdig's avatar
Christian Würdig committed
24
 */
Christian Würdig's avatar
Christian Würdig committed
25
26
#ifndef FIRM_BE_IA32_IA32_NODES_ATTR_H
#define FIRM_BE_IA32_IA32_NODES_ATTR_H
27
28

#include "firm_types.h"
29
#include "bearch.h"
30
#include "irnode_t.h"
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/** ia32 condition codes (the numbers correspond to the real encoding order) */
typedef enum ia32_condition_code_t {
	ia32_cc_negated       = 0x01, /**< negates condition */

	ia32_cc_overflow      = 0x00,                                /**< OF=1 */
	ia32_cc_below         = 0x02,                                /**< CF=1 */
	ia32_cc_equal         = 0x04,                                /**< ZF=1 */
	ia32_cc_below_equal   = 0x06,                                /**< ZF=1 or CF=1 */
	ia32_cc_sign          = 0x08,                                /**< SF=1 */
	ia32_cc_parity        = 0x0A,                                /**< PF=1 */
	ia32_cc_less          = 0x0C,                                /**< SF!=OF */
	ia32_cc_less_equal    = 0x0E,                                /**< ZF=1 or SF!=OF */
	ia32_cc_not_overflow  = ia32_cc_negated|ia32_cc_overflow,    /**< OF=0 */
	ia32_cc_above_equal   = ia32_cc_negated|ia32_cc_below,       /**< CF=0 */
	ia32_cc_not_equal     = ia32_cc_negated|ia32_cc_equal,       /**< ZF=0 */
	ia32_cc_above         = ia32_cc_negated|ia32_cc_below_equal, /**< ZF=0 and CF=0 */
	ia32_cc_not_sign      = ia32_cc_negated|ia32_cc_sign,        /**< SF=0 */
	ia32_cc_not_parity    = ia32_cc_negated|ia32_cc_parity,      /**< PF=0 */
	ia32_cc_greater_equal = ia32_cc_negated|ia32_cc_less,        /**< SF=OF */
	ia32_cc_greater       = ia32_cc_negated|ia32_cc_less_equal,  /**< ZF=0 and SF=OF */

	/* the following codes are (unfortunately) NOT real hardware codes but
	 * simplify our backend as you need these combinations for some
	 * floatingpoint compares (the emitter will split them into multiple
	 * instructions) */
	ia32_cc_float_parity_cases = 0x20,
	/* we need even more cases as inversing the cc is different for float
	 * comparisons (though for the following we need no special
	 * parity+x combinations) */
	ia32_cc_additional_float_cases = 0x10,

	/* make sure that the lower 4 bit correspond to the real encoding
	 * (of the comparison not involving the parity special) */
	ia32_cc_float_equal        = 0x34,                                /**< PF=0 and ZF=1 */
	ia32_cc_float_below        = 0x32,                                /**< PF=0 and CF=1 */
	ia32_cc_float_below_equal  = 0x36,                                /**< PF=0 and (ZF=1 or CF=1) */
	ia32_cc_float_not_equal    = ia32_cc_negated|ia32_cc_float_equal, /**< PF=1 or ZF=0 */
	ia32_cc_float_unordered_above_equal
		= ia32_cc_negated|ia32_cc_float_below,                        /**< PF=1 or CF=0 */
	ia32_cc_float_unordered_above
		= ia32_cc_negated|ia32_cc_float_below_equal,                  /**< PF=1 or (ZF=0 and CF=0) */

	ia32_cc_float_unordered_below_equal = 0x16,                       /**< ZF=1 or CF=1 */
	ia32_cc_float_unordered_below       = 0x12,                       /**< CF=1 */
	ia32_cc_float_above        =
		ia32_cc_negated|ia32_cc_float_unordered_below_equal,          /**< ZF=0 and CF=0 */
	ia32_cc_float_above_equal
		= ia32_cc_negated|ia32_cc_float_unordered_below,              /**< CF=0 */
} ia32_condition_code_t;
ENUM_BITSET(ia32_condition_code_t)

static inline ia32_condition_code_t ia32_negate_condition_code(
		ia32_condition_code_t code)
{
	return code ^ ia32_cc_negated;
}

static inline ia32_condition_code_t ia32_invert_condition_code(
		ia32_condition_code_t code)
{
	/* doesn't appear to have any systematic, so use a table */
	switch (code) {
	case ia32_cc_below:              return ia32_cc_above;
	case ia32_cc_below_equal:        return ia32_cc_above_equal;
	case ia32_cc_above:              return ia32_cc_below;
	case ia32_cc_above_equal:        return ia32_cc_below_equal;
	case ia32_cc_less:               return ia32_cc_greater;
	case ia32_cc_less_equal:         return ia32_cc_greater_equal;
	case ia32_cc_greater:            return ia32_cc_less;
	case ia32_cc_greater_equal:      return ia32_cc_less_equal;
	case ia32_cc_float_below:        return ia32_cc_float_above;
	case ia32_cc_float_below_equal:  return ia32_cc_float_above_equal;
	case ia32_cc_float_above:        return ia32_cc_float_below;
	case ia32_cc_float_above_equal:  return ia32_cc_float_below_equal;
	case ia32_cc_float_unordered_below:       return ia32_cc_float_unordered_above;
	case ia32_cc_float_unordered_below_equal: return ia32_cc_float_unordered_above_equal;
	case ia32_cc_float_unordered_above:       return ia32_cc_float_unordered_below;
	case ia32_cc_float_unordered_above_equal: return ia32_cc_float_unordered_below_equal;
	default:                         return code;
	}
}
113

114
115
116
117
118
119
typedef enum {
	ia32_Normal,
	ia32_AddrModeD,
	ia32_AddrModeS
} ia32_op_type_t;

Matthias Braun's avatar
Matthias Braun committed
120
typedef enum {
121
122
123
124
	ia32_am_none   = 0,
	ia32_am_unary  = 1,
	ia32_am_binary = 2
} ia32_am_type_t;
Matthias Braun's avatar
Matthias Braun committed
125

126
typedef enum {
127
128
129
130
131
132
133
	match_commutative       = 1 << 0, /**< inputs are commutative */
	match_am_and_immediates = 1 << 1, /**< node supports AM and immediate at
	                                       the same time */
	match_am                = 1 << 2, /**< node supports (32bit) source AM */
	match_8bit_am           = 1 << 3, /**< node supports 8bit source AM */
	match_16bit_am          = 1 << 4, /**< node supports 16bit source AM */
	match_immediate         = 1 << 5, /**< node supports immediates */
134
135
136
137
138
139
140
141
142
143
144
145
	/** for 8/16 bit modes, mode_neutral operations can be emulated by their
	 * 32bit equivalents, they just don't care about the upper bits (they can be
	 * arbitrary before the insn and are unknown after the instruction). */
	match_mode_neutral      = 1 << 6,
	/** for 8/16 bit modes, zero_ext operations can be emulated by their
	 * 32bit equivalents, however the upper bits must be zero extended. */
	match_zero_ext          = 1 << 7,
	/** for 8/16 bit modes, upconv operations can be emulated by their
	 * 32bit equivalents, however the upper bits have to sign/zero extended
	 * based on the operations mode. */
	match_upconv            = 1 << 8,
	match_try_am            = 1 << 9, /**< only try to produce AM node, don't
146
	                                       do anything if AM isn't possible */
147
	match_two_users         = 1 << 10,/**< the instruction uses a load two times ... */
148
} match_flags_t;
149
ENUM_BITSET(match_flags_t)
150
151
152

typedef struct ia32_op_attr_t ia32_op_attr_t;
struct ia32_op_attr_t {
Matthias Braun's avatar
Matthias Braun committed
153
	//match_flags_t  flags;
154
	unsigned       latency;
155
156
};

157
158
#ifndef NDEBUG
typedef enum {
159
160
161
162
163
164
165
166
167
	IA32_ATTR_INVALID                = 0,
	IA32_ATTR_ia32_attr_t            = 1 << 0,
	IA32_ATTR_ia32_x87_attr_t        = 1 << 1,
	IA32_ATTR_ia32_asm_attr_t        = 1 << 2,
	IA32_ATTR_ia32_immediate_attr_t  = 1 << 3,
	IA32_ATTR_ia32_condcode_attr_t   = 1 << 4,
	IA32_ATTR_ia32_copyb_attr_t      = 1 << 5,
	IA32_ATTR_ia32_call_attr_t       = 1 << 6,
	IA32_ATTR_ia32_climbframe_attr_t = 1 << 7,
168
	IA32_ATTR_ia32_switch_attr_t     = 1 << 8,
169
170
171
} ia32_attr_type_t;
#endif

Michael Beck's avatar
Michael Beck committed
172
173
174
/**
 * The generic ia32 attributes. Every node has them.
 */
175
176
typedef struct ia32_attr_t ia32_attr_t;
struct ia32_attr_t {
177
	except_attr  exc;               /**< the exception attribute. MUST be the first one. */
Matthias Braun's avatar
Matthias Braun committed
178
	struct ia32_attr_data_bitfield {
179
180
181
182
		unsigned tp:3;                  /**< ia32 node type. */
		unsigned am_arity:2;            /**< Indicates the address mode type supported by this node. */
		unsigned am_scale:2;            /**< The address mode scale for index register. */
		unsigned am_sc_sign:1;          /**< The sign bit of the address mode symconst. */
Christian Würdig's avatar
Christian Würdig committed
183

184
		unsigned am_sc_no_pic_adjust : 1;/**< AM symconst can be relative to EIP */
185
		unsigned am_tls_segment:1;       /**< addresses are relative to TLS */
186
187
		unsigned use_frame:1;           /**< Indicates whether the operation uses the frame pointer or not. */
		unsigned has_except_label:1;        /**< Set if this node needs a label because of possible exception. */
Christian Würdig's avatar
Christian Würdig committed
188

189
		unsigned is_commutative:1;      /**< Indicates whether op is commutative or not. */
190

191
		unsigned need_stackent:1;       /**< Set to 1 if node need space on stack. */
192
		unsigned need_64bit_stackent:1; /**< needs a 64bit stack entity (see double->unsigned int conv) */
Matthias Braun's avatar
Matthias Braun committed
193
		unsigned need_32bit_stackent:1; /**< needs a 32bit stack entity */
194
195
		unsigned ins_permuted : 1;      /**< inputs of node have been permuted
		                                     (for commutative nodes) */
196
		unsigned is_reload : 1;         /**< node performs a reload */
197
198
		unsigned is_spill : 1;
		unsigned is_remat : 1;
199
200
	} data;

201
202
	int        am_offs;       /**< offsets for AddrMode */
	ir_entity *am_sc;         /**< SymConst for AddrMode */
203

204
205
	ir_mode   *ls_mode;       /**< Load/Store mode: This is the mode of the
	                               value that is manipulated by this node. */
206

207
	ir_entity *frame_ent; /**< the frame entity attached to this node */
208

209
210
	ir_label_t        exc_label;       /**< the exception label iff this instruction can throw an exception */

Michael Beck's avatar
Michael Beck committed
211
212
213
214
#ifndef NDEBUG
	const char       *orig_node;      /**< holds the name of the original ir node */
	unsigned          attr_type;      /**< bitfield indicating the attribute type */
#endif
215
};
216

217
218
219
220
221
222
223
224
225
226
/**
 * The attributes for a Call node.
 */
typedef struct ia32_call_attr_t ia32_call_attr_t;
struct ia32_call_attr_t {
	ia32_attr_t  attr;    /**< generic attribute */
	unsigned     pop;     /**< number of bytes that get popped by the callee */
	ir_type     *call_tp; /**< The call type, copied from the original Call node. */
};

Michael Beck's avatar
Michael Beck committed
227
228
229
230
231
/**
 * The attributes for nodes with condition code.
 */
typedef struct ia32_condcode_attr_t ia32_condcode_attr_t;
struct ia32_condcode_attr_t {
232
233
234
235
236
237
238
239
240
	ia32_attr_t           attr;           /**< generic attribute */
	ia32_condition_code_t condition_code; /**< condition code*/
};

/**
 * The attributes for Switches
 */
typedef struct ia32_switch_attr_t ia32_switch_attr_t;
struct ia32_switch_attr_t {
Matthias Braun's avatar
Matthias Braun committed
241
242
243
	ia32_attr_t            attr;        /**< generic attribute */
	const ir_switch_table *table;
	ir_entity             *jump_table;
Michael Beck's avatar
Michael Beck committed
244
245
246
247
248
249
250
251
252
253
254
255
256
257
};

/**
 * The attributes for CopyB code.
 */
typedef struct ia32_copyb_attr_t ia32_copyb_attr_t;
struct ia32_copyb_attr_t {
	ia32_attr_t  attr;      /**< generic attribute */
	unsigned     size;      /**< size of copied block */
};

/**
 * The attributes for immediates.
 */
258
259
typedef struct ia32_immediate_attr_t ia32_immediate_attr_t;
struct ia32_immediate_attr_t {
Michael Beck's avatar
Michael Beck committed
260
261
262
	ia32_attr_t  attr;              /**< generic attribute */
	ir_entity   *symconst;          /**< An entity if any. */
	long         offset;            /**< An offset if any. */
263
264
	unsigned     sc_sign : 1;       /**< The sign bit of the symconst. */
	unsigned     no_pic_adjust : 1; /**< constant can be relative to EIP */
265
266
};

Michael Beck's avatar
Michael Beck committed
267
268
269
/**
 * The attributes for x87 nodes.
 */
270
271
typedef struct ia32_x87_attr_t ia32_x87_attr_t;
struct ia32_x87_attr_t {
272
273
274
275
	ia32_attr_t            attr;       /**< the generic attribute */
	arch_register_t const *reg;        /**< The explicit register operand. */
	bool                   res_in_reg; /**< True if the result is in the explicit register operand, %st0 otherwise. */
	bool                   pop;        /**< Emit a pop suffix. */
276
277
};

278
279
280
281
282
283
284
285
286
287
288
typedef struct ia32_asm_reg_t ia32_asm_reg_t;
struct ia32_asm_reg_t {
	unsigned                   use_input  : 1; /* use input or output pos */
	unsigned                   valid      : 1;
	unsigned                   memory     : 1;
	unsigned                   dummy_fill : 13;
	unsigned                   inout_pos  : 16; /* in/out pos where the
	                                               register is assigned */
	const ir_mode             *mode;
};

Michael Beck's avatar
Michael Beck committed
289
290
291
/**
 * The attributes for ASM nodes.
 */
292
293
typedef struct ia32_asm_attr_t ia32_asm_attr_t;
struct ia32_asm_attr_t {
294
	ia32_attr_t           attr;         /**< the generic attribute */
295
296
	ident                *asm_text;
	const ia32_asm_reg_t *register_map;
297
298
};

299
300
301
302
303
304
305
306
307
/**
 * The attributes for the ClimbFrame node.
 */
typedef struct ia32_climbframe_attr_t ia32_climbframe_attr_t;
struct ia32_climbframe_attr_t {
	ia32_attr_t attr;      /**< generic attribute */
	unsigned    count;     /**< number of frames to climb up */
};

308
309
310
/* the following union is necessary to indicate to the compiler that we might want to cast
 * the structs (we use them to simulate OO-inheritance) */
union allow_casts_attr_t_ {
311
	ia32_attr_t            attr;
312
	ia32_call_attr_t       call_attr;
Michael Beck's avatar
Michael Beck committed
313
314
	ia32_condcode_attr_t   cc_attr;
	ia32_copyb_attr_t      cpy_attr;
315
316
317
	ia32_x87_attr_t        x87_attr;
	ia32_asm_attr_t        asm_attr;
	ia32_immediate_attr_t  immediate_attr;
318
	ia32_climbframe_attr_t climbframe_attr;
319
	ia32_switch_attr_t     switch_attr;
320
321
322
323
324
325
326
327
328
329
330
};

#ifndef NDEBUG
#define CAST_IA32_ATTR(type,ptr)        (assert( ((const ia32_attr_t*)(ptr))->attr_type & IA32_ATTR_ ## type ), (type*) (ptr))
#define CONST_CAST_IA32_ATTR(type,ptr)  (assert( ((const ia32_attr_t*)(ptr))->attr_type & IA32_ATTR_ ## type ), (const type*) (ptr))
#else
#define CAST_IA32_ATTR(type,ptr)        ((type*) (ptr))
#define CONST_CAST_IA32_ATTR(type,ptr)  ((const type*) (ptr))
#endif

#endif