1 /*
2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
3 *
4 * This file is part of libFirm.
5 *
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
10 *
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
14 *
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE.
18 */
19
20 /**
21 * @file
22 * @brief Handling of ia32 specific firm opcodes.
23 * @author Christian Wuerdig
24 *
25 * This file implements the creation of the architecture specific firm opcodes
26 * and the corresponding node constructors for the ia32 assembler irg.
27 */
28 #include "config.h"
29
30 #include <stdlib.h>
31 #include <stdbool.h>
32
33 #include "irargs_t.h"
34 #include "irprog_t.h"
35 #include "irgraph_t.h"
36 #include "irnode_t.h"
37 #include "irmode_t.h"
38 #include "ircons_t.h"
39 #include "iropt_t.h"
40 #include "irop.h"
41 #include "irverify_t.h"
42 #include "irprintf.h"
43 #include "iredges.h"
44 #include "error.h"
45 #include "raw_bitset.h"
46 #include "xmalloc.h"
47
48 #include "bearch.h"
49 #include "beinfo.h"
50
51 #include "bearch_ia32_t.h"
52 #include "ia32_common_transform.h"
53 #include "ia32_nodes_attr.h"
54 #include "ia32_new_nodes.h"
55 #include "gen_ia32_regalloc_if.h"
56
57 struct obstack opcodes_obst;
58
59 /**
60 * Dumper interface for dumping ia32 nodes in vcg.
61 * @param n the node to dump
62 * @param F the output file
63 * @param reason indicates which kind of information should be dumped
64 * @return 0 on success or != 0 on failure
65 */
ia32_dump_node(FILE * F,const ir_node * n,dump_reason_t reason)66 static void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
67 {
68 ir_mode *mode = NULL;
69
70 switch (reason) {
71 case dump_node_opcode_txt:
72 fprintf(F, "%s", get_irn_opname(n));
73
74 if (is_ia32_Immediate(n) || is_ia32_Const(n)) {
75 const ia32_immediate_attr_t *attr
76 = get_ia32_immediate_attr_const(n);
77
78 fputc(' ', F);
79 if (attr->symconst) {
80 if (attr->sc_sign) {
81 fputc('-', F);
82 }
83 fputs(get_entity_name(attr->symconst), F);
84 }
85 if (attr->offset != 0 || attr->symconst == NULL) {
86 if (attr->offset > 0 && attr->symconst != NULL) {
87 fputc('+', F);
88 }
89 fprintf(F, "%ld", attr->offset);
90 if (attr->no_pic_adjust) {
91 fputs("(no_pic_adjust)", F);
92 }
93 }
94 }
95 else {
96 const ia32_attr_t *attr = get_ia32_attr_const(n);
97
98 if (attr->am_sc != NULL || attr->am_offs != 0)
99 fputs(" [", F);
100
101 if (attr->am_sc != NULL) {
102 if (attr->data.am_sc_sign) {
103 fputc('-', F);
104 }
105 fputs(get_entity_name(attr->am_sc), F);
106 if (attr->data.am_sc_no_pic_adjust) {
107 fputs("(no_pic_adjust)", F);
108 }
109 }
110 if (attr->am_offs != 0) {
111 if (attr->am_offs > 0 && attr->am_sc != NULL) {
112 fputc('+', F);
113 }
114 fprintf(F, "%d", attr->am_offs);
115 }
116
117 if (attr->am_sc != NULL || attr->am_offs != 0)
118 fputc(']', F);
119 }
120 break;
121
122 case dump_node_mode_txt:
123 mode = get_ia32_ls_mode(n);
124 if (mode != NULL)
125 fprintf(F, "[%s]", get_mode_name(mode));
126 break;
127
128 case dump_node_nodeattr_txt:
129 if (! is_ia32_Lea(n)) {
130 if (is_ia32_AddrModeS(n)) {
131 fprintf(F, "[AM S] ");
132 } else if (is_ia32_AddrModeD(n)) {
133 fprintf(F, "[AM D] ");
134 }
135 }
136
137 break;
138
139 case dump_node_info_txt:
140 arch_dump_reqs_and_registers(F, n);
141
142 /* dump op type */
143 fprintf(F, "op = ");
144 switch (get_ia32_op_type(n)) {
145 case ia32_Normal:
146 fprintf(F, "Normal");
147 break;
148 case ia32_AddrModeD:
149 fprintf(F, "AM Dest (Load+Store)");
150 break;
151 case ia32_AddrModeS:
152 fprintf(F, "AM Source (Load)");
153 break;
154 default:
155 fprintf(F, "unknown (%d)", (int)get_ia32_op_type(n));
156 break;
157 }
158 fprintf(F, "\n");
159
160 /* dump supported am */
161 fprintf(F, "AM support = ");
162 switch (get_ia32_am_support(n)) {
163 case ia32_am_none: fputs("none\n", F); break;
164 case ia32_am_unary: fputs("source (unary)\n", F); break;
165 case ia32_am_binary: fputs("source (binary)\n", F); break;
166
167 default:
168 fprintf(F, "unknown (%d)\n", (int)get_ia32_am_support(n));
169 break;
170 }
171
172 /* dump AM offset */
173 if (get_ia32_am_offs_int(n) != 0) {
174 fprintf(F, "AM offset = %d\n", get_ia32_am_offs_int(n));
175 }
176
177 /* dump AM symconst */
178 if (get_ia32_am_sc(n) != NULL) {
179 ir_entity *ent = get_ia32_am_sc(n);
180 ident *id = get_entity_ld_ident(ent);
181 fprintf(F, "AM symconst = %s\n", get_id_str(id));
182 }
183
184 /* dump AM scale */
185 fprintf(F, "AM scale = %u\n", get_ia32_am_scale(n));
186
187 /* dump pn code */
188 if (is_ia32_CMovcc(n) || is_ia32_Setcc(n) || is_ia32_Jcc(n)) {
189 const ia32_attr_t *attr = get_ia32_attr_const(n);
190 fprintf(F, "condition_code = 0x%X\n", (unsigned)get_ia32_condcode(n));
191 fprintf(F, "ins_permuted = %u\n", (unsigned)attr->data.ins_permuted);
192 }
193 else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
194 fprintf(F, "size = %u\n", get_ia32_copyb_size(n));
195 }
196
197 fprintf(F, "use_frame = %d\n", is_ia32_use_frame(n));
198 fprintf(F, "commutative = %d\n", is_ia32_commutative(n));
199 fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n));
200 fprintf(F, "is reload = %d\n", is_ia32_is_reload(n));
201 fprintf(F, "latency = %u\n", get_ia32_latency(n));
202
203 /* dump frame entity */
204 fprintf(F, "frame entity = ");
205 if (get_ia32_frame_ent(n)) {
206 ir_fprintf(F, "%+F", get_ia32_frame_ent(n));
207 }
208 else {
209 fprintf(F, "n/a");
210 }
211 fprintf(F, "\n");
212
213 /* dump modes */
214 fprintf(F, "ls_mode = ");
215 if (get_ia32_ls_mode(n)) {
216 ir_fprintf(F, "%+F", get_ia32_ls_mode(n));
217 }
218 else {
219 fprintf(F, "n/a");
220 }
221 fprintf(F, "\n");
222
223 #ifndef NDEBUG
224 /* dump original ir node name */
225 fprintf(F, "orig node = ");
226 if (get_ia32_orig_node(n)) {
227 fprintf(F, "%s", get_ia32_orig_node(n));
228 }
229 else {
230 fprintf(F, "n/a");
231 }
232 fprintf(F, "\n");
233 #endif /* NDEBUG */
234
235 break;
236 }
237 }
238
239
240
get_ia32_attr(ir_node * node)241 ia32_attr_t *get_ia32_attr(ir_node *node)
242 {
243 assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
244 return (ia32_attr_t *)get_irn_generic_attr(node);
245 }
246
get_ia32_attr_const(const ir_node * node)247 const ia32_attr_t *get_ia32_attr_const(const ir_node *node)
248 {
249 assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
250 return (const ia32_attr_t*) get_irn_generic_attr_const(node);
251 }
252
get_ia32_x87_attr(ir_node * node)253 ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node)
254 {
255 ia32_attr_t *attr = get_ia32_attr(node);
256 ia32_x87_attr_t *x87_attr = CAST_IA32_ATTR(ia32_x87_attr_t, attr);
257 return x87_attr;
258 }
259
get_ia32_x87_attr_const(const ir_node * node)260 const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node)
261 {
262 const ia32_attr_t *attr = get_ia32_attr_const(node);
263 const ia32_x87_attr_t *x87_attr = CONST_CAST_IA32_ATTR(ia32_x87_attr_t, attr);
264 return x87_attr;
265 }
266
get_ia32_asm_attr_const(const ir_node * node)267 const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node)
268 {
269 const ia32_attr_t *attr = get_ia32_attr_const(node);
270 const ia32_asm_attr_t *asm_attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, attr);
271
272 return asm_attr;
273 }
274
get_ia32_immediate_attr(ir_node * node)275 ia32_immediate_attr_t *get_ia32_immediate_attr(ir_node *node)
276 {
277 ia32_attr_t *attr = get_ia32_attr(node);
278 ia32_immediate_attr_t *imm_attr = CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
279
280 return imm_attr;
281 }
282
get_ia32_immediate_attr_const(const ir_node * node)283 const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
284 {
285 const ia32_attr_t *attr = get_ia32_attr_const(node);
286 const ia32_immediate_attr_t *imm_attr = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
287
288 return imm_attr;
289 }
290
get_ia32_condcode_attr(ir_node * node)291 ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node)
292 {
293 ia32_attr_t *attr = get_ia32_attr(node);
294 ia32_condcode_attr_t *cc_attr = CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
295
296 return cc_attr;
297 }
298
get_ia32_condcode_attr_const(const ir_node * node)299 const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node)
300 {
301 const ia32_attr_t *attr = get_ia32_attr_const(node);
302 const ia32_condcode_attr_t *cc_attr = CONST_CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
303
304 return cc_attr;
305 }
306
get_ia32_switch_attr(ir_node * node)307 ia32_switch_attr_t *get_ia32_switch_attr(ir_node *node)
308 {
309 ia32_attr_t *attr = get_ia32_attr(node);
310 ia32_switch_attr_t *switch_attr = CAST_IA32_ATTR(ia32_switch_attr_t, attr);
311 return switch_attr;
312 }
313
get_ia32_switch_attr_const(const ir_node * node)314 const ia32_switch_attr_t *get_ia32_switch_attr_const(const ir_node *node)
315 {
316 const ia32_attr_t *attr = get_ia32_attr_const(node);
317 const ia32_switch_attr_t *switch_attr = CONST_CAST_IA32_ATTR(ia32_switch_attr_t, attr);
318 return switch_attr;
319 }
320
get_ia32_call_attr(ir_node * node)321 ia32_call_attr_t *get_ia32_call_attr(ir_node *node)
322 {
323 ia32_attr_t *attr = get_ia32_attr(node);
324 ia32_call_attr_t *call_attr = CAST_IA32_ATTR(ia32_call_attr_t, attr);
325
326 return call_attr;
327 }
328
get_ia32_call_attr_const(const ir_node * node)329 const ia32_call_attr_t *get_ia32_call_attr_const(const ir_node *node)
330 {
331 const ia32_attr_t *attr = get_ia32_attr_const(node);
332 const ia32_call_attr_t *call_attr = CONST_CAST_IA32_ATTR(ia32_call_attr_t, attr);
333
334 return call_attr;
335 }
336
get_ia32_copyb_attr(ir_node * node)337 ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node)
338 {
339 ia32_attr_t *attr = get_ia32_attr(node);
340 ia32_copyb_attr_t *copyb_attr = CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
341
342 return copyb_attr;
343 }
344
get_ia32_copyb_attr_const(const ir_node * node)345 const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node)
346 {
347 const ia32_attr_t *attr = get_ia32_attr_const(node);
348 const ia32_copyb_attr_t *copyb_attr = CONST_CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
349
350 return copyb_attr;
351 }
352
get_ia32_climbframe_attr(ir_node * node)353 ia32_climbframe_attr_t *get_ia32_climbframe_attr(ir_node *node)
354 {
355 ia32_attr_t *attr = get_ia32_attr(node);
356 ia32_climbframe_attr_t *climbframe_attr = CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);
357
358 return climbframe_attr;
359 }
360
get_ia32_climbframe_attr_const(const ir_node * node)361 const ia32_climbframe_attr_t *get_ia32_climbframe_attr_const(const ir_node *node)
362 {
363 const ia32_attr_t *attr = get_ia32_attr_const(node);
364 const ia32_climbframe_attr_t *climbframe_attr = CONST_CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);
365
366 return climbframe_attr;
367 }
368
369 /**
370 * Gets the type of an ia32 node.
371 */
get_ia32_op_type(const ir_node * node)372 ia32_op_type_t get_ia32_op_type(const ir_node *node)
373 {
374 const ia32_attr_t *attr = get_ia32_attr_const(node);
375 return (ia32_op_type_t)attr->data.tp;
376 }
377
378 /**
379 * Sets the type of an ia32 node.
380 */
set_ia32_op_type(ir_node * node,ia32_op_type_t tp)381 void set_ia32_op_type(ir_node *node, ia32_op_type_t tp)
382 {
383 ia32_attr_t *attr = get_ia32_attr(node);
384 attr->data.tp = tp;
385 }
386
get_ia32_am_support(const ir_node * node)387 ia32_am_type_t get_ia32_am_support(const ir_node *node)
388 {
389 const ia32_attr_t *attr = get_ia32_attr_const(node);
390 return (ia32_am_type_t)attr->data.am_arity;
391 }
392
393 /**
394 * Sets the supported address mode of an ia32 node
395 */
set_ia32_am_support(ir_node * node,ia32_am_type_t arity)396 void set_ia32_am_support(ir_node *node, ia32_am_type_t arity)
397 {
398 ia32_attr_t *attr = get_ia32_attr(node);
399 attr->data.am_arity = arity;
400 }
401
402 /**
403 * Gets the address mode offset as int.
404 */
get_ia32_am_offs_int(const ir_node * node)405 int get_ia32_am_offs_int(const ir_node *node)
406 {
407 const ia32_attr_t *attr = get_ia32_attr_const(node);
408 return attr->am_offs;
409 }
410
411 /**
412 * Sets the address mode offset from an int.
413 */
set_ia32_am_offs_int(ir_node * node,int offset)414 void set_ia32_am_offs_int(ir_node *node, int offset)
415 {
416 ia32_attr_t *attr = get_ia32_attr(node);
417 attr->am_offs = offset;
418 }
419
add_ia32_am_offs_int(ir_node * node,int offset)420 void add_ia32_am_offs_int(ir_node *node, int offset)
421 {
422 ia32_attr_t *attr = get_ia32_attr(node);
423 attr->am_offs += offset;
424 }
425
426 /**
427 * Returns the symconst entity associated to address mode.
428 */
get_ia32_am_sc(const ir_node * node)429 ir_entity *get_ia32_am_sc(const ir_node *node)
430 {
431 const ia32_attr_t *attr = get_ia32_attr_const(node);
432 return attr->am_sc;
433 }
434
435 /**
436 * Sets the symconst entity associated to address mode.
437 */
set_ia32_am_sc(ir_node * node,ir_entity * entity)438 void set_ia32_am_sc(ir_node *node, ir_entity *entity)
439 {
440 ia32_attr_t *attr = get_ia32_attr(node);
441 attr->am_sc = entity;
442 }
443
444 /**
445 * Sets the sign bit for address mode symconst.
446 */
set_ia32_am_sc_sign(ir_node * node)447 void set_ia32_am_sc_sign(ir_node *node)
448 {
449 ia32_attr_t *attr = get_ia32_attr(node);
450 attr->data.am_sc_sign = 1;
451 }
452
453 /**
454 * Clears the sign bit for address mode symconst.
455 */
clear_ia32_am_sc_sign(ir_node * node)456 void clear_ia32_am_sc_sign(ir_node *node)
457 {
458 ia32_attr_t *attr = get_ia32_attr(node);
459 attr->data.am_sc_sign = 0;
460 }
461
462 /**
463 * Returns the sign bit for address mode symconst.
464 */
is_ia32_am_sc_sign(const ir_node * node)465 int is_ia32_am_sc_sign(const ir_node *node)
466 {
467 const ia32_attr_t *attr = get_ia32_attr_const(node);
468 return attr->data.am_sc_sign;
469 }
470
set_ia32_am_tls_segment(ir_node * node,bool value)471 void set_ia32_am_tls_segment(ir_node *node, bool value)
472 {
473 ia32_attr_t *attr = get_ia32_attr(node);
474 attr->data.am_tls_segment = value;
475 }
476
get_ia32_am_tls_segment(const ir_node * node)477 bool get_ia32_am_tls_segment(const ir_node *node)
478 {
479 const ia32_attr_t *attr = get_ia32_attr_const(node);
480 return attr->data.am_tls_segment;
481 }
482
483 /**
484 * Gets the addr mode const.
485 */
get_ia32_am_scale(const ir_node * node)486 unsigned get_ia32_am_scale(const ir_node *node)
487 {
488 const ia32_attr_t *attr = get_ia32_attr_const(node);
489 return attr->data.am_scale;
490 }
491
492 /**
493 * Sets the index register scale for address mode.
494 */
set_ia32_am_scale(ir_node * node,unsigned scale)495 void set_ia32_am_scale(ir_node *node, unsigned scale)
496 {
497 ia32_attr_t *attr = get_ia32_attr(node);
498 assert(scale <= 3 && "AM scale out of range [0 ... 3]");
499 attr->data.am_scale = scale;
500 }
501
ia32_copy_am_attrs(ir_node * to,const ir_node * from)502 void ia32_copy_am_attrs(ir_node *to, const ir_node *from)
503 {
504 set_ia32_ls_mode(to, get_ia32_ls_mode(from));
505 set_ia32_am_scale(to, get_ia32_am_scale(from));
506 set_ia32_am_sc(to, get_ia32_am_sc(from));
507 if (is_ia32_am_sc_sign(from))
508 set_ia32_am_sc_sign(to);
509 add_ia32_am_offs_int(to, get_ia32_am_offs_int(from));
510 set_ia32_frame_ent(to, get_ia32_frame_ent(from));
511 if (is_ia32_use_frame(from))
512 set_ia32_use_frame(to);
513 }
514
515 /**
516 * Sets the uses_frame flag.
517 */
set_ia32_use_frame(ir_node * node)518 void set_ia32_use_frame(ir_node *node)
519 {
520 ia32_attr_t *attr = get_ia32_attr(node);
521 attr->data.use_frame = 1;
522 }
523
524 /**
525 * Clears the uses_frame flag.
526 */
clear_ia32_use_frame(ir_node * node)527 void clear_ia32_use_frame(ir_node *node)
528 {
529 ia32_attr_t *attr = get_ia32_attr(node);
530 attr->data.use_frame = 0;
531 }
532
533 /**
534 * Gets the uses_frame flag.
535 */
is_ia32_use_frame(const ir_node * node)536 int is_ia32_use_frame(const ir_node *node)
537 {
538 const ia32_attr_t *attr = get_ia32_attr_const(node);
539 return attr->data.use_frame;
540 }
541
542 /**
543 * Sets node to commutative.
544 */
set_ia32_commutative(ir_node * node)545 void set_ia32_commutative(ir_node *node)
546 {
547 ia32_attr_t *attr = get_ia32_attr(node);
548 attr->data.is_commutative = 1;
549 }
550
551 /**
552 * Sets node to non-commutative.
553 */
clear_ia32_commutative(ir_node * node)554 void clear_ia32_commutative(ir_node *node)
555 {
556 ia32_attr_t *attr = get_ia32_attr(node);
557 attr->data.is_commutative = 0;
558 }
559
560 /**
561 * Checks if node is commutative.
562 */
is_ia32_commutative(const ir_node * node)563 int is_ia32_commutative(const ir_node *node)
564 {
565 const ia32_attr_t *attr = get_ia32_attr_const(node);
566 return attr->data.is_commutative;
567 }
568
set_ia32_need_stackent(ir_node * node)569 void set_ia32_need_stackent(ir_node *node)
570 {
571 ia32_attr_t *attr = get_ia32_attr(node);
572 attr->data.need_stackent = 1;
573 }
574
clear_ia32_need_stackent(ir_node * node)575 void clear_ia32_need_stackent(ir_node *node)
576 {
577 ia32_attr_t *attr = get_ia32_attr(node);
578 attr->data.need_stackent = 0;
579 }
580
is_ia32_need_stackent(const ir_node * node)581 int is_ia32_need_stackent(const ir_node *node)
582 {
583 const ia32_attr_t *attr = get_ia32_attr_const(node);
584 return attr->data.need_stackent;
585 }
586
set_ia32_is_reload(ir_node * node)587 void set_ia32_is_reload(ir_node *node)
588 {
589 ia32_attr_t *attr = get_ia32_attr(node);
590 attr->data.is_reload = 1;
591 }
592
is_ia32_is_reload(const ir_node * node)593 int is_ia32_is_reload(const ir_node *node)
594 {
595 const ia32_attr_t *attr = get_ia32_attr_const(node);
596 return attr->data.is_reload;
597 }
598
set_ia32_is_spill(ir_node * node)599 void set_ia32_is_spill(ir_node *node)
600 {
601 ia32_attr_t *attr = get_ia32_attr(node);
602 attr->data.is_spill = 1;
603 }
604
is_ia32_is_spill(const ir_node * node)605 int is_ia32_is_spill(const ir_node *node)
606 {
607 const ia32_attr_t *attr = get_ia32_attr_const(node);
608 return attr->data.is_spill;
609 }
610
set_ia32_is_remat(ir_node * node)611 void set_ia32_is_remat(ir_node *node)
612 {
613 ia32_attr_t *attr = get_ia32_attr(node);
614 attr->data.is_remat = 1;
615 }
616
is_ia32_is_remat(const ir_node * node)617 int is_ia32_is_remat(const ir_node *node)
618 {
619 const ia32_attr_t *attr = get_ia32_attr_const(node);
620 return attr->data.is_remat;
621 }
622
623 /**
624 * Gets the mode of the stored/loaded value (only set for Store/Load)
625 */
get_ia32_ls_mode(const ir_node * node)626 ir_mode *get_ia32_ls_mode(const ir_node *node)
627 {
628 const ia32_attr_t *attr = get_ia32_attr_const(node);
629 return attr->ls_mode;
630 }
631
632 /**
633 * Sets the mode of the stored/loaded value (only set for Store/Load)
634 */
set_ia32_ls_mode(ir_node * node,ir_mode * mode)635 void set_ia32_ls_mode(ir_node *node, ir_mode *mode)
636 {
637 ia32_attr_t *attr = get_ia32_attr(node);
638 attr->ls_mode = mode;
639 }
640
641 /**
642 * Gets the frame entity assigned to this node.
643 */
get_ia32_frame_ent(const ir_node * node)644 ir_entity *get_ia32_frame_ent(const ir_node *node)
645 {
646 const ia32_attr_t *attr = get_ia32_attr_const(node);
647 return attr->frame_ent;
648 }
649
650 /**
651 * Sets the frame entity for this node.
652 */
set_ia32_frame_ent(ir_node * node,ir_entity * ent)653 void set_ia32_frame_ent(ir_node *node, ir_entity *ent)
654 {
655 ia32_attr_t *attr = get_ia32_attr(node);
656 attr->frame_ent = ent;
657 if (ent != NULL)
658 set_ia32_use_frame(node);
659 else
660 clear_ia32_use_frame(node);
661 }
662
663
664 /**
665 * Gets the instruction latency.
666 */
get_ia32_latency(const ir_node * node)667 unsigned get_ia32_latency(const ir_node *node)
668 {
669 const ir_op *op = get_irn_op(node);
670 const ia32_op_attr_t *op_attr = (ia32_op_attr_t*) get_op_attr(op);
671 return op_attr->latency;
672 }
673
get_ia32_switch_table(const ir_node * node)674 const ir_switch_table *get_ia32_switch_table(const ir_node *node)
675 {
676 const ia32_switch_attr_t *attr = get_ia32_switch_attr_const(node);
677 return attr->table;
678 }
679
get_ia32_condcode(const ir_node * node)680 ia32_condition_code_t get_ia32_condcode(const ir_node *node)
681 {
682 const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
683 return attr->condition_code;
684 }
685
686 /**
687 * Sets the condition code of a node
688 */
set_ia32_condcode(ir_node * node,ia32_condition_code_t code)689 void set_ia32_condcode(ir_node *node, ia32_condition_code_t code)
690 {
691 ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
692 attr->condition_code = code;
693 }
694
695 /**
696 * Returns the condition code of a node.
697 */
get_ia32_copyb_size(const ir_node * node)698 unsigned get_ia32_copyb_size(const ir_node *node)
699 {
700 const ia32_copyb_attr_t *attr = get_ia32_copyb_attr_const(node);
701 return attr->size;
702 }
703
704 /**
705 * Get the exception label attribute.
706 */
get_ia32_exc_label(const ir_node * node)707 unsigned get_ia32_exc_label(const ir_node *node)
708 {
709 const ia32_attr_t *attr = get_ia32_attr_const(node);
710 return attr->data.has_except_label;
711 }
712
713 /**
714 * Set the exception label attribute.
715 */
set_ia32_exc_label(ir_node * node,unsigned flag)716 void set_ia32_exc_label(ir_node *node, unsigned flag)
717 {
718 ia32_attr_t *attr = get_ia32_attr(node);
719 attr->data.has_except_label = flag;
720 }
721
722 /**
723 * Return the exception label id.
724 */
get_ia32_exc_label_id(const ir_node * node)725 ir_label_t get_ia32_exc_label_id(const ir_node *node)
726 {
727 const ia32_attr_t *attr = get_ia32_attr_const(node);
728
729 assert(attr->data.has_except_label);
730 return attr->exc_label;
731 }
732
733 /**
734 * Assign the exception label id.
735 */
set_ia32_exc_label_id(ir_node * node,ir_label_t id)736 void set_ia32_exc_label_id(ir_node *node, ir_label_t id)
737 {
738 ia32_attr_t *attr = get_ia32_attr(node);
739
740 assert(attr->data.has_except_label);
741 attr->exc_label = id;
742 }
743
744 #ifndef NDEBUG
745
746 /**
747 * Returns the name of the original ir node.
748 */
get_ia32_orig_node(const ir_node * node)749 const char *get_ia32_orig_node(const ir_node *node)
750 {
751 const ia32_attr_t *attr = get_ia32_attr_const(node);
752 return attr->orig_node;
753 }
754
ia32_get_old_node_name(const ir_node * irn)755 static const char *ia32_get_old_node_name(const ir_node *irn)
756 {
757 ir_graph *irg = get_irn_irg(irn);
758 struct obstack *obst = be_get_be_obst(irg);
759
760 lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn);
761 obstack_1grow(obst, 0);
762 return (const char*)obstack_finish(obst);
763 }
764
765 /**
766 * Sets the name of the original ir node.
767 */
set_ia32_orig_node(ir_node * node,const ir_node * old)768 void set_ia32_orig_node(ir_node *node, const ir_node *old)
769 {
770 const char *name = ia32_get_old_node_name(old);
771 ia32_attr_t *attr = get_ia32_attr(node);
772 attr->orig_node = name;
773 }
774
775 #endif /* NDEBUG */
776
777
778 /**
779 * Returns whether or not the node is an AddrModeS node.
780 */
is_ia32_AddrModeS(const ir_node * node)781 int is_ia32_AddrModeS(const ir_node *node)
782 {
783 const ia32_attr_t *attr = get_ia32_attr_const(node);
784 return (attr->data.tp == ia32_AddrModeS);
785 }
786
787 /**
788 * Returns whether or not the node is an AddrModeD node.
789 */
is_ia32_AddrModeD(const ir_node * node)790 int is_ia32_AddrModeD(const ir_node *node)
791 {
792 const ia32_attr_t *attr = get_ia32_attr_const(node);
793 return (attr->data.tp == ia32_AddrModeD);
794 }
795
ia32_swap_left_right(ir_node * node)796 void ia32_swap_left_right(ir_node *node)
797 {
798 ia32_attr_t *attr = get_ia32_attr(node);
799 ir_node *left = get_irn_n(node, n_ia32_binary_left);
800 ir_node *right = get_irn_n(node, n_ia32_binary_right);
801
802 assert(is_ia32_commutative(node));
803 attr->data.ins_permuted = !attr->data.ins_permuted;
804 set_irn_n(node, n_ia32_binary_left, right);
805 set_irn_n(node, n_ia32_binary_right, left);
806 }
807
808 /**
809 * Initializes the nodes attributes.
810 */
init_ia32_attributes(ir_node * node,arch_irn_flags_t flags,const arch_register_req_t ** in_reqs,int n_res)811 static void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
812 const arch_register_req_t **in_reqs,
813 int n_res)
814 {
815 ir_graph *irg = get_irn_irg(node);
816 struct obstack *obst = get_irg_obstack(irg);
817 ia32_attr_t *attr = get_ia32_attr(node);
818 backend_info_t *info;
819
820 arch_set_irn_flags(node, flags);
821 arch_set_irn_register_reqs_in(node, in_reqs);
822
823 #ifndef NDEBUG
824 attr->attr_type |= IA32_ATTR_ia32_attr_t;
825 #endif
826
827 info = be_get_info(node);
828 info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
829 memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
830 }
831
init_ia32_x87_attributes(ir_node * res)832 static void init_ia32_x87_attributes(ir_node *res)
833 {
834 ir_graph *irg = get_irn_irg(res);
835 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
836 #ifndef NDEBUG
837 ia32_attr_t *attr = get_ia32_attr(res);
838 attr->attr_type |= IA32_ATTR_ia32_x87_attr_t;
839 #else
840 (void) res;
841 #endif
842 irg_data->do_x87_sim = 1;
843 }
844
init_ia32_asm_attributes(ir_node * res)845 static void init_ia32_asm_attributes(ir_node *res)
846 {
847 #ifndef NDEBUG
848 ia32_attr_t *attr = get_ia32_attr(res);
849 attr->attr_type |= IA32_ATTR_ia32_asm_attr_t;
850 #else
851 (void) res;
852 #endif
853 }
854
init_ia32_immediate_attributes(ir_node * res,ir_entity * symconst,int symconst_sign,int no_pic_adjust,long offset)855 static void init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst,
856 int symconst_sign, int no_pic_adjust,
857 long offset)
858 {
859 ia32_immediate_attr_t *attr = (ia32_immediate_attr_t*)get_irn_generic_attr(res);
860
861 #ifndef NDEBUG
862 attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t;
863 #endif
864 attr->symconst = symconst;
865 attr->sc_sign = symconst_sign;
866 attr->no_pic_adjust = no_pic_adjust;
867 attr->offset = offset;
868 }
869
init_ia32_call_attributes(ir_node * res,unsigned pop,ir_type * call_tp)870 static void init_ia32_call_attributes(ir_node* res, unsigned pop,
871 ir_type* call_tp)
872 {
873 ia32_call_attr_t *attr = (ia32_call_attr_t*)get_irn_generic_attr(res);
874
875 #ifndef NDEBUG
876 attr->attr.attr_type |= IA32_ATTR_ia32_call_attr_t;
877 #endif
878 attr->pop = pop;
879 attr->call_tp = call_tp;
880 }
881
init_ia32_copyb_attributes(ir_node * res,unsigned size)882 static void init_ia32_copyb_attributes(ir_node *res, unsigned size)
883 {
884 ia32_copyb_attr_t *attr = (ia32_copyb_attr_t*)get_irn_generic_attr(res);
885
886 #ifndef NDEBUG
887 attr->attr.attr_type |= IA32_ATTR_ia32_copyb_attr_t;
888 #endif
889 attr->size = size;
890 }
891
init_ia32_condcode_attributes(ir_node * res,ia32_condition_code_t cc)892 static void init_ia32_condcode_attributes(ir_node *res,
893 ia32_condition_code_t cc)
894 {
895 ia32_condcode_attr_t *attr = (ia32_condcode_attr_t*)get_irn_generic_attr(res);
896
897 #ifndef NDEBUG
898 attr->attr.attr_type |= IA32_ATTR_ia32_condcode_attr_t;
899 #endif
900 attr->condition_code = cc;
901 }
902
init_ia32_climbframe_attributes(ir_node * res,unsigned count)903 static void init_ia32_climbframe_attributes(ir_node *res, unsigned count)
904 {
905 ia32_climbframe_attr_t *attr = (ia32_climbframe_attr_t*)get_irn_generic_attr(res);
906
907 #ifndef NDEBUG
908 attr->attr.attr_type |= IA32_ATTR_ia32_climbframe_attr_t;
909 #endif
910 attr->count = count;
911 }
912
init_ia32_switch_attributes(ir_node * node,const ir_switch_table * table)913 static void init_ia32_switch_attributes(ir_node *node,
914 const ir_switch_table *table)
915 {
916 unsigned n_outs = arch_get_irn_n_outs(node);
917 unsigned o;
918
919 ia32_switch_attr_t *attr = (ia32_switch_attr_t*) get_irn_generic_attr(node);
920 #ifndef NDEBUG
921 attr->attr.attr_type |= IA32_ATTR_ia32_switch_attr_t;
922 #endif
923 attr->table = table;
924
925 for (o = 0; o < n_outs; ++o) {
926 arch_set_irn_register_req_out(node, o, arch_no_register_req);
927 }
928 }
929
930 /* default compare operation to compare attributes */
ia32_compare_attr(const ia32_attr_t * a,const ia32_attr_t * b)931 static int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b)
932 {
933 if (a->data.tp != b->data.tp)
934 return 1;
935
936 if (a->data.am_scale != b->data.am_scale
937 || a->data.am_sc_sign != b->data.am_sc_sign
938 || a->am_offs != b->am_offs
939 || a->am_sc != b->am_sc
940 || a->data.am_sc_no_pic_adjust != b->data.am_sc_no_pic_adjust
941 || a->ls_mode != b->ls_mode)
942 return 1;
943
944 /* nodes with not yet assigned entities shouldn't be CSEd (important for
945 * unsigned int -> double conversions */
946 if (a->data.use_frame && a->frame_ent == NULL)
947 return 1;
948 if (b->data.use_frame && b->frame_ent == NULL)
949 return 1;
950
951 if (a->data.use_frame != b->data.use_frame
952 || a->frame_ent != b->frame_ent)
953 return 1;
954
955 if (a->data.has_except_label != b->data.has_except_label)
956 return 1;
957
958 if (a->data.ins_permuted != b->data.ins_permuted)
959 return 1;
960
961 return 0;
962 }
963
964 /** Compare nodes attributes for all "normal" nodes. */
ia32_compare_nodes_attr(const ir_node * a,const ir_node * b)965 static int ia32_compare_nodes_attr(const ir_node *a, const ir_node *b)
966 {
967 const ia32_attr_t* attr_a = get_ia32_attr_const(a);
968 const ia32_attr_t* attr_b = get_ia32_attr_const(b);
969
970 return ia32_compare_attr(attr_a, attr_b);
971 }
972
973 /** Compare node attributes for nodes with condition code. */
ia32_compare_condcode_attr(const ir_node * a,const ir_node * b)974 static int ia32_compare_condcode_attr(const ir_node *a, const ir_node *b)
975 {
976 const ia32_condcode_attr_t *attr_a;
977 const ia32_condcode_attr_t *attr_b;
978
979 if (ia32_compare_nodes_attr(a, b))
980 return 1;
981
982 attr_a = get_ia32_condcode_attr_const(a);
983 attr_b = get_ia32_condcode_attr_const(b);
984
985 if (attr_a->condition_code != attr_b->condition_code)
986 return 1;
987
988 return 0;
989 }
990
991 /** Compare node attributes for call nodes. */
ia32_compare_call_attr(const ir_node * a,const ir_node * b)992 static int ia32_compare_call_attr(const ir_node *a, const ir_node *b)
993 {
994 const ia32_call_attr_t *attr_a;
995 const ia32_call_attr_t *attr_b;
996
997 if (ia32_compare_nodes_attr(a, b))
998 return 1;
999
1000 attr_a = get_ia32_call_attr_const(a);
1001 attr_b = get_ia32_call_attr_const(b);
1002
1003 if (attr_a->pop != attr_b->pop)
1004 return 1;
1005
1006 if (attr_a->call_tp != attr_b->call_tp)
1007 return 1;
1008
1009 return 0;
1010 }
1011
1012 /** Compare node attributes for CopyB nodes. */
ia32_compare_copyb_attr(const ir_node * a,const ir_node * b)1013 static int ia32_compare_copyb_attr(const ir_node *a, const ir_node *b)
1014 {
1015 const ia32_copyb_attr_t *attr_a;
1016 const ia32_copyb_attr_t *attr_b;
1017
1018 if (ia32_compare_nodes_attr(a, b))
1019 return 1;
1020
1021 attr_a = get_ia32_copyb_attr_const(a);
1022 attr_b = get_ia32_copyb_attr_const(b);
1023
1024 if (attr_a->size != attr_b->size)
1025 return 1;
1026
1027 return 0;
1028 }
1029
1030
1031 /** Compare ASM node attributes. */
ia32_compare_asm_attr(const ir_node * a,const ir_node * b)1032 static int ia32_compare_asm_attr(const ir_node *a, const ir_node *b)
1033 {
1034 const ia32_asm_attr_t *attr_a;
1035 const ia32_asm_attr_t *attr_b;
1036
1037 if (ia32_compare_nodes_attr(a, b))
1038 return 1;
1039
1040 attr_a = get_ia32_asm_attr_const(a);
1041 attr_b = get_ia32_asm_attr_const(b);
1042
1043 if (attr_a->asm_text != attr_b->asm_text)
1044 return 1;
1045
1046 return 0;
1047 }
1048
1049 /**
1050 * Hash function for Immediates
1051 */
ia32_hash_Immediate(const ir_node * irn)1052 static unsigned ia32_hash_Immediate(const ir_node *irn)
1053 {
1054 const ia32_immediate_attr_t *a = get_ia32_immediate_attr_const(irn);
1055
1056 return hash_ptr(a->symconst) + (a->sc_sign << 16) + a->offset;
1057 }
1058
1059 /** Compare node attributes for Immediates. */
ia32_compare_immediate_attr(const ir_node * a,const ir_node * b)1060 static int ia32_compare_immediate_attr(const ir_node *a, const ir_node *b)
1061 {
1062 const ia32_immediate_attr_t *attr_a = get_ia32_immediate_attr_const(a);
1063 const ia32_immediate_attr_t *attr_b = get_ia32_immediate_attr_const(b);
1064
1065 if (attr_a->symconst != attr_b->symconst
1066 || attr_a->sc_sign != attr_b->sc_sign
1067 || attr_a->no_pic_adjust != attr_b->no_pic_adjust
1068 || attr_a->offset != attr_b->offset) {
1069 return 1;
1070 }
1071
1072 return 0;
1073 }
1074
1075 /** Compare node attributes for x87 nodes. */
ia32_compare_x87_attr(const ir_node * a,const ir_node * b)1076 static int ia32_compare_x87_attr(const ir_node *a, const ir_node *b)
1077 {
1078 return ia32_compare_nodes_attr(a, b);
1079 }
1080
1081 /** Compare node attributes for ClimbFrame nodes. */
ia32_compare_climbframe_attr(const ir_node * a,const ir_node * b)1082 static int ia32_compare_climbframe_attr(const ir_node *a, const ir_node *b)
1083 {
1084 const ia32_climbframe_attr_t *attr_a;
1085 const ia32_climbframe_attr_t *attr_b;
1086
1087 if (ia32_compare_nodes_attr(a, b))
1088 return 1;
1089
1090 attr_a = get_ia32_climbframe_attr_const(a);
1091 attr_b = get_ia32_climbframe_attr_const(b);
1092
1093 if (attr_a->count != attr_b->count)
1094 return 1;
1095
1096 return 0;
1097 }
1098
1099 /* copies the ia32 attributes */
ia32_copy_attr(ir_graph * irg,const ir_node * old_node,ir_node * new_node)1100 static void ia32_copy_attr(ir_graph *irg, const ir_node *old_node,
1101 ir_node *new_node)
1102 {
1103 struct obstack *obst = get_irg_obstack(irg);
1104 const ia32_attr_t *attr_old = get_ia32_attr_const(old_node);
1105 ia32_attr_t *attr_new = get_ia32_attr(new_node);
1106 backend_info_t *old_info = be_get_info(old_node);
1107 backend_info_t *new_info = be_get_info(new_node);
1108
1109 /* copy the attributes */
1110 memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
1111
1112 /* copy out flags */
1113 new_info->out_infos =
1114 DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
1115 new_info->in_reqs = old_info->in_reqs;
1116 new_info->flags = old_info->flags;
1117 }
1118
ia32_init_op(ir_op * op,unsigned latency)1119 static void ia32_init_op(ir_op *op, unsigned latency)
1120 {
1121 ia32_op_attr_t *attr = OALLOCZ(&opcodes_obst, ia32_op_attr_t);
1122 attr->latency = latency;
1123 set_op_attr(op, attr);
1124 }
1125
1126 /* Include the generated constructor functions */
1127 #include "gen_ia32_new_nodes.c.inl"
1128