Annotation of GNUtools/cc/bc-optab.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.