source: trunk/third/gcc/bc-optab.c @ 8834

Revision 8834, 22.2 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
1/* Bytecode conversion definitions for GNU C-compiler.
2   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21
22#include "config.h"
23#include "tree.h"
24#include "rtl.h"
25#include "machmode.h"
26#include "obstack.h"
27#include "bytecode.h"
28#include "bc-typecd.h"
29#include "bc-opcode.h"
30#include "bc-optab.h"
31
32#define obstack_chunk_alloc xmalloc
33#define obstack_chunk_free free
34
35extern char *xmalloc ();
36extern void free ();
37
38/* Table relating interpreter typecodes to machine modes.  */
39#define GET_TYPECODE_MODE(CODE) (typecode_mode[((int) CODE)])
40enum machine_mode typecode_mode[] = {
41#define DEFTYPECODE(CODE, NAME, MODE, TYPE) MODE,
42#include "bc-typecd.def"
43#undef DEFTYPECODE
44};
45
46/* Machine mode to type code map */
47static enum typecode signed_mode_to_code_map[MAX_MACHINE_MODE+1];
48static enum typecode unsigned_mode_to_code_map[MAX_MACHINE_MODE+1];
49
50#define GET_TYPECODE_SIZE(CODE) GET_MODE_SIZE (GET_TYPECODE_MODE (CODE))
51
52#define BIG_ARBITRARY_NUMBER 100000
53
54/* Table of recipes for conversions among scalar types, to be filled
55   in as needed at run time.  */
56static struct conversion_recipe
57{
58  unsigned char *opcodes;       /* Bytecodes to emit in order.  */
59  int nopcodes;                 /* Count of bytecodes. */
60  int cost;                     /* A rather arbitrary cost function. */
61} conversion_recipe[NUM_TYPECODES][NUM_TYPECODES];
62
63/* Binary operator tables.  */
64struct binary_operator optab_plus_expr[] = {
65  { addSI, SIcode, SIcode, SIcode },
66  { addDI, DIcode, DIcode, DIcode },
67  { addSF, SFcode, SFcode, SFcode },
68  { addDF, DFcode, DFcode, DFcode },
69  { addXF, XFcode, XFcode, XFcode },
70  { addPSI, Pcode, Pcode, SIcode },
71  { -1, -1, -1, -1 },
72};
73
74struct binary_operator optab_minus_expr[] = {
75  { subSI, SIcode, SIcode, SIcode },
76  { subDI, DIcode, DIcode, DIcode },
77  { subSF, SFcode, SFcode, SFcode },
78  { subDF, DFcode, DFcode, DFcode },
79  { subXF, XFcode, XFcode, XFcode },
80  { subPP, SIcode, Pcode, Pcode },
81  { -1, -1, -1, -1 },
82};
83
84/* The ordering of the tables for multiplicative operators
85   is such that unsigned operations will be preferred to signed
86   operations when one argument is unsigned.  */
87
88struct binary_operator optab_mult_expr[] = {
89  { mulSU, SUcode, SUcode, SUcode },
90  { mulDU, DUcode, DUcode, DUcode },
91  { mulSI, SIcode, SIcode, SIcode },
92  { mulDI, DIcode, DIcode, DIcode },
93  { mulSF, SFcode, SFcode, SFcode },
94  { mulDF, DFcode, DFcode, DFcode },
95  { mulXF, XFcode, XFcode, XFcode },
96  { -1, -1, -1, -1 },
97};
98
99struct binary_operator optab_trunc_div_expr[] = {
100  { divSU, SUcode, SUcode, SUcode },
101  { divDU, DUcode, DUcode, DUcode },
102  { divSI, SIcode, SIcode, SIcode },
103  { divDI, DIcode, DIcode, DIcode },
104  { -1, -1, -1, -1 },
105};
106
107struct binary_operator optab_trunc_mod_expr[] = {
108  { modSU, SUcode, SUcode, SUcode },
109  { modDU, DUcode, DUcode, DUcode },
110  { modSI, SIcode, SIcode, SIcode },
111  { modDI, DIcode, DIcode, DIcode },
112  { -1, -1, -1, -1 },
113};
114
115struct binary_operator optab_rdiv_expr[] = {
116  { divSF, SFcode, SFcode, SFcode },
117  { divDF, DFcode, DFcode, DFcode },
118  { divXF, XFcode, XFcode, XFcode },
119  { -1, -1, -1, -1 },
120};
121
122struct binary_operator optab_bit_and_expr[] = {
123  { andSI, SIcode, SIcode, SIcode },
124  { andDI, DIcode, DIcode, DIcode },
125  { -1, -1, -1, -1 },
126};
127
128struct binary_operator optab_bit_ior_expr[] = {
129  { iorSI, SIcode, SIcode, SIcode },
130  { iorDI, DIcode, DIcode, DIcode },
131  { -1, -1, -1, -1 },
132};
133
134struct binary_operator optab_bit_xor_expr[] = {
135  { xorSI, SIcode, SIcode, SIcode },
136  { xorDI, DIcode, DIcode, DIcode },
137  { -1, -1, -1, -1 },
138};
139
140struct binary_operator optab_lshift_expr[] = {
141  { lshiftSI, SIcode, SIcode, SIcode },
142  { lshiftSU, SUcode, SUcode, SIcode },
143  { lshiftDI, DIcode, DIcode, SIcode },
144  { lshiftDU, DUcode, DUcode, SIcode },
145  { -1, -1, -1, -1 },
146};
147
148struct binary_operator optab_rshift_expr[] = {
149  { rshiftSI, SIcode, SIcode, SIcode },
150  { rshiftSU, SUcode, SUcode, SIcode },
151  { rshiftDI, DIcode, DIcode, SIcode },
152  { rshiftDU, DUcode, DUcode, SIcode },
153  { -1, -1, -1, -1 },
154};
155
156struct binary_operator optab_truth_and_expr[] = {
157  { andSI, SIcode, Tcode, Tcode },
158  { -1, -1, -1, -1 },
159};
160
161struct binary_operator optab_truth_or_expr[] = {
162  { iorSI, SIcode, Tcode, Tcode },
163  { -1, -1, -1, -1 },
164};
165
166struct binary_operator optab_lt_expr[] = {
167  { ltSI, Tcode, SIcode, SIcode },
168  { ltSU, Tcode, SUcode, SUcode },
169  { ltDI, Tcode, DIcode, DIcode },
170  { ltDU, Tcode, DUcode, DUcode },
171  { ltSF, Tcode, SFcode, SFcode },
172  { ltDF, Tcode, DFcode, DFcode },
173  { ltXF, Tcode, XFcode, XFcode },
174  { ltP, Tcode, Pcode, Pcode },
175  { -1, -1, -1, -1 },
176};
177
178struct binary_operator optab_le_expr[] = {
179  { leSI, Tcode, SIcode, SIcode },
180  { leSU, Tcode, SUcode, SUcode },
181  { leDI, Tcode, DIcode, DIcode },
182  { leDU, Tcode, DUcode, DUcode },
183  { leSF, Tcode, SFcode, SFcode },
184  { leDF, Tcode, DFcode, DFcode },
185  { leXF, Tcode, XFcode, XFcode },
186  { leP, Tcode, Pcode, Pcode },
187  { -1, -1, -1, -1 },
188};
189
190struct binary_operator optab_ge_expr[] = {
191  { geSI, Tcode, SIcode, SIcode },
192  { geSU, Tcode, SUcode, SUcode },
193  { geDI, Tcode, DIcode, DIcode },
194  { geDU, Tcode, DUcode, DUcode },
195  { geSF, Tcode, SFcode, SFcode },
196  { geDF, Tcode, DFcode, DFcode },
197  { geXF, Tcode, XFcode, XFcode },
198  { geP, Tcode, Pcode, Pcode },
199  { -1, -1, -1, -1 },
200};
201
202struct binary_operator optab_gt_expr[] = {
203  { gtSI, Tcode, SIcode, SIcode },
204  { gtSU, Tcode, SUcode, SUcode },
205  { gtDI, Tcode, DIcode, DIcode },
206  { gtDU, Tcode, DUcode, DUcode },
207  { gtSF, Tcode, SFcode, SFcode },
208  { gtDF, Tcode, DFcode, DFcode },
209  { gtXF, Tcode, XFcode, XFcode },
210  { gtP, Tcode, Pcode, Pcode },
211  { -1, -1, -1, -1 },
212};
213
214struct binary_operator optab_eq_expr[] = {
215  { eqSI, Tcode, SIcode, SIcode },
216  { eqDI, Tcode, DIcode, DIcode },
217  { eqSF, Tcode, SFcode, SFcode },
218  { eqDF, Tcode, DFcode, DFcode },
219  { eqXF, Tcode, XFcode, XFcode },
220  { eqP, Tcode, Pcode, Pcode },
221  { -1, -1, -1, -1 },
222};
223
224struct binary_operator optab_ne_expr[] = {
225  { neSI, Tcode, SIcode, SIcode },
226  { neDI, Tcode, DIcode, DIcode },
227  { neSF, Tcode, SFcode, SFcode },
228  { neDF, Tcode, DFcode, DFcode },
229  { neXF, Tcode, XFcode, XFcode },
230  { neP, Tcode, Pcode, Pcode },
231  { -1, -1, -1, -1 },
232};
233
234/* Unary operator tables.  */
235struct unary_operator optab_negate_expr[] = {
236  { negSI, SIcode, SIcode },
237  { negDI, DIcode, DIcode },
238  { negSF, SFcode, SFcode },
239  { negDF, DFcode, DFcode },
240  { negXF, XFcode, XFcode },
241  { -1, -1, -1 },
242};
243
244struct unary_operator optab_bit_not_expr[] = {
245  { notSI, SIcode, SIcode },
246  { notDI, DIcode, DIcode },
247  { -1, -1, -1 },
248};
249
250struct unary_operator optab_truth_not_expr[] = {
251  { notT, SIcode, SIcode },
252  { -1, -1, -1 },
253};
254
255/* Increment operator tables.  */
256struct increment_operator optab_predecrement_expr[] = {
257  { predecQI, QIcode },
258  { predecQI, QUcode },
259  { predecHI, HIcode },
260  { predecHI, HUcode },
261  { predecSI, SIcode },
262  { predecSI, SUcode },
263  { predecDI, DIcode },
264  { predecDI, DUcode },
265  { predecP, Pcode },
266  { predecSF, SFcode },
267  { predecDF, DFcode },
268  { predecXF, XFcode },
269  { -1, -1 },
270};
271
272struct increment_operator optab_preincrement_expr[] = {
273  { preincQI, QIcode },
274  { preincQI, QUcode },
275  { preincHI, HIcode },
276  { preincHI, HUcode },
277  { preincSI, SIcode },
278  { preincSI, SUcode },
279  { preincDI, DIcode },
280  { preincDI, DUcode },
281  { preincP, Pcode },
282  { preincSF, SFcode },
283  { preincDF, DFcode },
284  { preincXF, XFcode },
285  { -1, -1 },
286};
287
288struct increment_operator optab_postdecrement_expr[] = {
289  { postdecQI, QIcode },
290  { postdecQI, QUcode },
291  { postdecHI, HIcode },
292  { postdecHI, HUcode },
293  { postdecSI, SIcode },
294  { postdecSI, SUcode },
295  { postdecDI, DIcode },
296  { postdecDI, DUcode },
297  { postdecP, Pcode },
298  { postdecSF, SFcode },
299  { postdecDF, DFcode },
300  { postdecXF, XFcode },
301  { -1, -1 },
302};
303
304struct increment_operator optab_postincrement_expr[] = {
305  { postincQI, QIcode },
306  { postincQI, QUcode },
307  { postincHI, HIcode },
308  { postincHI, HUcode },
309  { postincSI, SIcode },
310  { postincSI, SUcode },
311  { postincDI, DIcode },
312  { postincDI, DUcode },
313  { postincP, Pcode },
314  { postincSF, SFcode },
315  { postincDF, DFcode },
316  { postincXF, XFcode },
317  { -1, -1 },
318};
319
320/* Table of conversions supported by the interpreter.  */
321static struct conversion_info
322{
323  enum bytecode_opcode opcode;  /*  here indicates the conversion needs no opcode.  */
324  enum typecode from;
325  enum typecode to;
326  int cost;                     /* 1 for no-op conversions, 2 for widening conversions,
327                                   4 for int/float conversions, 8 for narrowing conversions.  */
328} conversion_info[] = {
329  { -1, QIcode, QUcode, 1 },
330  { -1, HIcode, HUcode, 1 },
331  { -1, SIcode, SUcode, 1 },
332  { -1, DIcode, DUcode, 1 },
333  { -1, QUcode, QIcode, 1 },
334  { -1, HUcode, HIcode, 1 },
335  { -1, SUcode, SIcode, 1 },
336  { -1, DUcode, DIcode, 1 },
337  { -1, Tcode, SIcode, 1 },
338  { convertQIHI, QIcode, HIcode, 2 },
339  { convertQUHU, QUcode, HUcode, 2 },
340  { convertQUSU, QUcode, SUcode, 2 },
341  { convertHISI, HIcode, SIcode, 2 },
342  { convertHUSU, HUcode, SUcode, 2 },
343  { convertSIDI, SIcode, DIcode, 2 },
344  { convertSUDU, SUcode, DUcode, 2 },
345  { convertSFDF, SFcode, DFcode, 2 },
346  { convertDFXF, DFcode, XFcode, 2 },
347  { convertHIQI, HIcode, QIcode, 8 },
348  { convertSIQI, SIcode, QIcode, 8 },
349  { convertSIHI, SIcode, HIcode, 8 },
350  { convertSUQU, SUcode, QUcode, 8 },
351  { convertDISI, DIcode, SIcode, 8 },
352  { convertDFSF, DFcode, SFcode, 8 },
353  { convertXFDF, XFcode, DFcode, 8 },
354  { convertPSI, Pcode, SIcode, 2 },
355  { convertSIP, SIcode, Pcode, 2 },
356  { convertSIT, SIcode, Tcode, 2 },
357  { convertDIT, DIcode, Tcode, 2 },
358  { convertSFT, SFcode, Tcode, 2 },
359  { convertDFT, DFcode, Tcode, 2 },
360  { convertXFT, XFcode, Tcode, 2 },
361  { convertQISI, QIcode, SIcode, 2 },
362  { convertPT, Pcode, Tcode, 2 },
363  { convertSISF, SIcode, SFcode, 4 },
364  { convertSIDF, SIcode, DFcode, 4 },
365  { convertSIXF, SIcode, XFcode, 4 },
366  { convertSUSF, SUcode, SFcode, 4 },
367  { convertSUDF, SUcode, DFcode, 4 },
368  { convertSUXF, SUcode, XFcode, 4 },
369  { convertDISF, DIcode, SFcode, 4 },
370  { convertDIDF, DIcode, DFcode, 4 },
371  { convertDIXF, DIcode, XFcode, 4 },
372  { convertDUSF, DUcode, SFcode, 4 },
373  { convertDUDF, DUcode, DFcode, 4 },
374  { convertDUXF, DUcode, XFcode, 4 },
375  { convertSFSI, SFcode, SIcode, 4 },
376  { convertDFSI, DFcode, SIcode, 4 },
377  { convertXFSI, XFcode, SIcode, 4 },
378  { convertSFSU, SFcode, SUcode, 4 },
379  { convertDFSU, DFcode, SUcode, 4 },
380  { convertXFSU, XFcode, SUcode, 4 },
381  { convertSFDI, SFcode, DIcode, 4 },
382  { convertDFDI, DFcode, DIcode, 4 },
383  { convertXFDI, XFcode, DIcode, 4 },
384  { convertSFDU, SFcode, DUcode, 4 },
385  { convertDFDU, DFcode, DUcode, 4 },
386  { convertXFDU, XFcode, DUcode, 4 },
387  { convertSIQI, SIcode, QIcode, 8 },
388};
389
390#define NUM_CONVERSIONS (sizeof conversion_info / sizeof (struct conversion_info))
391
392/* List form of a conversion recipe.  */
393struct conversion_list
394{
395  enum bytecode_opcode opcode;
396  enum typecode to;
397  int cost;
398  struct conversion_list *prev;
399};
400
401/* Determine if it is "reasonable" to add a given conversion to
402   a given list of conversions.  The following criteria define
403   "reasonable" conversion lists:
404   * No typecode appears more than once in the sequence (no loops).
405   * At most one conversion from integer to float or vice versa is present.
406   * Either sign extensions or zero extensions may be present, but not both.
407   * No widening conversions occur after a signed/unsigned conversion.
408   * The sequence of sizes must be strict nonincreasing or nondecreasing.  */
409static int
410conversion_reasonable_p (conversion, list)
411     struct conversion_info *conversion;
412     struct conversion_list *list;
413{
414  struct conversion_list *curr;
415  int curr_size, prev_size;
416  int has_int_float, has_float_int;
417  int has_sign_extend, has_zero_extend;
418  int has_signed_unsigned, has_unsigned_signed;
419
420  has_int_float = 0;
421  has_float_int = 0;
422  has_sign_extend = 0;
423  has_zero_extend = 0;
424  has_signed_unsigned = 0;
425  has_unsigned_signed = 0;
426
427  /* Make sure the destination typecode doesn't already appear in
428     the list.  */
429  for (curr = list; curr; curr = curr->prev)
430    if (conversion->to == curr->to)
431      return 0;
432
433  /* Check for certain kinds of conversions.  */
434  if (TYPECODE_INTEGER_P (conversion->from)
435      && TYPECODE_FLOAT_P (conversion->to))
436    has_int_float = 1;
437  if (TYPECODE_FLOAT_P (conversion->from)
438      && TYPECODE_INTEGER_P (conversion->to))
439    has_float_int = 1;
440  if (TYPECODE_SIGNED_P (conversion->from)
441      && TYPECODE_SIGNED_P (conversion->to)
442      && GET_TYPECODE_SIZE (conversion->from)
443      < GET_TYPECODE_SIZE (conversion->to))
444    has_sign_extend = 1;
445  if (TYPECODE_UNSIGNED_P (conversion->from)
446      && TYPECODE_UNSIGNED_P (conversion->to)
447      && GET_TYPECODE_SIZE (conversion->from)
448      < GET_TYPECODE_SIZE (conversion->to))
449    has_zero_extend = 1;
450
451  for (curr = list; curr && curr->prev; curr = curr->prev)
452    {
453      if (TYPECODE_INTEGER_P (curr->prev->to)
454          && TYPECODE_FLOAT_P (curr->to))
455        has_int_float = 1;
456      if (TYPECODE_FLOAT_P (curr->prev->to)
457          && TYPECODE_INTEGER_P (curr->to))
458        has_float_int = 1;
459      if (TYPECODE_SIGNED_P (curr->prev->to)
460          && TYPECODE_SIGNED_P (curr->to)
461          && GET_TYPECODE_SIZE (curr->prev->to)
462          < GET_TYPECODE_SIZE (curr->to))
463        has_sign_extend = 1;
464      if (TYPECODE_UNSIGNED_P (curr->prev->to)
465          && TYPECODE_UNSIGNED_P (curr->to)
466          && GET_TYPECODE_SIZE (curr->prev->to)
467          < GET_TYPECODE_SIZE (curr->to))
468        has_zero_extend = 1;
469      if (TYPECODE_SIGNED_P (curr->prev->to)
470          && TYPECODE_UNSIGNED_P (curr->to))
471        has_signed_unsigned = 1;
472      if (TYPECODE_UNSIGNED_P (curr->prev->to)
473          && TYPECODE_SIGNED_P (curr->to))
474        has_unsigned_signed = 1;
475    }
476
477  if (TYPECODE_INTEGER_P (conversion->from)
478      && TYPECODE_INTEGER_P (conversion->to)
479      && GET_TYPECODE_SIZE (conversion->to)
480      > GET_TYPECODE_SIZE (conversion->from)
481      && (has_signed_unsigned || has_unsigned_signed))
482    return 0;
483
484  if (has_float_int && has_int_float || has_sign_extend && has_zero_extend)
485    return 0;
486
487  /* Make sure the sequence of destination typecode sizes is
488     strictly nondecreasing or strictly nonincreasing.  */
489  prev_size = GET_TYPECODE_SIZE (conversion->to);
490  for (curr = list; curr; curr = curr->prev)
491    {
492      curr_size = GET_TYPECODE_SIZE (curr->to);
493      if (curr_size != prev_size)
494        break;
495    }
496  if (!curr)
497    return 1;
498
499  if (curr_size < prev_size)
500    for (prev_size = curr_size; curr; curr = curr->prev)
501      {
502        curr_size = GET_TYPECODE_SIZE (curr->to);
503        if (curr_size > prev_size)
504          return 0;
505        prev_size = curr_size;
506      }
507  else
508    for (prev_size = curr_size; curr; curr = curr->prev)
509      {
510        curr_size = GET_TYPECODE_SIZE (curr->to);
511        if (curr_size < prev_size)
512          return 0;
513        prev_size = curr_size;
514      }
515  return 1;
516}
517
518
519/* Exhaustively search all reasonable conversions to find one to
520   convert the given types.  */
521static struct conversion_recipe
522deduce_conversion (from, to)
523     enum typecode from, to;
524{
525  struct rl
526    {
527      struct conversion_list *list;
528      struct rl *next;
529    } *prev, curr, *good, *temp;
530  struct conversion_list *conv, *best;
531  int i, cost, bestcost;
532  struct conversion_recipe result;
533  struct obstack recipe_obstack;
534
535
536  obstack_init (&recipe_obstack);
537  curr.next = (struct rl *) obstack_alloc (&recipe_obstack, sizeof (struct rl));
538  curr.next->list =
539    (struct conversion_list *) obstack_alloc (&recipe_obstack,
540                                              sizeof (struct conversion_list));
541  curr.next->list->opcode = -1;
542  curr.next->list->to = from;
543  curr.next->list->cost = 0;
544  curr.next->list->prev = 0;
545  curr.next->next = 0;
546  good = 0;
547
548  while (curr.next)
549    {
550      /* Remove successful conversions from further consideration.  */
551      for (prev = &curr; prev; prev = prev->next)
552        if (prev->next && prev->next->list->to == to)
553          {
554            temp = prev->next->next;
555            prev->next->next = good;
556            good = prev->next;
557            prev->next = temp;
558          }
559
560      /* Go through each of the pending conversion chains, trying
561         all possible candidate conversions on them.  */
562      for (prev = curr.next, curr.next = 0; prev; prev = prev->next)
563        for (i = 0; i < NUM_CONVERSIONS; ++i)
564          if (conversion_info[i].from == prev->list->to
565              && conversion_reasonable_p (&conversion_info[i], prev->list))
566            {
567              temp = (struct rl *) obstack_alloc (&recipe_obstack,
568                                                  sizeof (struct rl));
569              temp->list = (struct conversion_list *)
570                obstack_alloc (&recipe_obstack,
571                               sizeof (struct conversion_list));
572              temp->list->opcode = conversion_info[i].opcode;
573              temp->list->to = conversion_info[i].to;
574              temp->list->cost = conversion_info[i].cost;
575              temp->list->prev = prev->list;
576              temp->next = curr.next;
577              curr.next = temp;
578            }
579    }
580
581  bestcost = BIG_ARBITRARY_NUMBER;
582  best = 0;
583  for (temp = good; temp; temp = temp->next)
584    {
585      for (conv = temp->list, cost = 0; conv; conv = conv->prev)
586        cost += conv->cost;
587      if (cost < bestcost)
588        {
589          bestcost = cost;
590          best = temp->list;
591        }
592    }
593
594  if (!best)
595    abort ();
596
597  for (i = 0, conv = best; conv; conv = conv->prev)
598    if (conv->opcode != -1)
599      ++i;
600
601  result.opcodes = (unsigned char *) xmalloc (i);
602  result.nopcodes = i;
603  for (conv = best; conv; conv = conv->prev)
604    if (conv->opcode != -1)
605      result.opcodes[--i] = conv->opcode;
606  result.cost = bestcost;
607  obstack_free (&recipe_obstack, 0);
608  return result;
609}
610
611#define DEDUCE_CONVERSION(FROM, TO)                             \
612  (conversion_recipe[(int) FROM][(int) TO].opcodes ? 0          \
613   : (conversion_recipe[(int) FROM][(int) TO]                   \
614       = deduce_conversion (FROM, TO), 0))
615
616
617/* Emit a conversion between the given scalar types.  */
618void
619emit_typecode_conversion (from, to)
620     enum typecode from, to;
621{
622  int i;
623
624  DEDUCE_CONVERSION (from, to);
625  for (i = 0; i < conversion_recipe[(int) from][(int) to].nopcodes; ++i)
626    bc_emit_instruction (conversion_recipe[(int) from][(int) to].opcodes[i]);
627}
628
629
630/* Initialize mode_to_code_map[] */
631void
632bc_init_mode_to_code_map ()
633{
634  int mode;
635
636  for (mode = 0; mode < MAX_MACHINE_MODE + 1; mode++)
637    {
638      signed_mode_to_code_map[mode] =
639        unsigned_mode_to_code_map[mode] =
640          LAST_AND_UNUSED_TYPECODE;
641    }
642
643#define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \
644  { signed_mode_to_code_map[(int) SYM] = CODE; \
645    unsigned_mode_to_code_map[(int) SYM] = UCODE; }
646#include "modemap.def"
647#undef DEF_MODEMAP
648
649  /* Initialize opcode maps for const, load, and store */
650  bc_init_mode_to_opcode_maps ();
651}
652
653/* Given a machine mode return the preferred typecode.  */
654enum typecode
655preferred_typecode (mode, unsignedp)
656     enum machine_mode mode;
657     int unsignedp;
658{
659  enum typecode code = (unsignedp
660                        ? unsigned_mode_to_code_map
661                        : signed_mode_to_code_map) [MIN ((int) mode,
662                                                         (int) MAX_MACHINE_MODE)];
663
664  if (code == LAST_AND_UNUSED_TYPECODE)
665    abort ();
666
667  return code;
668}
669
670
671/* Expand a conversion between the given types.  */
672void
673bc_expand_conversion (from, to)
674     tree from, to;
675{
676  enum typecode fcode, tcode;
677
678  fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
679  tcode = preferred_typecode (TYPE_MODE (to), TREE_UNSIGNED (to));
680
681  emit_typecode_conversion (fcode, tcode);
682}
683
684/* Expand a conversion of the given type to a truth value.  */
685void
686bc_expand_truth_conversion (from)
687     tree from;
688{
689  enum typecode fcode;
690
691  fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
692  emit_typecode_conversion (fcode, Tcode);
693}
694
695/* Emit an appropriate binary operation.  */
696void
697bc_expand_binary_operation (optab, resulttype, arg0, arg1)
698     struct binary_operator optab[];
699     tree resulttype, arg0, arg1;
700{
701  int i, besti, cost, bestcost;
702  enum typecode resultcode, arg0code, arg1code;
703 
704  resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
705  arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (resulttype));
706  arg1code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg1)), TREE_UNSIGNED (resulttype));
707
708  besti = -1;
709  bestcost = BIG_ARBITRARY_NUMBER;
710
711  for (i = 0; optab[i].opcode != -1; ++i)
712    {
713      cost = 0;
714      DEDUCE_CONVERSION (arg0code, optab[i].arg0);
715      cost += conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
716      DEDUCE_CONVERSION (arg1code, optab[i].arg1);
717      cost += conversion_recipe[(int) arg1code][(int) optab[i].arg1].cost;
718      if (cost < bestcost)
719        {
720          besti = i;
721          bestcost = cost;
722        }
723    }
724
725  if (besti == -1)
726    abort ();
727
728  expand_expr (arg1, 0, VOIDmode, 0);
729  emit_typecode_conversion (arg1code, optab[besti].arg1);
730  expand_expr (arg0, 0, VOIDmode, 0);
731  emit_typecode_conversion (arg0code, optab[besti].arg0);
732  bc_emit_instruction (optab[besti].opcode);
733  emit_typecode_conversion (optab[besti].result, resultcode);
734}
735
736/* Emit an appropriate unary operation.  */
737void
738bc_expand_unary_operation (optab, resulttype, arg0)
739     struct unary_operator optab[];
740     tree resulttype, arg0;
741{
742  int i, besti, cost, bestcost;
743  enum typecode resultcode, arg0code;
744 
745  resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
746  arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (TREE_TYPE (arg0)));
747
748  besti = -1;
749  bestcost = BIG_ARBITRARY_NUMBER;
750
751  for (i = 0; optab[i].opcode != -1; ++i)
752    {
753      DEDUCE_CONVERSION (arg0code, optab[i].arg0);
754      cost = conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
755      if (cost < bestcost)
756        {
757          besti = i;
758          bestcost = cost;
759        }
760    }
761
762  if (besti == -1)
763    abort ();
764
765  expand_expr (arg0, 0, VOIDmode, 0);
766  emit_typecode_conversion (arg0code, optab[besti].arg0);
767  bc_emit_instruction (optab[besti].opcode);
768  emit_typecode_conversion (optab[besti].result, resultcode);
769}
770
771
772/* Emit an appropriate increment.  */
773void
774bc_expand_increment (optab, type)
775     struct increment_operator optab[];
776     tree type;
777{
778  enum typecode code;
779  int i;
780
781  code = preferred_typecode (TYPE_MODE (type), TREE_UNSIGNED (type));
782  for (i = 0; (int) optab[i].opcode >= 0; ++i)
783    if (code == optab[i].arg)
784      {
785        bc_emit_instruction (optab[i].opcode);
786        return;
787      }
788  abort ();
789}
Note: See TracBrowser for help on using the repository browser.