besched: Change sched_foreach_reverse_from(sched_prev(x), y) to sched_foreach_reverse...
[libfirm] / ir / be / ia32 / ia32_common_transform.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief       This file implements the common parts of IR transformation from
9  *              firm into ia32-Firm.
10  * @author      Matthias Braun, Sebastian Buchwald
11  */
12 #include "config.h"
13
14 #include "error.h"
15 #include "ircons.h"
16 #include "irprintf.h"
17 #include "typerep.h"
18 #include "bitset.h"
19 #include "heights.h"
20
21 #include "betranshlp.h"
22 #include "beabi.h"
23
24 #include "ia32_architecture.h"
25 #include "ia32_common_transform.h"
26 #include "ia32_new_nodes.h"
27
28 #include "gen_ia32_new_nodes.h"
29 #include "gen_ia32_regalloc_if.h"
30
31 ir_heights_t *ia32_heights = NULL;
32
33 static int check_immediate_constraint(long val, char immediate_constraint_type)
34 {
35         switch (immediate_constraint_type) {
36                 case 'i': return 1;
37
38                 case 'I': return    0 <= val && val <=  31;
39                 case 'J': return    0 <= val && val <=  63;
40                 case 'K': return -128 <= val && val <= 127;
41                 case 'L': return val == 0xff || val == 0xffff;
42                 case 'M': return    0 <= val && val <=   3;
43                 case 'N': return    0 <= val && val <= 255;
44                 case 'O': return    0 <= val && val <= 127;
45
46                 default: panic("Invalid immediate constraint found");
47         }
48 }
49
50 ir_type *ia32_get_prim_type(const ir_mode *mode)
51 {
52         if (mode == ia32_mode_E) {
53                 return ia32_type_E;
54         } else {
55                 return get_type_for_mode(mode);
56         }
57 }
58
59 ir_entity *ia32_create_float_const_entity(ia32_isa_t *isa, ir_tarval *tv,
60                                           ident *name)
61 {
62         ir_entity        *res = pmap_get(ir_entity, isa->tv_ent, tv);
63         ir_initializer_t *initializer;
64         ir_mode          *mode;
65         ir_type          *tp;
66
67         if (res != NULL)
68                 return res;
69
70         mode = get_tarval_mode(tv);
71
72         if (! ia32_cg_config.use_sse2) {
73                 /* try to reduce the mode to produce smaller sized entities */
74                 if (mode != mode_F) {
75                         if (tarval_ieee754_can_conv_lossless(tv, mode_F)) {
76                                 mode = mode_F;
77                                 tv = tarval_convert_to(tv, mode);
78                         } else if (mode != mode_D) {
79                                 if (tarval_ieee754_can_conv_lossless(tv, mode_D)) {
80                                         mode = mode_D;
81                                         tv = tarval_convert_to(tv, mode);
82                                 }
83                         }
84                 }
85         }
86
87         if (name == NULL)
88                 name = id_unique("C%u");
89
90         tp  = ia32_get_prim_type(mode);
91         res = new_entity(get_glob_type(), name, tp);
92         set_entity_ld_ident(res, get_entity_ident(res));
93         set_entity_visibility(res, ir_visibility_private);
94         add_entity_linkage(res, IR_LINKAGE_CONSTANT);
95
96         initializer = create_initializer_tarval(tv);
97         set_entity_initializer(res, initializer);
98
99         pmap_insert(isa->tv_ent, tv, res);
100         return res;
101 }
102
103 ir_node *ia32_create_Immediate(ir_graph *const irg, ir_entity *const symconst, int const symconst_sign, long const val)
104 {
105         ir_node  *start_block = get_irg_start_block(irg);
106         ir_node  *immediate   = new_bd_ia32_Immediate(NULL, start_block, symconst,
107                         symconst_sign, ia32_no_pic_adjust, val);
108         arch_set_irn_register(immediate, &ia32_registers[REG_GP_NOREG]);
109
110         return immediate;
111 }
112
113 const arch_register_t *ia32_get_clobber_register(const char *clobber)
114 {
115         const arch_register_t       *reg = NULL;
116         int                          c;
117         size_t                       r;
118         const arch_register_class_t *cls;
119
120         /* TODO: construct a hashmap instead of doing linear search for clobber
121          * register */
122         for (c = 0; c < N_IA32_CLASSES; ++c) {
123                 cls = & ia32_reg_classes[c];
124                 for (r = 0; r < cls->n_regs; ++r) {
125                         const arch_register_t *temp_reg = arch_register_for_index(cls, r);
126                         if (strcmp(temp_reg->name, clobber) == 0
127                                         || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
128                                 reg = temp_reg;
129                                 break;
130                         }
131                 }
132                 if (reg != NULL)
133                         break;
134         }
135
136         return reg;
137 }
138
139 int ia32_mode_needs_gp_reg(ir_mode *mode)
140 {
141         if (mode == ia32_mode_fpcw)
142                 return 0;
143         if (get_mode_size_bits(mode) > 32)
144                 return 0;
145         return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
146 }
147
148 static void parse_asm_constraints(constraint_t *constraint, const char *c,
149                                   bool is_output)
150 {
151         char                         immediate_type     = '\0';
152         unsigned                     limited            = 0;
153         const arch_register_class_t *cls                = NULL;
154         int                          memory_possible       = 0;
155         int                          all_registers_allowed = 0;
156         int                          p;
157         int                          same_as = -1;
158
159         memset(constraint, 0, sizeof(constraint[0]));
160         constraint->same_as = -1;
161
162         if (*c == 0) {
163                 /* a memory constraint: no need to do anything in backend about it
164                  * (the dependencies are already respected by the memory edge of
165                  * the node) */
166                 return;
167         }
168
169         /* TODO: improve error messages with node and source info. (As users can
170          * easily hit these) */
171         while (*c != 0) {
172                 switch (*c) {
173                 case ' ':
174                 case '\t':
175                 case '\n':
176                         break;
177
178                 /* Skip out/in-out marker */
179                 case '=': break;
180                 case '+': break;
181
182                 case '&': break;
183
184                 case '*':
185                         ++c;
186                         break;
187                 case '#':
188                         while (*c != 0 && *c != ',')
189                                 ++c;
190                         break;
191
192                 case 'a':
193                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
194                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
195                         limited |= 1 << REG_GP_EAX;
196                         break;
197                 case 'b':
198                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
199                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
200                         limited |= 1 << REG_GP_EBX;
201                         break;
202                 case 'c':
203                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
204                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
205                         limited |= 1 << REG_GP_ECX;
206                         break;
207                 case 'd':
208                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
209                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
210                         limited |= 1 << REG_GP_EDX;
211                         break;
212                 case 'D':
213                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
214                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
215                         limited |= 1 << REG_GP_EDI;
216                         break;
217                 case 'S':
218                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
219                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
220                         limited |= 1 << REG_GP_ESI;
221                         break;
222                 case 'Q':
223                 case 'q':
224                         /* q means lower part of the regs only, this makes no
225                          * difference to Q for us (we only assign whole registers) */
226                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
227                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
228                         limited |= 1 << REG_GP_EAX | 1 << REG_GP_EBX | 1 << REG_GP_ECX |
229                                    1 << REG_GP_EDX;
230                         break;
231                 case 'A':
232                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
233                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
234                         limited |= 1 << REG_GP_EAX | 1 << REG_GP_EDX;
235                         break;
236                 case 'l':
237                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
238                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
239                         limited |= 1 << REG_GP_EAX | 1 << REG_GP_EBX | 1 << REG_GP_ECX |
240                                    1 << REG_GP_EDX | 1 << REG_GP_ESI | 1 << REG_GP_EDI |
241                                    1 << REG_GP_EBP;
242                         break;
243
244                 case 'R':
245                 case 'r':
246                 case 'p':
247                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
248                                 panic("multiple register classes not supported");
249                         cls                   = &ia32_reg_classes[CLASS_ia32_gp];
250                         all_registers_allowed = 1;
251                         break;
252
253                 case 'f':
254                 case 't':
255                 case 'u':
256                         /* TODO: mark values so the x87 simulator knows about t and u */
257                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_fp])
258                                 panic("multiple register classes not supported");
259                         cls                   = &ia32_reg_classes[CLASS_ia32_fp];
260                         all_registers_allowed = 1;
261                         break;
262
263                 case 'Y':
264                 case 'x':
265                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_xmm])
266                                 panic("multiple register classes not supproted");
267                         cls                   = &ia32_reg_classes[CLASS_ia32_xmm];
268                         all_registers_allowed = 1;
269                         break;
270
271                 case 'I':
272                 case 'J':
273                 case 'K':
274                 case 'L':
275                 case 'M':
276                 case 'N':
277                 case 'O':
278                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
279                                 panic("multiple register classes not supported");
280                         if (immediate_type != '\0')
281                                 panic("multiple immediate types not supported");
282                         cls            = &ia32_reg_classes[CLASS_ia32_gp];
283                         immediate_type = *c;
284                         break;
285                 case 'n':
286                 case 'i':
287                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
288                                 panic("multiple register classes not supported");
289                         if (immediate_type != '\0')
290                                 panic("multiple immediate types not supported");
291                         cls            = &ia32_reg_classes[CLASS_ia32_gp];
292                         immediate_type = 'i';
293                         break;
294
295                 case 'X':
296                 case 'g':
297                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
298                                 panic("multiple register classes not supported");
299                         if (immediate_type != '\0')
300                                 panic("multiple immediate types not supported");
301                         immediate_type        = 'i';
302                         cls                   = &ia32_reg_classes[CLASS_ia32_gp];
303                         all_registers_allowed = 1;
304                         memory_possible       = 1;
305                         break;
306
307                 case '0':
308                 case '1':
309                 case '2':
310                 case '3':
311                 case '4':
312                 case '5':
313                 case '6':
314                 case '7':
315                 case '8':
316                 case '9':
317                         if (is_output)
318                                 panic("can only specify same constraint on input");
319
320                         sscanf(c, "%d%n", &same_as, &p);
321                         if (same_as >= 0) {
322                                 c += p;
323                                 continue;
324                         }
325                         break;
326
327                 case 'm':
328                 case 'o':
329                 case 'V':
330                         /* memory constraint no need to do anything in backend about it
331                          * (the dependencies are already respected by the memory edge of
332                          * the node) */
333                         memory_possible = 1;
334                         break;
335
336                 case 'E': /* no float consts yet */
337                 case 'F': /* no float consts yet */
338                 case 's': /* makes no sense on x86 */
339                 case '<': /* no autodecrement on x86 */
340                 case '>': /* no autoincrement on x86 */
341                 case 'C': /* sse constant not supported yet */
342                 case 'G': /* 80387 constant not supported yet */
343                 case 'y': /* we don't support mmx registers yet */
344                 case 'Z': /* not available in 32 bit mode */
345                 case 'e': /* not available in 32 bit mode */
346                         panic("unsupported asm constraint '%c' found in (%+F)",
347                               *c, current_ir_graph);
348                 default:
349                         panic("unknown asm constraint '%c' found in (%+F)", *c,
350                               current_ir_graph);
351                 }
352                 ++c;
353         }
354
355         if (same_as >= 0) {
356                 if (cls != NULL)
357                         panic("same as and register constraint not supported");
358                 if (immediate_type != '\0')
359                         panic("same as and immediate constraint not supported");
360         }
361
362         if (cls == NULL && same_as < 0) {
363                 if (!memory_possible)
364                         panic("no constraint specified for assembler input");
365         }
366
367         constraint->same_as               = same_as;
368         constraint->cls                   = cls;
369         constraint->allowed_registers     = limited;
370         constraint->all_registers_allowed = all_registers_allowed;
371         constraint->memory_possible       = memory_possible;
372         constraint->immediate_type        = immediate_type;
373 }
374
375 static bool can_match(const arch_register_req_t *in,
376                       const arch_register_req_t *out)
377 {
378         if (in->cls != out->cls)
379                 return false;
380         if (!arch_register_req_is(in,  limited) ||
381             !arch_register_req_is(out, limited))
382                 return true;
383
384         return (*in->limited & *out->limited) != 0;
385 }
386
387 static inline ir_node *get_new_node(ir_node *node)
388 {
389 #ifdef FIRM_GRGEN_BE
390         if (be_transformer == TRANSFORMER_DEFAULT) {
391                 return be_transform_node(node);
392         } else {
393                 return node;
394         }
395 #else
396         return be_transform_node(node);
397 #endif
398 }
399
400 static arch_register_req_t const *ia32_make_register_req(ir_graph *irg, constraint_t const *constraint, int n_outs, arch_register_req_t const **out_reqs, int pos);
401
402 ir_node *ia32_gen_ASM(ir_node *node)
403 {
404         ir_node        *block        = get_nodes_block(node);
405         ir_node        *new_block    = get_new_node(block);
406         dbg_info       *dbgi         = get_irn_dbg_info(node);
407         int             n_inputs     = get_ASM_n_inputs(node);
408         int             n_ins        = n_inputs+1;
409         ir_node       **in           = ALLOCANZ(ir_node*, n_ins);
410         size_t          n_clobbers   = 0;
411         ident         **clobbers     = get_ASM_clobbers(node);
412         unsigned        reg_map_size = 0;
413         ir_graph       *irg          = get_irn_irg(node);
414         struct obstack *obst         = get_irg_obstack(irg);
415         unsigned        clobber_bits[N_IA32_CLASSES];
416         memset(&clobber_bits, 0, sizeof(clobber_bits));
417
418         for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) {
419                 const char                *clobber = get_id_str(clobbers[c]);
420                 const arch_register_req_t *req     = ia32_parse_clobber(clobber);
421                 if (req == NULL)
422                         continue;
423
424                 clobber_bits[req->cls->index] |= *req->limited;
425                 assert(req->cls->n_regs <= sizeof(unsigned)*8);
426                 ++n_clobbers;
427         }
428         size_t n_out_constraints = get_ASM_n_output_constraints(node);
429         size_t out_arity         = n_out_constraints + n_clobbers;
430
431         const ir_asm_constraint *in_constraints  = get_ASM_input_constraints(node);
432         const ir_asm_constraint *out_constraints = get_ASM_output_constraints(node);
433
434         /* determine size of register_map */
435         for (size_t out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
436                 const ir_asm_constraint *constraint = &out_constraints[out_idx];
437                 if (constraint->pos+1 > reg_map_size)
438                         reg_map_size = constraint->pos+1;
439         }
440         for (int i = 0; i < n_inputs; ++i) {
441                 const ir_asm_constraint *constraint = &in_constraints[i];
442                 if (constraint->pos+1 > reg_map_size)
443                         reg_map_size = constraint->pos+1;
444         }
445
446         ia32_asm_reg_t *const register_map = NEW_ARR_DZ(ia32_asm_reg_t, obst, reg_map_size);
447
448         /* construct output constraints */
449         size_t                      out_size = out_arity + 1;
450         const arch_register_req_t **out_reg_reqs
451                 = OALLOCN(obst, const arch_register_req_t*, out_size);
452
453         size_t out_idx;
454         for (out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
455                 constraint_t             parsed_constraint;
456                 const ir_asm_constraint *constraint = &out_constraints[out_idx];
457                 const char              *c          = get_id_str(constraint->constraint);
458                 unsigned                 pos        = constraint->pos;
459                 parse_asm_constraints(&parsed_constraint, c, true);
460                 arch_register_req_t const *const req = ia32_make_register_req(irg, &parsed_constraint, n_out_constraints, out_reg_reqs, out_idx);
461                 out_reg_reqs[out_idx] = req;
462
463                 /* multiple constraints for same pos. This can happen for example when
464                  * a =A constraint gets lowered to two constraints: =a and =d for the
465                  * same pos */
466                 if (register_map[pos].valid)
467                         continue;
468
469                 register_map[pos].use_input = 0;
470                 register_map[pos].valid     = 1;
471                 register_map[pos].memory    = 0;
472                 register_map[pos].inout_pos = out_idx;
473                 register_map[pos].mode      = constraint->mode;
474         }
475
476         /* inputs + input constraints */
477         const arch_register_req_t **in_reg_reqs
478                 = OALLOCN(obst, const arch_register_req_t*, n_ins);
479         for (int i = 0; i < n_inputs; ++i) {
480                 constraint_t               parsed_constraint;
481                 ir_node                   *pred         = get_ASM_input(node, i);
482                 const ir_asm_constraint   *constraint   = &in_constraints[i];
483                 ident                     *constr_id    = constraint->constraint;
484                 const char                *c            = get_id_str(constr_id);
485                 unsigned                   pos          = constraint->pos;
486                 int                        is_memory_op = 0;
487                 ir_node                   *input        = NULL;
488
489                 parse_asm_constraints(&parsed_constraint, c, false);
490                 if (parsed_constraint.cls != NULL) {
491                         unsigned r_clobber_bits
492                                 = clobber_bits[parsed_constraint.cls->index];
493                         if (r_clobber_bits != 0) {
494                                 if (parsed_constraint.all_registers_allowed) {
495                                         parsed_constraint.all_registers_allowed = 0;
496                                         be_set_allocatable_regs(irg,
497                                                         parsed_constraint.cls,
498                                                         &parsed_constraint.allowed_registers);
499                                 }
500                                 parsed_constraint.allowed_registers &= ~r_clobber_bits;
501                         }
502                 }
503
504                 arch_register_req_t const *const req = ia32_make_register_req(irg, &parsed_constraint, n_out_constraints, out_reg_reqs, i);
505                 in_reg_reqs[i] = req;
506
507                 if (parsed_constraint.immediate_type != '\0') {
508                         char imm_type = parsed_constraint.immediate_type;
509                         input = ia32_try_create_Immediate(pred, imm_type);
510                 }
511
512                 if (input == NULL) {
513                         input = get_new_node(pred);
514
515                         if (parsed_constraint.cls == NULL
516                                         && parsed_constraint.same_as < 0) {
517                                 is_memory_op = 1;
518                                 in_reg_reqs[i] = ia32_reg_classes[CLASS_ia32_gp].class_req;
519                         } else if (parsed_constraint.memory_possible) {
520                                 /* TODO: match Load or Load/Store if memory possible is set */
521                         }
522                 }
523                 in[i] = input;
524
525                 register_map[pos].use_input = 1;
526                 register_map[pos].valid     = 1;
527                 register_map[pos].memory    = is_memory_op;
528                 register_map[pos].inout_pos = i;
529                 register_map[pos].mode      = constraint->mode;
530         }
531
532         assert(n_inputs == n_ins-1);
533         ir_node *mem = get_ASM_mem(node);
534         in[n_inputs]          = be_transform_node(mem);
535         in_reg_reqs[n_inputs] = arch_no_register_req;
536
537         /* parse clobbers */
538         for (size_t c = 0; c < get_ASM_n_clobbers(node); ++c) {
539                 const char                *clobber = get_id_str(clobbers[c]);
540                 const arch_register_req_t *req     = ia32_parse_clobber(clobber);
541                 if (req == NULL)
542                         continue;
543                 out_reg_reqs[out_idx] = req;
544                 ++out_idx;
545         }
546
547         /* Attempt to make ASM node register pressure faithful.
548          * (This does not work for complicated cases yet!)
549          *
550          * Algorithm: Check if there are fewer inputs or outputs (I will call this
551          * the smaller list). Then try to match each constraint of the smaller list
552          * to 1 of the other list. If we can't match it, then we have to add a dummy
553          * input/output to the other list
554          *
555          * FIXME: This is still broken in lots of cases. But at least better than
556          *        before...
557          * FIXME: need to do this per register class...
558          */
559         if (out_arity <= (size_t)n_inputs) {
560                 int       orig_inputs = n_ins;
561                 int       in_size     = n_ins;
562                 bitset_t *used_ins    = bitset_alloca(n_ins);
563                 for (size_t o = 0; o < out_arity; ++o) {
564                         const arch_register_req_t *outreq = out_reg_reqs[o];
565
566                         if (outreq->cls == NULL) {
567                                 continue;
568                         }
569
570                         int i;
571                         for (i = 0; i < orig_inputs; ++i) {
572                                 if (bitset_is_set(used_ins, i))
573                                         continue;
574                                 const arch_register_req_t *inreq = in_reg_reqs[i];
575                                 if (!can_match(outreq, inreq))
576                                         continue;
577                                 bitset_set(used_ins, i);
578                                 break;
579                         }
580                         /* did we find any match? */
581                         if (i < orig_inputs)
582                                 continue;
583
584                         /* we might need more space in the input arrays */
585                         if (n_ins >= in_size) {
586                                 in_size *= 2;
587                                 const arch_register_req_t **new_in_reg_reqs
588                                         = OALLOCN(obst, const arch_register_req_t*,
589                                                           in_size);
590                                 memcpy(new_in_reg_reqs, in_reg_reqs,
591                                        n_ins*sizeof(new_in_reg_reqs[0]));
592                                 ir_node **new_in = ALLOCANZ(ir_node*, in_size);
593                                 memcpy(new_in, in, n_ins*sizeof(new_in[0]));
594
595                                 in_reg_reqs = new_in_reg_reqs;
596                                 in          = new_in;
597                         }
598
599                         /* add a new (dummy) input which occupies the register */
600                         assert(arch_register_req_is(outreq, limited));
601                         in_reg_reqs[n_ins] = outreq;
602                         in[n_ins]          = new_bd_ia32_ProduceVal(NULL, block);
603                         ++n_ins;
604                 }
605         } else {
606                 bitset_t *used_outs      = bitset_alloca(out_arity);
607                 size_t    orig_out_arity = out_arity;
608                 for (int i = 0; i < n_inputs; ++i) {
609                         const arch_register_req_t *inreq = in_reg_reqs[i];
610
611                         if (inreq->cls == NULL)
612                                 continue;
613
614                         size_t o;
615                         for (o = 0; o < orig_out_arity; ++o) {
616                                 const arch_register_req_t *outreq;
617                                 if (bitset_is_set(used_outs, o))
618                                         continue;
619                                 outreq = out_reg_reqs[o];
620                                 if (!can_match(outreq, inreq))
621                                         continue;
622                                 bitset_set(used_outs, i);
623                                 break;
624                         }
625                         /* did we find any match? */
626                         if (o < orig_out_arity)
627                                 continue;
628
629                         /* we might need more space in the output arrays */
630                         if (out_arity >= out_size) {
631                                 const arch_register_req_t **new_out_reg_reqs;
632
633                                 out_size *= 2;
634                                 new_out_reg_reqs
635                                         = OALLOCN(obst, const arch_register_req_t*, out_size);
636                                 memcpy(new_out_reg_reqs, out_reg_reqs,
637                                        out_arity * sizeof(new_out_reg_reqs[0]));
638                                 out_reg_reqs = new_out_reg_reqs;
639                         }
640
641                         /* add a new (dummy) output which occupies the register */
642                         assert(arch_register_req_is(inreq, limited));
643                         out_reg_reqs[out_arity] = inreq;
644                         ++out_arity;
645                 }
646         }
647
648         /* append none register requirement for the memory output */
649         if (out_arity + 1 >= out_size) {
650                 const arch_register_req_t **new_out_reg_reqs;
651
652                 out_size = out_arity + 1;
653                 new_out_reg_reqs
654                         = OALLOCN(obst, const arch_register_req_t*, out_size);
655                 memcpy(new_out_reg_reqs, out_reg_reqs,
656                            out_arity * sizeof(new_out_reg_reqs[0]));
657                 out_reg_reqs = new_out_reg_reqs;
658         }
659
660         /* add a new (dummy) output which occupies the register */
661         out_reg_reqs[out_arity] = arch_no_register_req;
662         ++out_arity;
663
664         ir_node *new_node = new_bd_ia32_Asm(dbgi, new_block, n_ins, in, out_arity,
665                                             get_ASM_text(node), register_map);
666
667         backend_info_t *info = be_get_info(new_node);
668         for (size_t o = 0; o < out_arity; ++o) {
669                 info->out_infos[o].req = out_reg_reqs[o];
670         }
671         arch_set_irn_register_reqs_in(new_node, in_reg_reqs);
672
673         SET_IA32_ORIG_NODE(new_node, node);
674
675         return new_node;
676 }
677
678 ir_node *ia32_gen_CopyB(ir_node *node)
679 {
680         ir_node  *block    = get_new_node(get_nodes_block(node));
681         ir_node  *src      = get_CopyB_src(node);
682         ir_node  *new_src  = get_new_node(src);
683         ir_node  *dst      = get_CopyB_dst(node);
684         ir_node  *new_dst  = get_new_node(dst);
685         ir_node  *mem      = get_CopyB_mem(node);
686         ir_node  *new_mem  = get_new_node(mem);
687         ir_node  *res      = NULL;
688         dbg_info *dbgi     = get_irn_dbg_info(node);
689         int      size      = get_type_size_bytes(get_CopyB_type(node));
690         int      throws_exception = ir_throws_exception(node);
691         int      rem;
692
693         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
694         /* then we need the size explicitly in ECX.                    */
695         if (size >= 32 * 4) {
696                 rem = size & 0x3; /* size % 4 */
697                 size >>= 2;
698
699                 res = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, size);
700
701                 res = new_bd_ia32_CopyB(dbgi, block, new_dst, new_src, res, new_mem, rem);
702         } else {
703                 if (size == 0) {
704                         ir_fprintf(stderr, "Optimization warning copyb %+F with size <4\n",
705                                    node);
706                 }
707                 res = new_bd_ia32_CopyB_i(dbgi, block, new_dst, new_src, new_mem, size);
708         }
709         ir_set_throws_exception(res, throws_exception);
710
711         SET_IA32_ORIG_NODE(res, node);
712
713         return res;
714 }
715
716 ir_node *ia32_gen_Proj_tls(ir_node *node)
717 {
718         ir_node *block = get_new_node(get_nodes_block(node));
719         ir_node *res   = new_bd_ia32_LdTls(NULL, block);
720         return res;
721 }
722
723 ir_node *ia32_gen_Unknown(ir_node *node)
724 {
725         ir_mode  *mode  = get_irn_mode(node);
726         ir_graph *irg   = current_ir_graph;
727         dbg_info *dbgi  = get_irn_dbg_info(node);
728         ir_node  *block = get_irg_start_block(irg);
729         ir_node  *res   = NULL;
730
731         if (mode_is_float(mode)) {
732                 if (ia32_cg_config.use_sse2) {
733                         res = new_bd_ia32_xUnknown(dbgi, block);
734                 } else {
735                         res = new_bd_ia32_fldz(dbgi, block);
736                 }
737         } else if (ia32_mode_needs_gp_reg(mode)) {
738                 res = new_bd_ia32_Unknown(dbgi, block);
739         } else {
740                 panic("unsupported Unknown-Mode");
741         }
742
743         return res;
744 }
745
746 static arch_register_req_t const *ia32_make_register_req(ir_graph *const irg, constraint_t const *const c, int const n_outs, arch_register_req_t const **const out_reqs, int const pos)
747 {
748         int const same_as = c->same_as;
749         if (same_as >= 0) {
750                 if (same_as >= n_outs)
751                         panic("invalid output number in same_as constraint");
752
753                 struct obstack            *const obst  = get_irg_obstack(irg);
754                 arch_register_req_t       *const req   = OALLOC(obst, arch_register_req_t);
755                 arch_register_req_t const *const other = out_reqs[same_as];
756                 *req            = *other;
757                 req->type      |= arch_register_req_type_should_be_same;
758                 req->other_same = 1U << pos;
759
760                 /* Switch constraints. This is because in firm we have same_as
761                  * constraints on the output constraints while in the gcc asm syntax
762                  * they are specified on the input constraints. */
763                 out_reqs[same_as] = req;
764                 return other;
765         }
766
767         /* Pure memory ops. */
768         if (!c->cls)
769                 return arch_no_register_req;
770
771         if (c->allowed_registers == 0 || c->all_registers_allowed)
772                 return c->cls->class_req;
773
774         struct obstack      *const obst    = get_irg_obstack(irg);
775         arch_register_req_t *const req     = (arch_register_req_t*)obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
776         unsigned            *const limited = (unsigned*)(req + 1);
777         *limited = c->allowed_registers;
778
779         memset(req, 0, sizeof(req[0]));
780         req->type    = arch_register_req_type_limited;
781         req->cls     = c->cls;
782         req->limited = limited;
783         req->width   = 1;
784         return req;
785 }
786
787 const arch_register_req_t *ia32_parse_clobber(const char *clobber)
788 {
789         if (strcmp(clobber, "memory") == 0 || strcmp(clobber, "cc") == 0)
790                 return NULL;
791
792         arch_register_t const *const reg = ia32_get_clobber_register(clobber);
793         if (!reg)
794                 panic("Register '%s' mentioned in asm clobber is unknown", clobber);
795
796         return reg->single_req;
797 }
798
799
800 int ia32_prevents_AM(ir_node *const block, ir_node *const am_candidate,
801                        ir_node *const other)
802 {
803         if (get_nodes_block(other) != block)
804                 return 0;
805
806         if (is_Sync(other)) {
807                 int i;
808
809                 for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
810                         ir_node *const pred = get_Sync_pred(other, i);
811
812                         if (get_nodes_block(pred) != block)
813                                 continue;
814
815                         /* Do not block ourselves from getting eaten */
816                         if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
817                                 continue;
818
819                         if (!heights_reachable_in_block(ia32_heights, pred, am_candidate))
820                                 continue;
821
822                         return 1;
823                 }
824
825                 return 0;
826         } else {
827                 /* Do not block ourselves from getting eaten */
828                 if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
829                         return 0;
830
831                 if (!heights_reachable_in_block(ia32_heights, other, am_candidate))
832                         return 0;
833
834                 return 1;
835         }
836 }
837
838 ir_node *ia32_try_create_Immediate(ir_node *node, char immediate_constraint_type)
839 {
840         ir_mode *const mode = get_irn_mode(node);
841         if (!mode_is_int(mode) && !mode_is_reference(mode))
842                 return NULL;
843
844         ir_node *cnst;
845         ir_node *symconst;
846         if (is_Const(node)) {
847                 cnst     = node;
848                 symconst = NULL;
849         } else if (is_SymConst_addr_ent(node)
850                         && get_entity_owner(get_SymConst_entity(node)) != get_tls_type()) {
851                 cnst     = NULL;
852                 symconst = node;
853         } else if (is_Add(node)) {
854                 ir_node *left  = get_Add_left(node);
855                 ir_node *right = get_Add_right(node);
856                 if (is_Const(left) && is_SymConst_addr_ent(right)) {
857                         cnst     = left;
858                         symconst = right;
859                 } else if (is_SymConst_addr_ent(left) && is_Const(right)) {
860                         cnst     = right;
861                         symconst = left;
862                 } else {
863                         return NULL;
864                 }
865         } else {
866                 return NULL;
867         }
868
869         long val = 0;
870         if (cnst != NULL) {
871                 ir_tarval *offset = get_Const_tarval(cnst);
872                 if (!tarval_is_long(offset)) {
873                         ir_fprintf(stderr, "Optimisation Warning: tarval of %+F is not a long?\n", cnst);
874                         return NULL;
875                 }
876
877                 val = get_tarval_long(offset);
878                 if (!check_immediate_constraint(val, immediate_constraint_type))
879                         return NULL;
880         }
881
882         ir_entity *symconst_ent = NULL;
883         if (symconst != NULL) {
884                 /* we need full 32bits for symconsts */
885                 if (immediate_constraint_type != 'i')
886                         return NULL;
887
888                 symconst_ent = get_SymConst_entity(symconst);
889         }
890
891         ir_graph *const irg = get_irn_irg(node);
892         return ia32_create_Immediate(irg, symconst_ent, 0, val);
893 }