i86: turn off backend debug prints
[people/dverkamp/gcc.git] / gcc / config / i86 / i86.c
1 #include <stdio.h>
2
3 #include "config.h"
4 #include "system.h"
5 #include "coretypes.h"
6 #include "tm.h"
7 #include "rtl.h"
8 #include "tree.h"
9 #include "tm_p.h"
10 #include "regs.h"
11 #include "hard-reg-set.h"
12 #include "real.h"
13 #include "insn-config.h"
14 #include "conditions.h"
15 #include "output.h"
16 #include "insn-codes.h"
17 #include "insn-attr.h"
18 #include "flags.h"
19 #include "except.h"
20 #include "function.h"
21 #include "recog.h"
22 #include "expr.h"
23 #include "optabs.h"
24 #include "toplev.h"
25 #include "basic-block.h"
26 #include "ggc.h"
27 #include "target.h"
28 #include "target-def.h"
29 #include "langhooks.h"
30 #include "cgraph.h"
31 #include "tree-gimple.h"
32 #include "dwarf2.h"
33 #include "df.h"
34 #include "tm-constrs.h"
35 #include "params.h"
36
37 static void i86_file_start (void);
38 static rtx  i86_function_value (tree, tree, bool);
39 static bool i86_rtx_costs (rtx x, int code, int outer_code_i, int *total);
40
41 const enum reg_class regclass_map[] = { AREG, AREG,  DREG, DREG,  CREG, CREG,
42                                         BREG, BREG,  SIREG, SIREG,  DIREG, DIREG,
43                                         BPREG, BPREG,  GENERAL_REGS, GENERAL_REGS };
44
45 static const char *register_names[] = REGISTER_NAMES;
46
47
48 /* Table of valid machine attributes.  */
49 static const struct attribute_spec i86_attribute_table[] =
50 {
51 #ifdef SUBTARGET_ATTRIBUTE_TABLE
52   SUBTARGET_ATTRIBUTE_TABLE,
53 #endif
54   { NULL,        0, 0, false, false, false, NULL }
55 };
56
57 /* Initialize the GCC target structure.  */
58 #undef TARGET_ATTRIBUTE_TABLE
59 #define TARGET_ATTRIBUTE_TABLE i86_attribute_table
60
61 #undef TARGET_ASM_OPEN_PAREN
62 #define TARGET_ASM_OPEN_PAREN "("
63 #undef TARGET_ASM_CLOSE_PAREN
64 #define TARGET_ASM_CLOSE_PAREN ")"
65
66 #undef TARGET_ASM_ALIGNED_HI_OP
67 #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
68
69 #undef TARGET_ASM_UNALIGNED_HI_OP
70 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
71
72 #undef TARGET_ASM_FILE_START
73 #define TARGET_ASM_FILE_START i86_file_start
74
75 #undef TARGET_PROMOTE_PROTOTYPES
76 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
77
78 #undef TARGET_FUNCTION_VALUE
79 #define TARGET_FUNCTION_VALUE i86_function_value
80
81 #undef TARGET_RTX_COSTS
82 #define TARGET_RTX_COSTS i86_rtx_costs
83
84 struct gcc_target targetm = TARGET_INITIALIZER;
85
86
87 int
88 i86_reg_class_from_letter(int c)
89 {
90   switch (c)
91   {
92   case 'a': return AREG;
93   case 'b': return BREG;
94   case 'c': return CREG;
95   case 'd': return DREG;
96   case 'S': return SIREG;
97   case 'D': return DIREG;
98   case 'B': return BPREG;
99   case 'r': return GENERAL_REGS;
100   case 'q': return Q_REGS;
101   }
102   return NO_REGS;
103 }
104
105 int
106 i86_const_ok_for_letter_p(int v, int c)
107 {
108   switch (c)
109   {
110   case 'I':
111     /* The constant that we can shift by: shl ax,1 */
112     return v >= 0 && v <= 31;
113   case 'J':
114     /* I/O ports and byte registers */
115     return v >= 0 && v <= 255;
116   }
117   return 0;
118 }
119
120 /* The purpose of this function is to decide if "x" represents
121    an addressing mode that the assembler can handle directly.  If
122    not, gcc will simplify it.
123
124 */
125
126 #define DEBUG 0
127
128 /* g: general-purpose
129    b: base
130    i: index
131    s: stack
132
133    ax dx cx bx si di bp sp
134 */
135 static char packreg[] = "gugugubuiuiubusu";
136 static char *
137 pack_rtx(rtx r, char *buf, char *ebuf, int strict)
138 {
139   if (buf >= ebuf)
140     return buf;
141   switch (GET_CODE(r))
142   {
143   case PLUS:
144     *buf++ = '+';
145     buf = pack_rtx(XEXP(r,0), buf, ebuf, strict);
146     buf = pack_rtx(XEXP(r,1), buf, ebuf, strict);
147     break;
148   case MEM:
149     *buf++ = 'm';
150     buf = pack_rtx(XEXP(r,0), buf, ebuf, strict);
151     break;
152   case PRE_DEC:
153     *buf++ = '<';
154     buf = pack_rtx(XEXP(r,0), buf, ebuf, strict);
155     break;
156   case REG:
157     if (strict || REGNO(r)<FIRST_PSEUDO_REGISTER)
158       *buf++ = REGNO(r) >= FIRST_PSEUDO_REGISTER ? '?' : packreg[REGNO(r)];
159     else
160       *buf++ = 'p';
161     break;
162   case CONST:
163   case CONST_INT:
164   case SYMBOL_REF:
165     *buf++ = '#';
166     break;
167   default:
168     *buf++ = '?';
169     break;
170   }
171   return buf;
172 }
173
174 static const char *valid_addr_list[] = {
175   "#",
176   "b",
177   "i",
178   "p",
179   "+bi",
180   "+ib",
181   "+pi",
182   "+ip",
183   "+pb",
184   "+bp",
185   "+pp",
186   "+b#",
187   "+i#",
188   "+p#",
189   "++bi#",
190   "++ib#",
191   "++pi#",
192   "++ip#",
193   "++pb#",
194   "++bp#",
195   "++pp#",
196   "<s",
197   "<p",
198   0
199 };
200
201 int
202 i86_valid_addr(enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, int strict)
203 {
204   int i;
205   char packed[20];
206   *pack_rtx(x, packed, packed+20, strict) = 0;
207 #if DEBUG
208   print_rtl(stdout, x);
209   printf(" mode %s %s: `%s'   ", mode_name[mode], strict?"strict":"", packed);
210 #endif
211
212   for (i=0; valid_addr_list[i]; i++)
213   {
214     const char *v = valid_addr_list[i];
215     if (*v == '!')
216     {
217       if (strict)
218         continue;
219       v++;
220     }
221     if (strcmp(packed, v) == 0)
222     {
223 #if DEBUG
224       printf("yup\n");
225 #endif
226       return 1;
227     }
228   }
229 #if DEBUG
230   printf("nope\n");
231 #endif
232   return 0;
233 }
234
235 void
236 i86_notice_update_cc(rtx e ATTRIBUTE_UNUSED)
237 {
238   CC_STATUS_INIT;
239 }
240
241
242 /* Generate a "push" pattern for input ARG.  */
243 static rtx
244 gen_push (rtx arg, enum machine_mode mode)
245 {
246   return gen_rtx_SET (VOIDmode,
247                       gen_rtx_MEM (mode,
248                                    gen_rtx_PRE_DEC (Pmode,
249                                                     stack_pointer_rtx)),
250                       arg);
251 }
252
253 static int
254 i86_need_save (int regno)
255 {
256   return df_regs_ever_live_p (regno) && ! call_used_regs[regno];
257 }
258
259 void
260 i86_expand_prologue (void)
261 {
262   rtx insn;
263   int regno;
264   HOST_WIDE_INT size = get_frame_size ();
265
266   /* Enter is 4 bytes, the normal prologue is 3 bytes if size
267      is zero, otherwise 5 or 6 bytes. */
268   if (size) {
269     insn = emit_insn (gen_enterhi1 (gen_int_mode (size, Pmode)));
270     RTX_FRAME_RELATED_P (insn) = 1;
271   } else {
272     insn = emit_insn (gen_push (hard_frame_pointer_rtx, Pmode));
273     RTX_FRAME_RELATED_P (insn) = 1;
274
275     insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
276     RTX_FRAME_RELATED_P (insn) = 1;
277
278 #if 0
279     /* This code is unreachable, since enter is always used. */
280     if (size) {
281       insn = emit_insn (gen_subhi3 (stack_pointer_rtx, stack_pointer_rtx,
282                         gen_int_mode (size, Pmode)));
283       RTX_FRAME_RELATED_P (insn) = 1;
284     }
285 #endif
286   }
287
288   for (regno = REG_DI; regno >= REG_AX; regno -= 2) {
289     if (i86_need_save (regno+1)) {
290       insn = emit_insn (gen_push (gen_rtx_REG (SImode, regno), SImode));
291       RTX_FRAME_RELATED_P (insn) = 1;
292     } else if (i86_need_save (regno)) {
293       insn = emit_insn (gen_push (gen_rtx_REG (HImode, regno), HImode));
294       RTX_FRAME_RELATED_P (insn) = 1;
295     }
296   }    
297 }
298
299 void
300 i86_expand_epilogue (int style)
301 {
302   int regno;
303
304   for (regno = REG_AX; regno <= REG_DI; regno += 2) {
305     if (i86_need_save (regno+1)) {
306       emit_insn(gen_popsi1 (gen_rtx_REG (SImode, regno)));
307     } else if (i86_need_save (regno)) {
308       emit_insn(gen_pophi1 (gen_rtx_REG (HImode, regno)));
309     }
310   }
311
312   emit_insn (gen_leavehi ());
313
314   /* If style == 0 then this is a sibcall; no return instruction */
315   if (style)
316     emit_jump_insn (gen_return_internal ());
317 }
318
319 static void
320 print_reg (rtx x, int c, FILE *s)
321 {
322   enum machine_mode mode = GET_MODE (x);
323
324   gcc_assert (GET_CODE(x) == REG);
325
326   switch (c) {
327   case 'b':
328   case 'L':
329   case 'H':
330     mode = QImode;
331     break;
332   case 'w':
333     mode = HImode;
334     break;
335   case 'd':
336   case 'D':
337     mode = SImode;
338     break;
339   case 'q':                     /* First DImode register */
340     mode = DImode;
341     break;
342   default:
343     break;
344   }
345   
346   switch (mode) {
347   case QImode:
348     gcc_assert (REGNO(x) < REG_SI);
349     fprintf (s, "%%%c%c", register_names[REGNO(x)][0],
350              (c == 'H') ? 'h' : 'l');
351     break;
352   case HImode:
353     fprintf (s, "%%%s", register_names[REGNO(x)]);
354     break;
355   case SImode:
356   case DImode:
357     {
358       int nr = (c == 'D') ? 2 : 0;
359       fprintf (s, "%%e%s", register_names[REGNO(x)+nr]);
360     }
361     break;
362   default:
363     gcc_unreachable ();
364   }
365 }
366
367 void
368 i86_print_operand(FILE *s, rtx x, int c)
369 {
370 #if DEBUG
371   printf("[i86_print_operand(%c)]\n", c?c:' ');
372   print_rtl(stdout, x);
373   printf("\n");
374 #endif
375   switch (GET_CODE (x))
376   {
377   case REG:
378     print_reg (x, c, s);
379     break;
380     break;
381
382   case MEM:
383     x = XEXP (x,0);
384     if (c == 'P') {
385       i86_print_operand(s, x, 0);
386     } else {
387       if (c == 'D')
388         fprintf (s, "4+");
389       i86_print_operand_address(s, x);
390     }
391     break;
392
393   case PLUS:
394     i86_print_operand(s, XEXP(x,0), 0);
395     if (GET_CODE(XEXP(x,1)) == CONST_INT)
396     {
397       fprintf(s, "%+d", (int)INTVAL(XEXP(x,1))); /* offset */
398     }
399     else
400     {
401       fputc('+', s);
402       i86_print_operand(s, XEXP(x,1), 0);
403     }
404     break;
405   case SYMBOL_REF:
406     assemble_name(s, XSTR(x,0));
407     break;
408   case CONST:
409   case CONST_INT:
410   case CODE_LABEL:
411     fputc('$', s);
412     output_addr_const(s, x);
413     break;
414   default:
415     printf("blah! default in i86_print_operand %d\n", GET_CODE(x));
416     break;
417     }
418 }
419
420 struct i86_address {
421   rtx base;
422   rtx index;
423   rtx disp;
424 };
425
426 /* Heavily cribbed from i386 ix86_decompose_address() */
427 static int
428 i86_decompose_address (rtx addr, struct i86_address *out)
429 {
430   rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
431   rtx base_reg, index_reg;
432   int retval = 1;
433   
434   if (REG_P (addr) || GET_CODE (addr) == SUBREG)
435     base = addr;
436   else if (GET_CODE (addr) == PLUS)
437     {
438       rtx addends[3], op;
439       int n = 0, i;
440
441       op = addr;
442       do
443         {
444           if (n >= 3)
445             return 0;
446           addends[n++] = XEXP (op, 1);
447           op = XEXP (op, 0);
448         }
449
450       while (GET_CODE (op) == PLUS);
451       if (n >= 3)
452         return 0;
453       addends[n] = op;
454
455       for (i = n; i >= 0; --i)
456         {
457           op = addends[i];
458           switch (GET_CODE (op))
459             {
460             case REG:
461             case SUBREG:
462               if (!base)
463                 base = op;
464               else if (!index)
465                 index = op;
466               else
467                 return 0;
468               break;
469
470             case CONST:
471             case CONST_INT:
472             case SYMBOL_REF:
473             case LABEL_REF:
474               if (disp)
475                 return 0;
476               disp = op;
477               break;
478
479             default:
480               return 0;
481             }
482         }
483     }
484   else
485     disp = addr;                        /* displacement */
486
487   base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
488   index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
489
490   /* Special case: (%bp) can only be encoded as 0(%bp).  The assembler
491      would do the right thing, but cost accounting would be off. */
492   if ((base_reg == hard_frame_pointer_rtx
493        || base_reg == frame_pointer_rtx
494        || base_reg == arg_pointer_rtx) && !disp)
495     disp = const0_rtx;
496
497   out->base = base_reg;
498   out->index = index;
499   out->disp = disp;
500
501   return retval;
502 }
503
504 void
505 i86_print_operand_address(FILE *s, rtx x)
506 {
507   struct i86_address parts;
508   rtx base, index, disp;
509   int ok = i86_decompose_address (x, &parts);
510
511 #if DEBUG
512   printf("[i86_print_operand_address] ok = %d\n", ok);
513   print_rtl(stdout, x);
514   printf("\n");
515 #endif
516
517   gcc_assert (ok);
518
519   base = parts.base;
520   index = parts.index;
521   disp = parts.disp;
522
523 #if DEBUG
524   printf("base =\n");
525   print_rtl(stdout, base);
526   printf("index =\n");
527   print_rtl(stdout, index);
528   printf("disp =\n");
529   print_rtl(stdout, disp);
530 #endif
531
532   if (disp) {
533     if (GET_CODE (disp) == LABEL_REF)
534       output_asm_label (disp);
535     else
536       output_addr_const (s, disp);
537   }
538
539   if (base || index) {
540     putc ('(', s);
541     if (base)
542       print_reg (base, 0, s);
543     if (index) {
544       putc(',', s);
545       print_reg (index, 0, s);
546     }
547     putc (')', s);
548   }
549 }
550
551 static void
552 i86_file_start (void)
553 {
554   default_file_start ();
555
556   fprintf (asm_out_file, "\t.code16\n\n");
557 }
558
559 static rtx
560 i86_function_value (tree valtype, tree fntype_or_decl ATTRIBUTE_UNUSED,
561                      bool outgoing ATTRIBUTE_UNUSED)
562 {
563   /* return everything in %ax (FIXME) */
564   return gen_rtx_REG (TYPE_MODE( valtype ), REG_AX);
565 }
566
567
568 /* Return the cost of moving data from a register in class CLASS1 to
569    one in class CLASS2.
570
571    It is not required that the cost always equal 2 when FROM is the same as TO;
572    on some machines it is expensive to move between registers if they are not
573    general registers.  */
574
575 int
576 i86_register_move_cost (enum machine_mode mode, enum reg_class class1,
577                          enum reg_class class2)
578 {
579   return 2;
580 }
581
582
583 /* Return the cost of moving data of mode M between a
584    register and memory.  A value of 2 is the default; this cost is
585    relative to those in `REGISTER_MOVE_COST'.
586
587    If moving between registers and memory is more expensive than
588    between two registers, you should define this macro to express the
589    relative cost.
590
591    Model also increased moving costs of QImode registers in non
592    Q_REGS classes.
593  */
594 int
595 i86_memory_move_cost (enum machine_mode mode, enum reg_class regclass, int in)
596 {
597   if (mode == SImode)
598     return 3;
599   else
600     return 2;
601 }
602
603
604 /* Compute a (partial) cost for rtx X.  Return true if the complete
605    cost has been computed, and false if subexpressions should be
606    scanned.  In either case, *TOTAL contains the cost result.  */
607
608 static bool
609 i86_rtx_costs (rtx x, int code, int outer_code_i, int *total)
610 {
611   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
612   enum machine_mode mode = GET_MODE (x);
613
614   switch (code)
615     {
616     case CONST_INT:
617     case CONST:
618     case LABEL_REF:
619     case SYMBOL_REF:
620       *total = GET_MODE_SIZE (mode);
621       return true;
622
623     case ZERO_EXTEND:
624     case SIGN_EXTEND:
625       if (mode == SImode)
626         *total = 4;
627       else
628         *total = 3;
629       return true;
630
631     default:
632       return false;
633     }
634 }
635
636