|
|
1.1 root 1: /* Bytecode conversion definitions for GNU C-compiler.
1.1.1.2 root 2: Copyright (C) 1993, 1994 Free Software Foundation, Inc.
1.1 root 3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
1.1.1.3 ! root 18: the Free Software Foundation, 59 Temple Place - Suite 330,
! 19: Boston, MA 02111-1307, USA. */
1.1 root 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:
35: extern char *xmalloc ();
36: extern void free ();
37:
38: /* Table relating interpreter typecodes to machine modes. */
39: #define GET_TYPECODE_MODE(CODE) (typecode_mode[((int) CODE)])
40: enum 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 */
47: static enum typecode signed_mode_to_code_map[MAX_MACHINE_MODE+1];
48: static 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. */
56: static 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. */
64: struct 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:
74: struct 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:
88: struct 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:
99: struct 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:
107: struct 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:
115: struct 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:
122: struct binary_operator optab_bit_and_expr[] = {
123: { andSI, SIcode, SIcode, SIcode },
124: { andDI, DIcode, DIcode, DIcode },
125: { -1, -1, -1, -1 },
126: };
127:
128: struct binary_operator optab_bit_ior_expr[] = {
129: { iorSI, SIcode, SIcode, SIcode },
130: { iorDI, DIcode, DIcode, DIcode },
131: { -1, -1, -1, -1 },
132: };
133:
134: struct binary_operator optab_bit_xor_expr[] = {
135: { xorSI, SIcode, SIcode, SIcode },
136: { xorDI, DIcode, DIcode, DIcode },
137: { -1, -1, -1, -1 },
138: };
139:
140: struct 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:
148: struct 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:
156: struct binary_operator optab_truth_and_expr[] = {
157: { andSI, SIcode, Tcode, Tcode },
158: { -1, -1, -1, -1 },
159: };
160:
161: struct binary_operator optab_truth_or_expr[] = {
162: { iorSI, SIcode, Tcode, Tcode },
163: { -1, -1, -1, -1 },
164: };
165:
166: struct 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:
178: struct 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:
190: struct 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:
202: struct 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:
214: struct 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:
224: struct 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. */
235: struct 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:
244: struct unary_operator optab_bit_not_expr[] = {
245: { notSI, SIcode, SIcode },
246: { notDI, DIcode, DIcode },
247: { -1, -1, -1 },
248: };
249:
250: struct unary_operator optab_truth_not_expr[] = {
251: { notT, SIcode, SIcode },
252: { -1, -1, -1 },
253: };
254:
255: /* Increment operator tables. */
256: struct 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:
272: struct 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:
288: struct 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:
304: struct 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. */
321: static 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. */
393: struct 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. */
409: static int
410: conversion_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. */
521: static struct conversion_recipe
522: deduce_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. */
618: void
619: emit_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[] */
631: void
632: bc_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. */
654: enum typecode
655: preferred_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. */
672: void
673: bc_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. */
685: void
686: bc_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. */
696: void
697: bc_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:
1.1.1.2 root 728: expand_expr (arg1, 0, VOIDmode, 0);
1.1 root 729: emit_typecode_conversion (arg1code, optab[besti].arg1);
1.1.1.2 root 730: expand_expr (arg0, 0, VOIDmode, 0);
1.1 root 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. */
737: void
738: bc_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:
1.1.1.2 root 765: expand_expr (arg0, 0, VOIDmode, 0);
1.1 root 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. */
773: void
774: bc_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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.