Annotation of gcc/stmt.c, revision 1.1.1.7

1.1       root        1: /* Expands front end tree to back end RTL for GNU C-Compiler
1.1.1.7 ! root        2:    Copyright (C) 1987, 88, 89, 92, 93, 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
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: 
                     21: /* This file handles the generation of rtl code from tree structure
                     22:    above the level of expressions, using subroutines in exp*.c and emit-rtl.c.
                     23:    It also creates the rtl expressions for parameters and auto variables
                     24:    and has full responsibility for allocating stack slots.
                     25: 
                     26:    The functions whose names start with `expand_' are called by the
                     27:    parser to generate RTL instructions for various kinds of constructs.
                     28: 
                     29:    Some control and binding constructs require calling several such
                     30:    functions at different times.  For example, a simple if-then
                     31:    is expanded by calling `expand_start_cond' (with the condition-expression
                     32:    as argument) before parsing the then-clause and calling `expand_end_cond'
                     33:    after parsing the then-clause.  */
                     34: 
                     35: #include "config.h"
                     36: 
                     37: #include <stdio.h>
                     38: #include <ctype.h>
                     39: 
                     40: #include "rtl.h"
                     41: #include "tree.h"
                     42: #include "flags.h"
                     43: #include "function.h"
                     44: #include "insn-flags.h"
                     45: #include "insn-config.h"
                     46: #include "insn-codes.h"
                     47: #include "expr.h"
                     48: #include "hard-reg-set.h"
                     49: #include "obstack.h"
                     50: #include "loop.h"
                     51: #include "recog.h"
1.1.1.6   root       52: #include "machmode.h"
                     53: 
                     54: #include "bytecode.h"
                     55: #include "bc-typecd.h"
                     56: #include "bc-opcode.h"
                     57: #include "bc-optab.h"
                     58: #include "bc-emit.h"
1.1       root       59: 
                     60: #define obstack_chunk_alloc xmalloc
                     61: #define obstack_chunk_free free
                     62: struct obstack stmt_obstack;
                     63: 
                     64: /* Filename and line number of last line-number note,
                     65:    whether we actually emitted it or not.  */
                     66: char *emit_filename;
                     67: int emit_lineno;
                     68: 
                     69: /* Nonzero if within a ({...}) grouping, in which case we must
                     70:    always compute a value for each expr-stmt in case it is the last one.  */
                     71: 
                     72: int expr_stmts_for_value;
                     73: 
                     74: /* Each time we expand an expression-statement,
                     75:    record the expr's type and its RTL value here.  */
                     76: 
                     77: static tree last_expr_type;
                     78: static rtx last_expr_value;
                     79: 
1.1.1.4   root       80: /* Each time we expand the end of a binding contour (in `expand_end_bindings')
                     81:    and we emit a new NOTE_INSN_BLOCK_END note, we save a pointer to it here.
                     82:    This is used by the `remember_end_note' function to record the endpoint
                     83:    of each generated block in its associated BLOCK node.  */
                     84: 
                     85: static rtx last_block_end_note;
                     86: 
1.1       root       87: /* Number of binding contours started so far in this function.  */
                     88: 
                     89: int block_start_count;
                     90: 
                     91: /* Nonzero if function being compiled needs to
                     92:    return the address of where it has put a structure value.  */
                     93: 
                     94: extern int current_function_returns_pcc_struct;
                     95: 
                     96: /* Label that will go on parm cleanup code, if any.
                     97:    Jumping to this label runs cleanup code for parameters, if
                     98:    such code must be run.  Following this code is the logical return label.  */
                     99: 
                    100: extern rtx cleanup_label;
                    101: 
                    102: /* Label that will go on function epilogue.
                    103:    Jumping to this label serves as a "return" instruction
                    104:    on machines which require execution of the epilogue on all returns.  */
                    105: 
                    106: extern rtx return_label;
                    107: 
                    108: /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
                    109:    So we can mark them all live at the end of the function, if nonopt.  */
                    110: extern rtx save_expr_regs;
                    111: 
                    112: /* Offset to end of allocated area of stack frame.
                    113:    If stack grows down, this is the address of the last stack slot allocated.
                    114:    If stack grows up, this is the address for the next slot.  */
                    115: extern int frame_offset;
                    116: 
                    117: /* Label to jump back to for tail recursion, or 0 if we have
                    118:    not yet needed one for this function.  */
                    119: extern rtx tail_recursion_label;
                    120: 
                    121: /* Place after which to insert the tail_recursion_label if we need one.  */
                    122: extern rtx tail_recursion_reentry;
                    123: 
                    124: /* Location at which to save the argument pointer if it will need to be
                    125:    referenced.  There are two cases where this is done: if nonlocal gotos
                    126:    exist, or if vars whose is an offset from the argument pointer will be
                    127:    needed by inner routines.  */
                    128: 
                    129: extern rtx arg_pointer_save_area;
                    130: 
                    131: /* Chain of all RTL_EXPRs that have insns in them.  */
                    132: extern tree rtl_expr_chain;
                    133: 
                    134: #if 0  /* Turned off because 0 seems to work just as well.  */
                    135: /* Cleanup lists are required for binding levels regardless of whether
                    136:    that binding level has cleanups or not.  This node serves as the
                    137:    cleanup list whenever an empty list is required.  */
                    138: static tree empty_cleanup_list;
                    139: #endif
1.1.1.7 ! root      140: 
        !           141: extern void (*interim_eh_hook) PROTO((tree));
1.1       root      142: 
                    143: /* Functions and data structures for expanding case statements.  */
                    144: 
                    145: /* Case label structure, used to hold info on labels within case
                    146:    statements.  We handle "range" labels; for a single-value label
                    147:    as in C, the high and low limits are the same.
                    148: 
                    149:    A chain of case nodes is initially maintained via the RIGHT fields
                    150:    in the nodes.  Nodes with higher case values are later in the list.
                    151: 
                    152:    Switch statements can be output in one of two forms.  A branch table
                    153:    is used if there are more than a few labels and the labels are dense
                    154:    within the range between the smallest and largest case value.  If a
                    155:    branch table is used, no further manipulations are done with the case
                    156:    node chain.
                    157: 
                    158:    The alternative to the use of a branch table is to generate a series
                    159:    of compare and jump insns.  When that is done, we use the LEFT, RIGHT,
                    160:    and PARENT fields to hold a binary tree.  Initially the tree is
                    161:    totally unbalanced, with everything on the right.  We balance the tree
                    162:    with nodes on the left having lower case values than the parent
                    163:    and nodes on the right having higher values.  We then output the tree
                    164:    in order.  */
                    165: 
                    166: struct case_node
                    167: {
                    168:   struct case_node     *left;  /* Left son in binary tree */
                    169:   struct case_node     *right; /* Right son in binary tree; also node chain */
                    170:   struct case_node     *parent; /* Parent of node in binary tree */
                    171:   tree                 low;    /* Lowest index value for this label */
                    172:   tree                 high;   /* Highest index value for this label */
                    173:   tree                 code_label; /* Label to jump to when node matches */
                    174: };
                    175: 
                    176: typedef struct case_node case_node;
                    177: typedef struct case_node *case_node_ptr;
                    178: 
                    179: /* These are used by estimate_case_costs and balance_case_nodes.  */
                    180: 
                    181: /* This must be a signed type, and non-ANSI compilers lack signed char.  */
                    182: static short *cost_table;
                    183: static int use_cost_table;
                    184: 
                    185: /* Stack of control and binding constructs we are currently inside.
                    186: 
                    187:    These constructs begin when you call `expand_start_WHATEVER'
                    188:    and end when you call `expand_end_WHATEVER'.  This stack records
                    189:    info about how the construct began that tells the end-function
                    190:    what to do.  It also may provide information about the construct
                    191:    to alter the behavior of other constructs within the body.
                    192:    For example, they may affect the behavior of C `break' and `continue'.
                    193: 
                    194:    Each construct gets one `struct nesting' object.
                    195:    All of these objects are chained through the `all' field.
                    196:    `nesting_stack' points to the first object (innermost construct).
                    197:    The position of an entry on `nesting_stack' is in its `depth' field.
                    198: 
                    199:    Each type of construct has its own individual stack.
                    200:    For example, loops have `loop_stack'.  Each object points to the
                    201:    next object of the same type through the `next' field.
                    202: 
                    203:    Some constructs are visible to `break' exit-statements and others
                    204:    are not.  Which constructs are visible depends on the language.
                    205:    Therefore, the data structure allows each construct to be visible
                    206:    or not, according to the args given when the construct is started.
                    207:    The construct is visible if the `exit_label' field is non-null.
                    208:    In that case, the value should be a CODE_LABEL rtx.  */
                    209: 
                    210: struct nesting
                    211: {
                    212:   struct nesting *all;
                    213:   struct nesting *next;
                    214:   int depth;
                    215:   rtx exit_label;
                    216:   union
                    217:     {
                    218:       /* For conds (if-then and if-then-else statements).  */
                    219:       struct
                    220:        {
                    221:          /* Label for the end of the if construct.
                    222:             There is none if EXITFLAG was not set
                    223:             and no `else' has been seen yet.  */
                    224:          rtx endif_label;
                    225:          /* Label for the end of this alternative.
                    226:             This may be the end of the if or the next else/elseif. */
                    227:          rtx next_label;
                    228:        } cond;
                    229:       /* For loops.  */
                    230:       struct
                    231:        {
                    232:          /* Label at the top of the loop; place to loop back to.  */
                    233:          rtx start_label;
                    234:          /* Label at the end of the whole construct.  */
                    235:          rtx end_label;
1.1.1.7 ! root      236:          /* Label before a jump that branches to the end of the whole
        !           237:             construct.  This is where destructors go if any.  */
        !           238:          rtx alt_end_label;
1.1       root      239:          /* Label for `continue' statement to jump to;
                    240:             this is in front of the stepper of the loop.  */
                    241:          rtx continue_label;
                    242:        } loop;
                    243:       /* For variable binding contours.  */
                    244:       struct
                    245:        {
                    246:          /* Sequence number of this binding contour within the function,
                    247:             in order of entry.  */
                    248:          int block_start_count;
1.1.1.6   root      249:          /* Nonzero => value to restore stack to on exit.  Complemented by
                    250:             bc_stack_level (see below) when generating bytecodes. */
1.1       root      251:          rtx stack_level;
                    252:          /* The NOTE that starts this contour.
                    253:             Used by expand_goto to check whether the destination
                    254:             is within each contour or not.  */
                    255:          rtx first_insn;
                    256:          /* Innermost containing binding contour that has a stack level.  */
                    257:          struct nesting *innermost_stack_block;
                    258:          /* List of cleanups to be run on exit from this contour.
                    259:             This is a list of expressions to be evaluated.
                    260:             The TREE_PURPOSE of each link is the ..._DECL node
                    261:             which the cleanup pertains to.  */
                    262:          tree cleanups;
                    263:          /* List of cleanup-lists of blocks containing this block,
                    264:             as they were at the locus where this block appears.
                    265:             There is an element for each containing block,
                    266:             ordered innermost containing block first.
                    267:             The tail of this list can be 0 (was empty_cleanup_list),
                    268:             if all remaining elements would be empty lists.
                    269:             The element's TREE_VALUE is the cleanup-list of that block,
                    270:             which may be null.  */
                    271:          tree outer_cleanups;
                    272:          /* Chain of labels defined inside this binding contour.
                    273:             For contours that have stack levels or cleanups.  */
                    274:          struct label_chain *label_chain;
                    275:          /* Number of function calls seen, as of start of this block.  */
                    276:          int function_call_count;
1.1.1.6   root      277:          /* Bytecode specific: stack level to restore stack to on exit.  */
                    278:          int bc_stack_level;
1.1       root      279:        } block;
                    280:       /* For switch (C) or case (Pascal) statements,
                    281:         and also for dummies (see `expand_start_case_dummy').  */
                    282:       struct
                    283:        {
                    284:          /* The insn after which the case dispatch should finally
                    285:             be emitted.  Zero for a dummy.  */
                    286:          rtx start;
1.1.1.6   root      287:          /* For bytecodes, the case table is in-lined right in the code.
                    288:             A label is needed for skipping over this block. It is only
                    289:             used when generating bytecodes. */
                    290:          rtx skip_label;
1.1       root      291:          /* A list of case labels, kept in ascending order by value
                    292:             as the list is built.
                    293:             During expand_end_case, this list may be rearranged into a
                    294:             nearly balanced binary tree.  */
                    295:          struct case_node *case_list;
                    296:          /* Label to jump to if no case matches.  */
                    297:          tree default_label;
                    298:          /* The expression to be dispatched on.  */
                    299:          tree index_expr;
                    300:          /* Type that INDEX_EXPR should be converted to.  */
                    301:          tree nominal_type;
                    302:          /* Number of range exprs in case statement.  */
                    303:          int num_ranges;
                    304:          /* Name of this kind of statement, for warnings.  */
                    305:          char *printname;
                    306:          /* Nonzero if a case label has been seen in this case stmt.  */
                    307:          char seenlabel;
                    308:        } case_stmt;
                    309:     } data;
                    310: };
                    311: 
                    312: /* Chain of all pending binding contours.  */
                    313: struct nesting *block_stack;
                    314: 
1.1.1.4   root      315: /* If any new stacks are added here, add them to POPSTACKS too.  */
                    316: 
1.1       root      317: /* Chain of all pending binding contours that restore stack levels
                    318:    or have cleanups.  */
                    319: struct nesting *stack_block_stack;
                    320: 
                    321: /* Chain of all pending conditional statements.  */
                    322: struct nesting *cond_stack;
                    323: 
                    324: /* Chain of all pending loops.  */
                    325: struct nesting *loop_stack;
                    326: 
                    327: /* Chain of all pending case or switch statements.  */
                    328: struct nesting *case_stack;
                    329: 
                    330: /* Separate chain including all of the above,
                    331:    chained through the `all' field.  */
                    332: struct nesting *nesting_stack;
                    333: 
                    334: /* Number of entries on nesting_stack now.  */
                    335: int nesting_depth;
                    336: 
                    337: /* Allocate and return a new `struct nesting'.  */
                    338: 
                    339: #define ALLOC_NESTING() \
                    340:  (struct nesting *) obstack_alloc (&stmt_obstack, sizeof (struct nesting))
                    341: 
1.1.1.4   root      342: /* Pop the nesting stack element by element until we pop off
                    343:    the element which is at the top of STACK.
                    344:    Update all the other stacks, popping off elements from them
                    345:    as we pop them from nesting_stack.  */
1.1       root      346: 
                    347: #define POPSTACK(STACK)                                        \
1.1.1.4   root      348: do { struct nesting *target = STACK;                   \
                    349:      struct nesting *this;                             \
                    350:      do { this = nesting_stack;                                \
                    351:          if (loop_stack == this)                       \
                    352:            loop_stack = loop_stack->next;              \
                    353:          if (cond_stack == this)                       \
                    354:            cond_stack = cond_stack->next;              \
                    355:          if (block_stack == this)                      \
                    356:            block_stack = block_stack->next;            \
                    357:          if (stack_block_stack == this)                \
                    358:            stack_block_stack = stack_block_stack->next; \
                    359:          if (case_stack == this)                       \
                    360:            case_stack = case_stack->next;              \
                    361:          nesting_depth = nesting_stack->depth - 1;     \
1.1       root      362:          nesting_stack = this->all;                    \
                    363:          obstack_free (&stmt_obstack, this); }         \
1.1.1.4   root      364:      while (this != target); } while (0)
1.1       root      365: 
                    366: /* In some cases it is impossible to generate code for a forward goto
                    367:    until the label definition is seen.  This happens when it may be necessary
                    368:    for the goto to reset the stack pointer: we don't yet know how to do that.
                    369:    So expand_goto puts an entry on this fixup list.
                    370:    Each time a binding contour that resets the stack is exited,
                    371:    we check each fixup.
                    372:    If the target label has now been defined, we can insert the proper code.  */
                    373: 
                    374: struct goto_fixup
                    375: {
                    376:   /* Points to following fixup.  */
                    377:   struct goto_fixup *next;
                    378:   /* Points to the insn before the jump insn.
                    379:      If more code must be inserted, it goes after this insn.  */
                    380:   rtx before_jump;
                    381:   /* The LABEL_DECL that this jump is jumping to, or 0
                    382:      for break, continue or return.  */
                    383:   tree target;
1.1.1.4   root      384:   /* The BLOCK for the place where this goto was found.  */
                    385:   tree context;
1.1       root      386:   /* The CODE_LABEL rtx that this is jumping to.  */
                    387:   rtx target_rtl;
                    388:   /* Number of binding contours started in current function
                    389:      before the label reference.  */
                    390:   int block_start_count;
                    391:   /* The outermost stack level that should be restored for this jump.
                    392:      Each time a binding contour that resets the stack is exited,
                    393:      if the target label is *not* yet defined, this slot is updated.  */
                    394:   rtx stack_level;
                    395:   /* List of lists of cleanup expressions to be run by this goto.
                    396:      There is one element for each block that this goto is within.
                    397:      The tail of this list can be 0 (was empty_cleanup_list),
                    398:      if all remaining elements would be empty.
                    399:      The TREE_VALUE contains the cleanup list of that block as of the
                    400:      time this goto was seen.
                    401:      The TREE_ADDRESSABLE flag is 1 for a block that has been exited.  */
                    402:   tree cleanup_list_list;
1.1.1.6   root      403: 
                    404:   /* Bytecode specific members follow */
                    405: 
                    406:   /* The label that this jump is jumping to, or 0 for break, continue
                    407:      or return.  */
                    408:   struct bc_label *bc_target;
                    409: 
                    410:   /* The label we use for the fixup patch */
                    411:   struct bc_label *label;
                    412: 
                    413:   /* True (non-0) if fixup has been handled */
                    414:   int bc_handled:1;
                    415: 
                    416:   /* Like stack_level above, except refers to the interpreter stack */
                    417:   int bc_stack_level;
1.1       root      418: };
                    419: 
                    420: static struct goto_fixup *goto_fixup_chain;
                    421: 
                    422: /* Within any binding contour that must restore a stack level,
                    423:    all labels are recorded with a chain of these structures.  */
                    424: 
                    425: struct label_chain
                    426: {
                    427:   /* Points to following fixup.  */
                    428:   struct label_chain *next;
                    429:   tree label;
                    430: };
1.1.1.7 ! root      431: static void expand_goto_internal       PROTO((tree, rtx, rtx));
        !           432: static void bc_expand_goto_internal    PROTO((enum bytecode_opcode,
        !           433:                                               struct bc_label *, tree));
        !           434: static int expand_fixup                        PROTO((tree, rtx, rtx));
        !           435: static void bc_expand_fixup            PROTO((enum bytecode_opcode,
        !           436:                                               struct bc_label *, int));
        !           437: static void fixup_gotos                        PROTO((struct nesting *, rtx, tree,
        !           438:                                               rtx, int));
        !           439: static void bc_fixup_gotos             PROTO((struct nesting *, int, tree,
        !           440:                                               rtx, int));
        !           441: static int warn_if_unused_value                PROTO((tree));
        !           442: static void bc_expand_start_cond       PROTO((tree, int));
        !           443: static void bc_expand_end_cond         PROTO((void));
        !           444: static void bc_expand_start_else       PROTO((void));
        !           445: static void bc_expand_end_loop         PROTO((void));
        !           446: static void bc_expand_end_bindings     PROTO((tree, int, int));
        !           447: static void bc_expand_decl             PROTO((tree, tree));
        !           448: static void bc_expand_variable_local_init PROTO((tree));
        !           449: static void bc_expand_decl_init                PROTO((tree));
        !           450: static void expand_null_return_1       PROTO((rtx, int));
        !           451: static int tail_recursion_args         PROTO((tree, tree));
        !           452: static void expand_cleanups            PROTO((tree, tree));
        !           453: static void bc_expand_start_case       PROTO((struct nesting *, tree,
        !           454:                                               tree, char *));
        !           455: static int bc_pushcase                 PROTO((tree, tree));
        !           456: static void bc_check_for_full_enumeration_handling PROTO((tree));
        !           457: static void bc_expand_end_case         PROTO((tree));
        !           458: static void do_jump_if_equal           PROTO((rtx, rtx, rtx, int));
        !           459: static int estimate_case_costs         PROTO((case_node_ptr));
        !           460: static void group_case_nodes           PROTO((case_node_ptr));
        !           461: static void balance_case_nodes         PROTO((case_node_ptr *,
        !           462:                                               case_node_ptr));
        !           463: static int node_has_low_bound          PROTO((case_node_ptr, tree));
        !           464: static int node_has_high_bound         PROTO((case_node_ptr, tree));
        !           465: static int node_is_bounded             PROTO((case_node_ptr, tree));
        !           466: static void emit_jump_if_reachable     PROTO((rtx));
        !           467: static void emit_case_nodes            PROTO((rtx, case_node_ptr, rtx, tree));
        !           468: 
        !           469: int bc_expand_exit_loop_if_false ();
        !           470: void bc_expand_start_cond ();
        !           471: void bc_expand_end_cond ();
        !           472: void bc_expand_start_else ();
        !           473: void bc_expand_end_bindings ();
        !           474: void bc_expand_start_case ();
        !           475: void bc_check_for_full_enumeration_handling ();
        !           476: void bc_expand_end_case ();
        !           477: void bc_expand_decl ();
        !           478: 
        !           479: extern rtx bc_allocate_local ();
        !           480: extern rtx bc_allocate_variable_array ();
1.1       root      481: 
                    482: void
                    483: init_stmt ()
                    484: {
                    485:   gcc_obstack_init (&stmt_obstack);
                    486: #if 0
                    487:   empty_cleanup_list = build_tree_list (NULL_TREE, NULL_TREE);
                    488: #endif
                    489: }
                    490: 
                    491: void
                    492: init_stmt_for_function ()
                    493: {
                    494:   /* We are not currently within any block, conditional, loop or case.  */
                    495:   block_stack = 0;
1.1.1.7 ! root      496:   stack_block_stack = 0;
1.1       root      497:   loop_stack = 0;
                    498:   case_stack = 0;
                    499:   cond_stack = 0;
                    500:   nesting_stack = 0;
                    501:   nesting_depth = 0;
                    502: 
                    503:   block_start_count = 0;
                    504: 
                    505:   /* No gotos have been expanded yet.  */
                    506:   goto_fixup_chain = 0;
                    507: 
                    508:   /* We are not processing a ({...}) grouping.  */
                    509:   expr_stmts_for_value = 0;
                    510:   last_expr_type = 0;
                    511: }
                    512: 
                    513: void
                    514: save_stmt_status (p)
                    515:      struct function *p;
                    516: {
                    517:   p->block_stack = block_stack;
                    518:   p->stack_block_stack = stack_block_stack;
                    519:   p->cond_stack = cond_stack;
                    520:   p->loop_stack = loop_stack;
                    521:   p->case_stack = case_stack;
                    522:   p->nesting_stack = nesting_stack;
                    523:   p->nesting_depth = nesting_depth;
                    524:   p->block_start_count = block_start_count;
                    525:   p->last_expr_type = last_expr_type;
                    526:   p->last_expr_value = last_expr_value;
                    527:   p->expr_stmts_for_value = expr_stmts_for_value;
                    528:   p->emit_filename = emit_filename;
                    529:   p->emit_lineno = emit_lineno;
                    530:   p->goto_fixup_chain = goto_fixup_chain;
                    531: }
                    532: 
                    533: void
                    534: restore_stmt_status (p)
                    535:      struct function *p;
                    536: {
                    537:   block_stack = p->block_stack;
                    538:   stack_block_stack = p->stack_block_stack;
                    539:   cond_stack = p->cond_stack;
                    540:   loop_stack = p->loop_stack;
                    541:   case_stack = p->case_stack;
                    542:   nesting_stack = p->nesting_stack;
                    543:   nesting_depth = p->nesting_depth;
                    544:   block_start_count = p->block_start_count;
                    545:   last_expr_type = p->last_expr_type;
                    546:   last_expr_value = p->last_expr_value;
                    547:   expr_stmts_for_value = p->expr_stmts_for_value;
                    548:   emit_filename = p->emit_filename;
                    549:   emit_lineno = p->emit_lineno;
                    550:   goto_fixup_chain = p->goto_fixup_chain;
                    551: }
                    552: 
                    553: /* Emit a no-op instruction.  */
                    554: 
                    555: void
                    556: emit_nop ()
                    557: {
1.1.1.6   root      558:   rtx last_insn;
                    559: 
                    560:   if (!output_bytecode)
                    561:     {
                    562:       last_insn = get_last_insn ();
                    563:       if (!optimize
                    564:          && (GET_CODE (last_insn) == CODE_LABEL
                    565:              || prev_real_insn (last_insn) == 0))
                    566:        emit_insn (gen_nop ());
                    567:     }
1.1       root      568: }
                    569: 
                    570: /* Return the rtx-label that corresponds to a LABEL_DECL,
                    571:    creating it if necessary.  */
                    572: 
                    573: rtx
                    574: label_rtx (label)
                    575:      tree label;
                    576: {
                    577:   if (TREE_CODE (label) != LABEL_DECL)
                    578:     abort ();
                    579: 
                    580:   if (DECL_RTL (label))
                    581:     return DECL_RTL (label);
                    582: 
                    583:   return DECL_RTL (label) = gen_label_rtx ();
                    584: }
                    585: 
                    586: /* Add an unconditional jump to LABEL as the next sequential instruction.  */
                    587: 
                    588: void
                    589: emit_jump (label)
                    590:      rtx label;
                    591: {
                    592:   do_pending_stack_adjust ();
                    593:   emit_jump_insn (gen_jump (label));
                    594:   emit_barrier ();
                    595: }
                    596: 
                    597: /* Emit code to jump to the address
                    598:    specified by the pointer expression EXP.  */
                    599: 
                    600: void
                    601: expand_computed_goto (exp)
                    602:      tree exp;
                    603: {
1.1.1.6   root      604:   if (output_bytecode)
                    605:     {
                    606:       bc_expand_expr (exp);
                    607:       bc_emit_instruction (jumpP);
                    608:     }
                    609:   else
                    610:     {
                    611:       rtx x = expand_expr (exp, NULL_RTX, VOIDmode, 0);
                    612:       emit_queue ();
                    613:       emit_indirect_jump (x);
                    614:     }
1.1       root      615: }
                    616: 
                    617: /* Handle goto statements and the labels that they can go to.  */
                    618: 
                    619: /* Specify the location in the RTL code of a label LABEL,
                    620:    which is a LABEL_DECL tree node.
                    621: 
                    622:    This is used for the kind of label that the user can jump to with a
                    623:    goto statement, and for alternatives of a switch or case statement.
                    624:    RTL labels generated for loops and conditionals don't go through here;
                    625:    they are generated directly at the RTL level, by other functions below.
                    626: 
                    627:    Note that this has nothing to do with defining label *names*.
                    628:    Languages vary in how they do that and what that even means.  */
                    629: 
                    630: void
                    631: expand_label (label)
                    632:      tree label;
                    633: {
                    634:   struct label_chain *p;
                    635: 
1.1.1.6   root      636:   if (output_bytecode)
                    637:     {
                    638:       if (! DECL_RTL (label))
                    639:        DECL_RTL (label) = bc_gen_rtx ((char *) 0, 0, bc_get_bytecode_label ());
                    640:       if (! bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (DECL_RTL (label))))
                    641:        error ("multiply defined label");
                    642:       return;
                    643:     }
                    644: 
1.1       root      645:   do_pending_stack_adjust ();
                    646:   emit_label (label_rtx (label));
                    647:   if (DECL_NAME (label))
                    648:     LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
                    649: 
                    650:   if (stack_block_stack != 0)
                    651:     {
                    652:       p = (struct label_chain *) oballoc (sizeof (struct label_chain));
                    653:       p->next = stack_block_stack->data.block.label_chain;
                    654:       stack_block_stack->data.block.label_chain = p;
                    655:       p->label = label;
                    656:     }
                    657: }
                    658: 
                    659: /* Declare that LABEL (a LABEL_DECL) may be used for nonlocal gotos
                    660:    from nested functions.  */
                    661: 
                    662: void
                    663: declare_nonlocal_label (label)
                    664:      tree label;
                    665: {
                    666:   nonlocal_labels = tree_cons (NULL_TREE, label, nonlocal_labels);
                    667:   LABEL_PRESERVE_P (label_rtx (label)) = 1;
                    668:   if (nonlocal_goto_handler_slot == 0)
                    669:     {
                    670:       nonlocal_goto_handler_slot
                    671:        = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
1.1.1.3   root      672:       emit_stack_save (SAVE_NONLOCAL,
                    673:                       &nonlocal_goto_stack_level,
                    674:                       PREV_INSN (tail_recursion_reentry));
1.1       root      675:     }
                    676: }
                    677: 
                    678: /* Generate RTL code for a `goto' statement with target label LABEL.
                    679:    LABEL should be a LABEL_DECL tree node that was or will later be
                    680:    defined with `expand_label'.  */
                    681: 
                    682: void
                    683: expand_goto (label)
                    684:      tree label;
                    685: {
1.1.1.6   root      686:   tree context;
                    687: 
                    688:   if (output_bytecode)
                    689:     {
                    690:       expand_goto_internal (label, label_rtx (label), NULL_RTX);
                    691:       return;
                    692:     }
                    693: 
1.1       root      694:   /* Check for a nonlocal goto to a containing function.  */
1.1.1.6   root      695:   context = decl_function_context (label);
1.1       root      696:   if (context != 0 && context != current_function_decl)
                    697:     {
                    698:       struct function *p = find_function_data (context);
1.1.1.4   root      699:       rtx label_ref = gen_rtx (LABEL_REF, Pmode, label_rtx (label));
1.1       root      700:       rtx temp;
1.1.1.4   root      701: 
1.1       root      702:       p->has_nonlocal_label = 1;
1.1.1.6   root      703:       current_function_has_nonlocal_goto = 1;
1.1.1.4   root      704:       LABEL_REF_NONLOCAL_P (label_ref) = 1;
1.1.1.3   root      705: 
                    706:       /* Copy the rtl for the slots so that they won't be shared in
                    707:         case the virtual stack vars register gets instantiated differently
                    708:         in the parent than in the child.  */
                    709: 
1.1       root      710: #if HAVE_nonlocal_goto
                    711:       if (HAVE_nonlocal_goto)
                    712:        emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
1.1.1.3   root      713:                                      copy_rtx (p->nonlocal_goto_handler_slot),
                    714:                                      copy_rtx (p->nonlocal_goto_stack_level),
1.1.1.4   root      715:                                      label_ref));
1.1       root      716:       else
                    717: #endif
                    718:        {
1.1.1.3   root      719:          rtx addr;
                    720: 
1.1       root      721:          /* Restore frame pointer for containing function.
                    722:             This sets the actual hard register used for the frame pointer
                    723:             to the location of the function's incoming static chain info.
                    724:             The non-local goto handler will then adjust it to contain the
                    725:             proper value and reload the argument pointer, if needed.  */
1.1.1.6   root      726:          emit_move_insn (hard_frame_pointer_rtx, lookup_static_chain (label));
1.1.1.3   root      727: 
                    728:          /* We have now loaded the frame pointer hardware register with
                    729:             the address of that corresponds to the start of the virtual
                    730:             stack vars.  So replace virtual_stack_vars_rtx in all
                    731:             addresses we use with stack_pointer_rtx.  */
                    732: 
1.1       root      733:          /* Get addr of containing function's current nonlocal goto handler,
                    734:             which will do any cleanups and then jump to the label.  */
1.1.1.3   root      735:          addr = copy_rtx (p->nonlocal_goto_handler_slot);
                    736:          temp = copy_to_reg (replace_rtx (addr, virtual_stack_vars_rtx,
1.1.1.6   root      737:                                           hard_frame_pointer_rtx));
1.1.1.3   root      738:          
1.1       root      739:          /* Restore the stack pointer.  Note this uses fp just restored.  */
1.1.1.3   root      740:          addr = p->nonlocal_goto_stack_level;
                    741:          if (addr)
                    742:            addr = replace_rtx (copy_rtx (addr),
1.1.1.6   root      743:                                virtual_stack_vars_rtx,
                    744:                                hard_frame_pointer_rtx);
1.1.1.3   root      745: 
1.1.1.4   root      746:          emit_stack_restore (SAVE_NONLOCAL, addr, NULL_RTX);
1.1.1.3   root      747: 
1.1       root      748:          /* Put in the static chain register the nonlocal label address.  */
1.1.1.4   root      749:          emit_move_insn (static_chain_rtx, label_ref);
1.1.1.6   root      750:          /* USE of hard_frame_pointer_rtx added for consistency; not clear if
1.1       root      751:             really needed.  */
1.1.1.6   root      752:          emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx));
1.1       root      753:          emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
                    754:          emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
                    755:          emit_indirect_jump (temp);
                    756:        }
                    757:      }
                    758:   else
1.1.1.4   root      759:     expand_goto_internal (label, label_rtx (label), NULL_RTX);
1.1       root      760: }
                    761: 
                    762: /* Generate RTL code for a `goto' statement with target label BODY.
                    763:    LABEL should be a LABEL_REF.
                    764:    LAST_INSN, if non-0, is the rtx we should consider as the last
                    765:    insn emitted (for the purposes of cleaning up a return).  */
                    766: 
                    767: static void
                    768: expand_goto_internal (body, label, last_insn)
                    769:      tree body;
                    770:      rtx label;
                    771:      rtx last_insn;
                    772: {
                    773:   struct nesting *block;
                    774:   rtx stack_level = 0;
                    775: 
1.1.1.6   root      776:   /* NOTICE!  If a bytecode instruction other than `jump' is needed,
                    777:      then the caller has to call bc_expand_goto_internal()
                    778:      directly. This is rather an exceptional case, and there aren't
                    779:      that many places where this is necessary. */
                    780:   if (output_bytecode)
                    781:     {
                    782:       expand_goto_internal (body, label, last_insn);
                    783:       return;
                    784:     }
                    785: 
1.1       root      786:   if (GET_CODE (label) != CODE_LABEL)
                    787:     abort ();
                    788: 
                    789:   /* If label has already been defined, we can tell now
                    790:      whether and how we must alter the stack level.  */
                    791: 
                    792:   if (PREV_INSN (label) != 0)
                    793:     {
                    794:       /* Find the innermost pending block that contains the label.
                    795:         (Check containment by comparing insn-uids.)
                    796:         Then restore the outermost stack level within that block,
                    797:         and do cleanups of all blocks contained in it.  */
                    798:       for (block = block_stack; block; block = block->next)
                    799:        {
                    800:          if (INSN_UID (block->data.block.first_insn) < INSN_UID (label))
                    801:            break;
                    802:          if (block->data.block.stack_level != 0)
                    803:            stack_level = block->data.block.stack_level;
                    804:          /* Execute the cleanups for blocks we are exiting.  */
                    805:          if (block->data.block.cleanups != 0)
                    806:            {
1.1.1.4   root      807:              expand_cleanups (block->data.block.cleanups, NULL_TREE);
1.1       root      808:              do_pending_stack_adjust ();
                    809:            }
                    810:        }
                    811: 
                    812:       if (stack_level)
                    813:        {
                    814:          /* Ensure stack adjust isn't done by emit_jump, as this would clobber
                    815:             the stack pointer.  This one should be deleted as dead by flow. */
                    816:          clear_pending_stack_adjust ();
                    817:          do_pending_stack_adjust ();
1.1.1.4   root      818:          emit_stack_restore (SAVE_BLOCK, stack_level, NULL_RTX);
1.1       root      819:        }
                    820: 
                    821:       if (body != 0 && DECL_TOO_LATE (body))
                    822:        error ("jump to `%s' invalidly jumps into binding contour",
                    823:               IDENTIFIER_POINTER (DECL_NAME (body)));
                    824:     }
                    825:   /* Label not yet defined: may need to put this goto
                    826:      on the fixup list.  */
                    827:   else if (! expand_fixup (body, label, last_insn))
                    828:     {
                    829:       /* No fixup needed.  Record that the label is the target
                    830:         of at least one goto that has no fixup.  */
                    831:       if (body != 0)
                    832:        TREE_ADDRESSABLE (body) = 1;
                    833:     }
                    834: 
                    835:   emit_jump (label);
                    836: }
                    837: 
1.1.1.6   root      838: /* Generate a jump with OPCODE to the given bytecode LABEL which is
                    839:    found within BODY. */
1.1.1.7 ! root      840: 
1.1.1.6   root      841: static void
                    842: bc_expand_goto_internal (opcode, label, body)
                    843:      enum bytecode_opcode opcode;
                    844:      struct bc_label *label;
                    845:      tree body;
                    846: {
                    847:   struct nesting *block;
                    848:   int stack_level = -1;
                    849: 
                    850:   /* If the label is defined, adjust the stack as necessary.
                    851:      If it's not defined, we have to push the reference on the
                    852:      fixup list. */
                    853: 
                    854:   if (label->defined)
                    855:     {
                    856: 
                    857:       /* Find the innermost pending block that contains the label.
                    858:         (Check containment by comparing bytecode uids.)  Then restore the
                    859:         outermost stack level within that block.  */
                    860: 
                    861:       for (block = block_stack; block; block = block->next)
                    862:        {
                    863:          if (BYTECODE_BC_LABEL (block->data.block.first_insn)->uid < label->uid)
                    864:            break;
                    865:          if (block->data.block.bc_stack_level)
                    866:            stack_level = block->data.block.bc_stack_level;
                    867: 
                    868:          /* Execute the cleanups for blocks we are exiting.  */
                    869:          if (block->data.block.cleanups != 0)
                    870:            {
                    871:              expand_cleanups (block->data.block.cleanups, NULL_TREE);
                    872:              do_pending_stack_adjust ();
                    873:            }
                    874:        }
                    875: 
                    876:       /* Restore the stack level. If we need to adjust the stack, we
                    877:         must do so after the jump, since the jump may depend on
                    878:         what's on the stack.  Thus, any stack-modifying conditional
                    879:         jumps (these are the only ones that rely on what's on the
                    880:         stack) go into the fixup list. */
                    881: 
                    882:       if (stack_level >= 0
                    883:          && stack_depth != stack_level
                    884:          && opcode != jump)
                    885: 
                    886:        bc_expand_fixup (opcode, label, stack_level);
                    887:       else
                    888:        {
                    889:          if (stack_level >= 0)
                    890:            bc_adjust_stack (stack_depth - stack_level);
                    891: 
                    892:          if (body && DECL_BIT_FIELD (body))
                    893:            error ("jump to `%s' invalidly jumps into binding contour",
                    894:                   IDENTIFIER_POINTER (DECL_NAME (body)));
                    895:          
                    896:          /* Emit immediate jump */
                    897:          bc_emit_bytecode (opcode);
                    898:          bc_emit_bytecode_labelref (label);
                    899:          
                    900: #ifdef DEBUG_PRINT_CODE
                    901:          fputc ('\n', stderr);
                    902: #endif
                    903:        }
                    904:     }
                    905:   else
                    906:     /* Put goto in the fixup list */
                    907:     bc_expand_fixup (opcode, label, stack_level);
                    908: }
                    909: 
1.1       root      910: /* Generate if necessary a fixup for a goto
                    911:    whose target label in tree structure (if any) is TREE_LABEL
                    912:    and whose target in rtl is RTL_LABEL.
                    913: 
                    914:    If LAST_INSN is nonzero, we pretend that the jump appears
                    915:    after insn LAST_INSN instead of at the current point in the insn stream.
                    916: 
1.1.1.4   root      917:    The fixup will be used later to insert insns just before the goto.
                    918:    Those insns will restore the stack level as appropriate for the
                    919:    target label, and will (in the case of C++) also invoke any object
                    920:    destructors which have to be invoked when we exit the scopes which
                    921:    are exited by the goto.
1.1       root      922: 
                    923:    Value is nonzero if a fixup is made.  */
                    924: 
                    925: static int
                    926: expand_fixup (tree_label, rtl_label, last_insn)
                    927:      tree tree_label;
                    928:      rtx rtl_label;
                    929:      rtx last_insn;
                    930: {
                    931:   struct nesting *block, *end_block;
                    932: 
                    933:   /* See if we can recognize which block the label will be output in.
                    934:      This is possible in some very common cases.
                    935:      If we succeed, set END_BLOCK to that block.
                    936:      Otherwise, set it to 0.  */
                    937: 
                    938:   if (cond_stack
                    939:       && (rtl_label == cond_stack->data.cond.endif_label
                    940:          || rtl_label == cond_stack->data.cond.next_label))
                    941:     end_block = cond_stack;
                    942:   /* If we are in a loop, recognize certain labels which
                    943:      are likely targets.  This reduces the number of fixups
                    944:      we need to create.  */
                    945:   else if (loop_stack
                    946:       && (rtl_label == loop_stack->data.loop.start_label
                    947:          || rtl_label == loop_stack->data.loop.end_label
                    948:          || rtl_label == loop_stack->data.loop.continue_label))
                    949:     end_block = loop_stack;
                    950:   else
                    951:     end_block = 0;
                    952: 
                    953:   /* Now set END_BLOCK to the binding level to which we will return.  */
                    954: 
                    955:   if (end_block)
                    956:     {
                    957:       struct nesting *next_block = end_block->all;
                    958:       block = block_stack;
                    959: 
                    960:       /* First see if the END_BLOCK is inside the innermost binding level.
                    961:         If so, then no cleanups or stack levels are relevant.  */
                    962:       while (next_block && next_block != block)
                    963:        next_block = next_block->all;
                    964: 
                    965:       if (next_block)
                    966:        return 0;
                    967: 
                    968:       /* Otherwise, set END_BLOCK to the innermost binding level
                    969:         which is outside the relevant control-structure nesting.  */
                    970:       next_block = block_stack->next;
                    971:       for (block = block_stack; block != end_block; block = block->all)
                    972:        if (block == next_block)
                    973:          next_block = next_block->next;
                    974:       end_block = next_block;
                    975:     }
                    976: 
                    977:   /* Does any containing block have a stack level or cleanups?
                    978:      If not, no fixup is needed, and that is the normal case
                    979:      (the only case, for standard C).  */
                    980:   for (block = block_stack; block != end_block; block = block->next)
                    981:     if (block->data.block.stack_level != 0
                    982:        || block->data.block.cleanups != 0)
                    983:       break;
                    984: 
                    985:   if (block != end_block)
                    986:     {
                    987:       /* Ok, a fixup is needed.  Add a fixup to the list of such.  */
                    988:       struct goto_fixup *fixup
                    989:        = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup));
                    990:       /* In case an old stack level is restored, make sure that comes
                    991:         after any pending stack adjust.  */
                    992:       /* ?? If the fixup isn't to come at the present position,
                    993:         doing the stack adjust here isn't useful.  Doing it with our
                    994:         settings at that location isn't useful either.  Let's hope
                    995:         someone does it!  */
                    996:       if (last_insn == 0)
                    997:        do_pending_stack_adjust ();
                    998:       fixup->target = tree_label;
                    999:       fixup->target_rtl = rtl_label;
1.1.1.4   root     1000: 
                   1001:       /* Create a BLOCK node and a corresponding matched set of
                   1002:         NOTE_INSN_BEGIN_BLOCK and NOTE_INSN_END_BLOCK notes at
                   1003:         this point.  The notes will encapsulate any and all fixup
                   1004:         code which we might later insert at this point in the insn
                   1005:         stream.  Also, the BLOCK node will be the parent (i.e. the
                   1006:         `SUPERBLOCK') of any other BLOCK nodes which we might create
                   1007:         later on when we are expanding the fixup code.  */
                   1008: 
                   1009:       {
                   1010:         register rtx original_before_jump
                   1011:           = last_insn ? last_insn : get_last_insn ();
                   1012: 
                   1013:         start_sequence ();
                   1014:         pushlevel (0);
                   1015:         fixup->before_jump = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
                   1016:         last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
                   1017:         fixup->context = poplevel (1, 0, 0);  /* Create the BLOCK node now! */
                   1018:         end_sequence ();
                   1019:         emit_insns_after (fixup->before_jump, original_before_jump);
                   1020:       }
                   1021: 
1.1       root     1022:       fixup->block_start_count = block_start_count;
                   1023:       fixup->stack_level = 0;
                   1024:       fixup->cleanup_list_list
                   1025:        = (((block->data.block.outer_cleanups
                   1026: #if 0
                   1027:             && block->data.block.outer_cleanups != empty_cleanup_list
                   1028: #endif
                   1029:             )
                   1030:            || block->data.block.cleanups)
1.1.1.4   root     1031:           ? tree_cons (NULL_TREE, block->data.block.cleanups,
1.1       root     1032:                        block->data.block.outer_cleanups)
                   1033:           : 0);
                   1034:       fixup->next = goto_fixup_chain;
                   1035:       goto_fixup_chain = fixup;
                   1036:     }
                   1037: 
                   1038:   return block != 0;
                   1039: }
                   1040: 
1.1.1.6   root     1041: 
                   1042: /* Generate bytecode jump with OPCODE to a fixup routine that links to LABEL.
                   1043:    Make the fixup restore the stack level to STACK_LEVEL.  */
                   1044: 
                   1045: static void
                   1046: bc_expand_fixup (opcode, label, stack_level)
                   1047:      enum bytecode_opcode opcode;
                   1048:      struct bc_label *label;
                   1049:      int stack_level;
                   1050: {
                   1051:   struct goto_fixup *fixup
                   1052:     = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup));
                   1053: 
                   1054:   fixup->label  = bc_get_bytecode_label ();
                   1055:   fixup->bc_target = label;
                   1056:   fixup->bc_stack_level = stack_level;
                   1057:   fixup->bc_handled = FALSE;
                   1058: 
                   1059:   fixup->next = goto_fixup_chain;
                   1060:   goto_fixup_chain = fixup;
                   1061: 
                   1062:   /* Insert a jump to the fixup code */
                   1063:   bc_emit_bytecode (opcode);
                   1064:   bc_emit_bytecode_labelref (fixup->label);
                   1065: 
                   1066: #ifdef DEBUG_PRINT_CODE
                   1067:   fputc ('\n', stderr);
                   1068: #endif
                   1069: }
1.1.1.7 ! root     1070: 
        !          1071: /* Expand any needed fixups in the outputmost binding level of the
        !          1072:    function.  FIRST_INSN is the first insn in the function.  */
1.1.1.6   root     1073: 
1.1.1.7 ! root     1074: void
        !          1075: expand_fixups (first_insn)
        !          1076:      rtx first_insn;
        !          1077: {
        !          1078:   fixup_gotos (NULL_PTR, NULL_RTX, NULL_TREE, first_insn, 0);
        !          1079: }
1.1.1.6   root     1080: 
1.1       root     1081: /* When exiting a binding contour, process all pending gotos requiring fixups.
                   1082:    THISBLOCK is the structure that describes the block being exited.
                   1083:    STACK_LEVEL is the rtx for the stack level to restore exiting this contour.
                   1084:    CLEANUP_LIST is a list of expressions to evaluate on exiting this contour.
                   1085:    FIRST_INSN is the insn that began this contour.
                   1086: 
                   1087:    Gotos that jump out of this contour must restore the
                   1088:    stack level and do the cleanups before actually jumping.
                   1089: 
                   1090:    DONT_JUMP_IN nonzero means report error there is a jump into this
                   1091:    contour from before the beginning of the contour.
                   1092:    This is also done if STACK_LEVEL is nonzero.  */
                   1093: 
1.1.1.7 ! root     1094: static void
1.1       root     1095: fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
                   1096:      struct nesting *thisblock;
                   1097:      rtx stack_level;
                   1098:      tree cleanup_list;
                   1099:      rtx first_insn;
                   1100:      int dont_jump_in;
                   1101: {
                   1102:   register struct goto_fixup *f, *prev;
                   1103: 
1.1.1.6   root     1104:   if (output_bytecode)
                   1105:     {
1.1.1.7 ! root     1106:       /* ??? The second arg is the bc stack level, which is not the same
        !          1107:         as STACK_LEVEL.  I have no idea what should go here, so I'll
        !          1108:         just pass 0.  */
        !          1109:       bc_fixup_gotos (thisblock, 0, cleanup_list, first_insn, dont_jump_in);
1.1.1.6   root     1110:       return;
                   1111:     }
                   1112: 
1.1       root     1113:   /* F is the fixup we are considering; PREV is the previous one.  */
                   1114:   /* We run this loop in two passes so that cleanups of exited blocks
                   1115:      are run first, and blocks that are exited are marked so
                   1116:      afterwards.  */
                   1117: 
                   1118:   for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
                   1119:     {
                   1120:       /* Test for a fixup that is inactive because it is already handled.  */
                   1121:       if (f->before_jump == 0)
                   1122:        {
                   1123:          /* Delete inactive fixup from the chain, if that is easy to do.  */
                   1124:          if (prev != 0)
                   1125:            prev->next = f->next;
                   1126:        }
                   1127:       /* Has this fixup's target label been defined?
                   1128:         If so, we can finalize it.  */
                   1129:       else if (PREV_INSN (f->target_rtl) != 0)
                   1130:        {
1.1.1.4   root     1131:          register rtx cleanup_insns;
                   1132: 
1.1       root     1133:          /* Get the first non-label after the label
                   1134:             this goto jumps to.  If that's before this scope begins,
                   1135:             we don't have a jump into the scope.  */
                   1136:          rtx after_label = f->target_rtl;
                   1137:          while (after_label != 0 && GET_CODE (after_label) == CODE_LABEL)
                   1138:            after_label = NEXT_INSN (after_label);
                   1139: 
                   1140:          /* If this fixup jumped into this contour from before the beginning
                   1141:             of this contour, report an error.  */
                   1142:          /* ??? Bug: this does not detect jumping in through intermediate
                   1143:             blocks that have stack levels or cleanups.
                   1144:             It detects only a problem with the innermost block
                   1145:             around the label.  */
                   1146:          if (f->target != 0
                   1147:              && (dont_jump_in || stack_level || cleanup_list)
                   1148:              /* If AFTER_LABEL is 0, it means the jump goes to the end
                   1149:                 of the rtl, which means it jumps into this scope.  */
                   1150:              && (after_label == 0
                   1151:                  || INSN_UID (first_insn) < INSN_UID (after_label))
                   1152:              && INSN_UID (first_insn) > INSN_UID (f->before_jump)
1.1.1.4   root     1153:              && ! DECL_REGISTER (f->target))
1.1       root     1154:            {
                   1155:              error_with_decl (f->target,
                   1156:                               "label `%s' used before containing binding contour");
                   1157:              /* Prevent multiple errors for one label.  */
1.1.1.4   root     1158:              DECL_REGISTER (f->target) = 1;
1.1       root     1159:            }
                   1160: 
1.1.1.4   root     1161:          /* We will expand the cleanups into a sequence of their own and
                   1162:             then later on we will attach this new sequence to the insn
                   1163:             stream just ahead of the actual jump insn.  */
                   1164: 
                   1165:          start_sequence ();
                   1166: 
                   1167:          /* Temporarily restore the lexical context where we will
                   1168:             logically be inserting the fixup code.  We do this for the
                   1169:             sake of getting the debugging information right.  */
                   1170: 
                   1171:          pushlevel (0);
                   1172:          set_block (f->context);
                   1173: 
                   1174:          /* Expand the cleanups for blocks this jump exits.  */
1.1       root     1175:          if (f->cleanup_list_list)
                   1176:            {
                   1177:              tree lists;
                   1178:              for (lists = f->cleanup_list_list; lists; lists = TREE_CHAIN (lists))
                   1179:                /* Marked elements correspond to blocks that have been closed.
                   1180:                   Do their cleanups.  */
                   1181:                if (TREE_ADDRESSABLE (lists)
                   1182:                    && TREE_VALUE (lists) != 0)
1.1.1.4   root     1183:                  {
                   1184:                    expand_cleanups (TREE_VALUE (lists), 0);
                   1185:                    /* Pop any pushes done in the cleanups,
                   1186:                       in case function is about to return.  */
                   1187:                    do_pending_stack_adjust ();
                   1188:                  }
1.1       root     1189:            }
                   1190: 
                   1191:          /* Restore stack level for the biggest contour that this
                   1192:             jump jumps out of.  */
                   1193:          if (f->stack_level)
1.1.1.3   root     1194:            emit_stack_restore (SAVE_BLOCK, f->stack_level, f->before_jump);
1.1.1.4   root     1195: 
                   1196:          /* Finish up the sequence containing the insns which implement the
                   1197:             necessary cleanups, and then attach that whole sequence to the
                   1198:             insn stream just ahead of the actual jump insn.  Attaching it
                   1199:             at that point insures that any cleanups which are in fact
                   1200:             implicit C++ object destructions (which must be executed upon
                   1201:             leaving the block) appear (to the debugger) to be taking place
                   1202:             in an area of the generated code where the object(s) being
                   1203:             destructed are still "in scope".  */
                   1204: 
                   1205:          cleanup_insns = get_insns ();
                   1206:          poplevel (1, 0, 0);
                   1207: 
                   1208:          end_sequence ();
                   1209:          emit_insns_after (cleanup_insns, f->before_jump);
                   1210: 
                   1211: 
1.1       root     1212:          f->before_jump = 0;
                   1213:        }
                   1214:     }
                   1215: 
                   1216:   /* Mark the cleanups of exited blocks so that they are executed
                   1217:      by the code above.  */
                   1218:   for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
                   1219:     if (f->before_jump != 0
                   1220:        && PREV_INSN (f->target_rtl) == 0
                   1221:        /* Label has still not appeared.  If we are exiting a block with
                   1222:           a stack level to restore, that started before the fixup,
                   1223:           mark this stack level as needing restoration
                   1224:           when the fixup is later finalized.
                   1225:           Also mark the cleanup_list_list element for F
                   1226:           that corresponds to this block, so that ultimately
                   1227:           this block's cleanups will be executed by the code above.  */
                   1228:        && thisblock != 0
                   1229:        /* Note: if THISBLOCK == 0 and we have a label that hasn't appeared,
                   1230:           it means the label is undefined.  That's erroneous, but possible.  */
                   1231:        && (thisblock->data.block.block_start_count
                   1232:            <= f->block_start_count))
                   1233:       {
                   1234:        tree lists = f->cleanup_list_list;
                   1235:        for (; lists; lists = TREE_CHAIN (lists))
                   1236:          /* If the following elt. corresponds to our containing block
                   1237:             then the elt. must be for this block.  */
                   1238:          if (TREE_CHAIN (lists) == thisblock->data.block.outer_cleanups)
                   1239:            TREE_ADDRESSABLE (lists) = 1;
                   1240: 
                   1241:        if (stack_level)
                   1242:          f->stack_level = stack_level;
                   1243:       }
                   1244: }
1.1.1.6   root     1245: 
                   1246: 
                   1247: /* When exiting a binding contour, process all pending gotos requiring fixups.
                   1248:    Note: STACK_DEPTH is not altered.
                   1249: 
1.1.1.7 ! root     1250:    The arguments are currently not used in the bytecode compiler, but we may
        !          1251:    need them one day for languages other than C.
1.1.1.6   root     1252: 
                   1253:    THISBLOCK is the structure that describes the block being exited.
                   1254:    STACK_LEVEL is the rtx for the stack level to restore exiting this contour.
                   1255:    CLEANUP_LIST is a list of expressions to evaluate on exiting this contour.
                   1256:    FIRST_INSN is the insn that began this contour.
                   1257: 
                   1258:    Gotos that jump out of this contour must restore the
                   1259:    stack level and do the cleanups before actually jumping.
                   1260: 
                   1261:    DONT_JUMP_IN nonzero means report error there is a jump into this
                   1262:    contour from before the beginning of the contour.
                   1263:    This is also done if STACK_LEVEL is nonzero.  */
                   1264: 
                   1265: static void
                   1266: bc_fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
                   1267:      struct nesting *thisblock;
                   1268:      int stack_level;
                   1269:      tree cleanup_list;
                   1270:      rtx first_insn;
                   1271:      int dont_jump_in;
                   1272: {
                   1273:   register struct goto_fixup *f, *prev;
                   1274:   int saved_stack_depth;
                   1275: 
                   1276:   /* F is the fixup we are considering; PREV is the previous one.  */
                   1277: 
                   1278:   for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
                   1279:     {
                   1280:       /* Test for a fixup that is inactive because it is already handled.  */
                   1281:       if (f->before_jump == 0)
                   1282:        {
                   1283:          /* Delete inactive fixup from the chain, if that is easy to do.  */
                   1284:          if (prev)
                   1285:            prev->next = f->next;
                   1286:        }
                   1287: 
                   1288:       /* Emit code to restore the stack and continue */
                   1289:       bc_emit_bytecode_labeldef (f->label);
                   1290: 
                   1291:       /* Save stack_depth across call, since bc_adjust_stack () will alter
                   1292:          the perceived stack depth via the instructions generated. */
                   1293: 
                   1294:       if (f->bc_stack_level >= 0)
                   1295:        {
                   1296:          saved_stack_depth = stack_depth;
                   1297:          bc_adjust_stack (stack_depth - f->bc_stack_level);
                   1298:          stack_depth = saved_stack_depth;
                   1299:        }
                   1300: 
                   1301:       bc_emit_bytecode (jump);
                   1302:       bc_emit_bytecode_labelref (f->bc_target);
                   1303: 
                   1304: #ifdef DEBUG_PRINT_CODE
                   1305:   fputc ('\n', stderr);
                   1306: #endif
                   1307:     }
                   1308: 
                   1309:   goto_fixup_chain = NULL;
                   1310: }
1.1       root     1311: 
                   1312: /* Generate RTL for an asm statement (explicit assembler code).
                   1313:    BODY is a STRING_CST node containing the assembler code text,
                   1314:    or an ADDR_EXPR containing a STRING_CST.  */
                   1315: 
                   1316: void
                   1317: expand_asm (body)
                   1318:      tree body;
                   1319: {
1.1.1.6   root     1320:   if (output_bytecode)
                   1321:     {
                   1322:       error ("`asm' is illegal when generating bytecode");
                   1323:       return;
                   1324:     }
                   1325: 
1.1       root     1326:   if (TREE_CODE (body) == ADDR_EXPR)
                   1327:     body = TREE_OPERAND (body, 0);
                   1328: 
                   1329:   emit_insn (gen_rtx (ASM_INPUT, VOIDmode,
                   1330:                      TREE_STRING_POINTER (body)));
                   1331:   last_expr_type = 0;
                   1332: }
                   1333: 
                   1334: /* Generate RTL for an asm statement with arguments.
                   1335:    STRING is the instruction template.
                   1336:    OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
                   1337:    Each output or input has an expression in the TREE_VALUE and
                   1338:    a constraint-string in the TREE_PURPOSE.
                   1339:    CLOBBERS is a list of STRING_CST nodes each naming a hard register
                   1340:    that is clobbered by this insn.
                   1341: 
                   1342:    Not all kinds of lvalue that may appear in OUTPUTS can be stored directly.
                   1343:    Some elements of OUTPUTS may be replaced with trees representing temporary
                   1344:    values.  The caller should copy those temporary values to the originally
                   1345:    specified lvalues.
                   1346: 
                   1347:    VOL nonzero means the insn is volatile; don't optimize it.  */
                   1348: 
                   1349: void
                   1350: expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
                   1351:      tree string, outputs, inputs, clobbers;
                   1352:      int vol;
                   1353:      char *filename;
                   1354:      int line;
                   1355: {
                   1356:   rtvec argvec, constraints;
                   1357:   rtx body;
                   1358:   int ninputs = list_length (inputs);
                   1359:   int noutputs = list_length (outputs);
1.1.1.3   root     1360:   int nclobbers;
1.1       root     1361:   tree tail;
                   1362:   register int i;
                   1363:   /* Vector of RTX's of evaluated output operands.  */
                   1364:   rtx *output_rtx = (rtx *) alloca (noutputs * sizeof (rtx));
                   1365:   /* The insn we have emitted.  */
                   1366:   rtx insn;
                   1367: 
1.1.1.6   root     1368:   if (output_bytecode)
                   1369:     {
                   1370:       error ("`asm' is illegal when generating bytecode");
                   1371:       return;
                   1372:     }
                   1373: 
1.1.1.3   root     1374:   /* Count the number of meaningful clobbered registers, ignoring what
                   1375:      we would ignore later.  */
                   1376:   nclobbers = 0;
                   1377:   for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
                   1378:     {
                   1379:       char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
1.1.1.4   root     1380:       i = decode_reg_name (regname);
                   1381:       if (i >= 0 || i == -4)
1.1.1.3   root     1382:        ++nclobbers;
1.1.1.7 ! root     1383:       else if (i == -2)
        !          1384:        error ("unknown register name `%s' in `asm'", regname);
1.1.1.3   root     1385:     }
                   1386: 
1.1       root     1387:   last_expr_type = 0;
                   1388: 
                   1389:   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
                   1390:     {
                   1391:       tree val = TREE_VALUE (tail);
                   1392:       tree val1;
                   1393:       int j;
                   1394:       int found_equal;
                   1395: 
                   1396:       /* If there's an erroneous arg, emit no insn.  */
                   1397:       if (TREE_TYPE (val) == error_mark_node)
                   1398:        return;
                   1399: 
                   1400:       /* Make sure constraint has `=' and does not have `+'.  */
                   1401: 
                   1402:       found_equal = 0;
                   1403:       for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++)
                   1404:        {
                   1405:          if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
                   1406:            {
                   1407:              error ("output operand constraint contains `+'");
                   1408:              return;
                   1409:            }
                   1410:          if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '=')
                   1411:            found_equal = 1;
                   1412:        }
                   1413:       if (! found_equal)
                   1414:        {
                   1415:          error ("output operand constraint lacks `='");
                   1416:          return;
                   1417:        }
                   1418: 
                   1419:       /* If an output operand is not a variable or indirect ref,
                   1420:         or a part of one,
                   1421:         create a SAVE_EXPR which is a pseudo-reg
                   1422:         to act as an intermediate temporary.
                   1423:         Make the asm insn write into that, then copy it to
                   1424:         the real output operand.  */
                   1425: 
                   1426:       while (TREE_CODE (val) == COMPONENT_REF
                   1427:             || TREE_CODE (val) == ARRAY_REF)
                   1428:        val = TREE_OPERAND (val, 0);
                   1429: 
                   1430:       if (TREE_CODE (val) != VAR_DECL
                   1431:          && TREE_CODE (val) != PARM_DECL
                   1432:          && TREE_CODE (val) != INDIRECT_REF)
1.1.1.5   root     1433:        {
                   1434:          TREE_VALUE (tail) = save_expr (TREE_VALUE (tail));
                   1435:          /* If it's a constant, print error now so don't crash later.  */
                   1436:          if (TREE_CODE (TREE_VALUE (tail)) != SAVE_EXPR)
                   1437:            {
                   1438:              error ("invalid output in `asm'");
                   1439:              return;
                   1440:            }
                   1441:        }
1.1       root     1442: 
1.1.1.4   root     1443:       output_rtx[i] = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
1.1       root     1444:     }
                   1445: 
                   1446:   if (ninputs + noutputs > MAX_RECOG_OPERANDS)
                   1447:     {
                   1448:       error ("more than %d operands in `asm'", MAX_RECOG_OPERANDS);
                   1449:       return;
                   1450:     }
                   1451: 
                   1452:   /* Make vectors for the expression-rtx and constraint strings.  */
                   1453: 
                   1454:   argvec = rtvec_alloc (ninputs);
                   1455:   constraints = rtvec_alloc (ninputs);
                   1456: 
                   1457:   body = gen_rtx (ASM_OPERANDS, VOIDmode,
                   1458:                  TREE_STRING_POINTER (string), "", 0, argvec, constraints,
                   1459:                  filename, line);
                   1460:   MEM_VOLATILE_P (body) = vol;
                   1461: 
                   1462:   /* Eval the inputs and put them into ARGVEC.
                   1463:      Put their constraints into ASM_INPUTs and store in CONSTRAINTS.  */
                   1464: 
                   1465:   i = 0;
                   1466:   for (tail = inputs; tail; tail = TREE_CHAIN (tail))
                   1467:     {
                   1468:       int j;
                   1469: 
                   1470:       /* If there's an erroneous arg, emit no insn,
                   1471:         because the ASM_INPUT would get VOIDmode
                   1472:         and that could cause a crash in reload.  */
                   1473:       if (TREE_TYPE (TREE_VALUE (tail)) == error_mark_node)
                   1474:        return;
                   1475:       if (TREE_PURPOSE (tail) == NULL_TREE)
                   1476:        {
                   1477:          error ("hard register `%s' listed as input operand to `asm'",
                   1478:                 TREE_STRING_POINTER (TREE_VALUE (tail)) );
                   1479:          return;
                   1480:        }
                   1481: 
                   1482:       /* Make sure constraint has neither `=' nor `+'.  */
                   1483: 
                   1484:       for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++)
                   1485:        if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '='
                   1486:            || TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
                   1487:          {
                   1488:            error ("input operand constraint contains `%c'",
                   1489:                   TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
                   1490:            return;
                   1491:          }
                   1492: 
                   1493:       XVECEXP (body, 3, i)      /* argvec */
1.1.1.4   root     1494:        = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
1.1       root     1495:       XVECEXP (body, 4, i)      /* constraints */
                   1496:        = gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
                   1497:                   TREE_STRING_POINTER (TREE_PURPOSE (tail)));
                   1498:       i++;
                   1499:     }
                   1500: 
                   1501:   /* Protect all the operands from the queue,
                   1502:      now that they have all been evaluated.  */
                   1503: 
                   1504:   for (i = 0; i < ninputs; i++)
                   1505:     XVECEXP (body, 3, i) = protect_from_queue (XVECEXP (body, 3, i), 0);
                   1506: 
                   1507:   for (i = 0; i < noutputs; i++)
                   1508:     output_rtx[i] = protect_from_queue (output_rtx[i], 1);
                   1509: 
                   1510:   /* Now, for each output, construct an rtx
                   1511:      (set OUTPUT (asm_operands INSN OUTPUTNUMBER OUTPUTCONSTRAINT
                   1512:                               ARGVEC CONSTRAINTS))
                   1513:      If there is more than one, put them inside a PARALLEL.  */
                   1514: 
                   1515:   if (noutputs == 1 && nclobbers == 0)
                   1516:     {
                   1517:       XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs));
                   1518:       insn = emit_insn (gen_rtx (SET, VOIDmode, output_rtx[0], body));
                   1519:     }
                   1520:   else if (noutputs == 0 && nclobbers == 0)
                   1521:     {
                   1522:       /* No output operands: put in a raw ASM_OPERANDS rtx.  */
                   1523:       insn = emit_insn (body);
                   1524:     }
                   1525:   else
                   1526:     {
                   1527:       rtx obody = body;
                   1528:       int num = noutputs;
                   1529:       if (num == 0) num = 1;
                   1530:       body = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num + nclobbers));
                   1531: 
                   1532:       /* For each output operand, store a SET.  */
                   1533: 
                   1534:       for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
                   1535:        {
                   1536:          XVECEXP (body, 0, i)
                   1537:            = gen_rtx (SET, VOIDmode,
                   1538:                       output_rtx[i],
                   1539:                       gen_rtx (ASM_OPERANDS, VOIDmode,
                   1540:                                TREE_STRING_POINTER (string),
                   1541:                                TREE_STRING_POINTER (TREE_PURPOSE (tail)),
                   1542:                                i, argvec, constraints,
                   1543:                                filename, line));
                   1544:          MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
                   1545:        }
                   1546: 
                   1547:       /* If there are no outputs (but there are some clobbers)
                   1548:         store the bare ASM_OPERANDS into the PARALLEL.  */
                   1549: 
                   1550:       if (i == 0)
                   1551:        XVECEXP (body, 0, i++) = obody;
                   1552: 
                   1553:       /* Store (clobber REG) for each clobbered register specified.  */
                   1554: 
1.1.1.3   root     1555:       for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
1.1       root     1556:        {
                   1557:          char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
1.1.1.2   root     1558:          int j = decode_reg_name (regname);
1.1       root     1559: 
1.1.1.2   root     1560:          if (j < 0)
1.1       root     1561:            {
1.1.1.4   root     1562:              if (j == -3)      /* `cc', which is not a register */
1.1.1.3   root     1563:                continue;
                   1564: 
1.1.1.4   root     1565:              if (j == -4)      /* `memory', don't cache memory across asm */
                   1566:                {
1.1.1.5   root     1567:                  XVECEXP (body, 0, i++)
                   1568:                    = gen_rtx (CLOBBER, VOIDmode,
1.1.1.7 ! root     1569:                               gen_rtx (MEM, BLKmode,
1.1.1.5   root     1570:                                        gen_rtx (SCRATCH, VOIDmode, 0)));
1.1.1.4   root     1571:                  continue;
                   1572:                }
                   1573: 
1.1.1.7 ! root     1574:              /* Ignore unknown register, error already signalled.  */
1.1       root     1575:            }
                   1576: 
                   1577:          /* Use QImode since that's guaranteed to clobber just one reg.  */
1.1.1.3   root     1578:          XVECEXP (body, 0, i++)
1.1       root     1579:            = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, QImode, j));
                   1580:        }
                   1581: 
                   1582:       insn = emit_insn (body);
                   1583:     }
                   1584: 
                   1585:   free_temp_slots ();
                   1586: }
                   1587: 
                   1588: /* Generate RTL to evaluate the expression EXP
                   1589:    and remember it in case this is the VALUE in a ({... VALUE; }) constr.  */
                   1590: 
                   1591: void
                   1592: expand_expr_stmt (exp)
                   1593:      tree exp;
                   1594: {
1.1.1.6   root     1595:   if (output_bytecode)
                   1596:     {
                   1597:       int org_stack_depth = stack_depth;
                   1598: 
                   1599:       bc_expand_expr (exp);
                   1600: 
                   1601:       /* Restore stack depth */
                   1602:       if (stack_depth < org_stack_depth)
                   1603:        abort ();
                   1604:       
                   1605:       bc_emit_instruction (drop);
                   1606: 
                   1607:       last_expr_type = TREE_TYPE (exp);
                   1608:       return;
                   1609:     }
                   1610: 
1.1       root     1611:   /* If -W, warn about statements with no side effects,
                   1612:      except for an explicit cast to void (e.g. for assert()), and
                   1613:      except inside a ({...}) where they may be useful.  */
                   1614:   if (expr_stmts_for_value == 0 && exp != error_mark_node)
                   1615:     {
                   1616:       if (! TREE_SIDE_EFFECTS (exp) && (extra_warnings || warn_unused)
                   1617:          && !(TREE_CODE (exp) == CONVERT_EXPR
                   1618:               && TREE_TYPE (exp) == void_type_node))
                   1619:        warning_with_file_and_line (emit_filename, emit_lineno,
                   1620:                                    "statement with no effect");
                   1621:       else if (warn_unused)
                   1622:        warn_if_unused_value (exp);
                   1623:     }
                   1624:   last_expr_type = TREE_TYPE (exp);
                   1625:   if (! flag_syntax_only)
1.1.1.4   root     1626:     last_expr_value = expand_expr (exp,
                   1627:                                   (expr_stmts_for_value
                   1628:                                    ? NULL_RTX : const0_rtx),
1.1       root     1629:                                   VOIDmode, 0);
                   1630: 
                   1631:   /* If all we do is reference a volatile value in memory,
                   1632:      copy it to a register to be sure it is actually touched.  */
                   1633:   if (last_expr_value != 0 && GET_CODE (last_expr_value) == MEM
                   1634:       && TREE_THIS_VOLATILE (exp))
                   1635:     {
1.1.1.5   root     1636:       if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode)
                   1637:        ;
                   1638:       else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode)
1.1       root     1639:        copy_to_reg (last_expr_value);
                   1640:       else
1.1.1.3   root     1641:        {
                   1642:          rtx lab = gen_label_rtx ();
                   1643:          
                   1644:          /* Compare the value with itself to reference it.  */
                   1645:          emit_cmp_insn (last_expr_value, last_expr_value, EQ,
                   1646:                         expand_expr (TYPE_SIZE (last_expr_type),
1.1.1.4   root     1647:                                      NULL_RTX, VOIDmode, 0),
1.1.1.3   root     1648:                         BLKmode, 0,
                   1649:                         TYPE_ALIGN (last_expr_type) / BITS_PER_UNIT);
                   1650:          emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (lab));
                   1651:          emit_label (lab);
                   1652:        }
1.1       root     1653:     }
                   1654: 
                   1655:   /* If this expression is part of a ({...}) and is in memory, we may have
                   1656:      to preserve temporaries.  */
                   1657:   preserve_temp_slots (last_expr_value);
                   1658: 
                   1659:   /* Free any temporaries used to evaluate this expression.  Any temporary
                   1660:      used as a result of this expression will already have been preserved
                   1661:      above.  */
                   1662:   free_temp_slots ();
                   1663: 
                   1664:   emit_queue ();
                   1665: }
                   1666: 
                   1667: /* Warn if EXP contains any computations whose results are not used.
                   1668:    Return 1 if a warning is printed; 0 otherwise.  */
                   1669: 
                   1670: static int
                   1671: warn_if_unused_value (exp)
                   1672:      tree exp;
                   1673: {
                   1674:   if (TREE_USED (exp))
                   1675:     return 0;
                   1676: 
                   1677:   switch (TREE_CODE (exp))
                   1678:     {
                   1679:     case PREINCREMENT_EXPR:
                   1680:     case POSTINCREMENT_EXPR:
                   1681:     case PREDECREMENT_EXPR:
                   1682:     case POSTDECREMENT_EXPR:
                   1683:     case MODIFY_EXPR:
                   1684:     case INIT_EXPR:
                   1685:     case TARGET_EXPR:
                   1686:     case CALL_EXPR:
                   1687:     case METHOD_CALL_EXPR:
                   1688:     case RTL_EXPR:
                   1689:     case WITH_CLEANUP_EXPR:
                   1690:     case EXIT_EXPR:
                   1691:       /* We don't warn about COND_EXPR because it may be a useful
                   1692:         construct if either arm contains a side effect.  */
                   1693:     case COND_EXPR:
                   1694:       return 0;
                   1695: 
                   1696:     case BIND_EXPR:
                   1697:       /* For a binding, warn if no side effect within it.  */
                   1698:       return warn_if_unused_value (TREE_OPERAND (exp, 1));
                   1699: 
                   1700:     case TRUTH_ORIF_EXPR:
                   1701:     case TRUTH_ANDIF_EXPR:
                   1702:       /* In && or ||, warn if 2nd operand has no side effect.  */
                   1703:       return warn_if_unused_value (TREE_OPERAND (exp, 1));
                   1704: 
                   1705:     case COMPOUND_EXPR:
1.1.1.7 ! root     1706:       if (TREE_NO_UNUSED_WARNING (exp))
        !          1707:        return 0;
1.1       root     1708:       if (warn_if_unused_value (TREE_OPERAND (exp, 0)))
                   1709:        return 1;
1.1.1.3   root     1710:       /* Let people do `(foo (), 0)' without a warning.  */
                   1711:       if (TREE_CONSTANT (TREE_OPERAND (exp, 1)))
                   1712:        return 0;
1.1       root     1713:       return warn_if_unused_value (TREE_OPERAND (exp, 1));
                   1714: 
                   1715:     case NOP_EXPR:
                   1716:     case CONVERT_EXPR:
1.1.1.2   root     1717:     case NON_LVALUE_EXPR:
1.1       root     1718:       /* Don't warn about values cast to void.  */
                   1719:       if (TREE_TYPE (exp) == void_type_node)
                   1720:        return 0;
                   1721:       /* Don't warn about conversions not explicit in the user's program.  */
                   1722:       if (TREE_NO_UNUSED_WARNING (exp))
                   1723:        return 0;
                   1724:       /* Assignment to a cast usually results in a cast of a modify.
1.1.1.6   root     1725:         Don't complain about that.  There can be an arbitrary number of
                   1726:         casts before the modify, so we must loop until we find the first
                   1727:         non-cast expression and then test to see if that is a modify.  */
                   1728:       {
                   1729:        tree tem = TREE_OPERAND (exp, 0);
                   1730: 
                   1731:        while (TREE_CODE (tem) == CONVERT_EXPR || TREE_CODE (tem) == NOP_EXPR)
                   1732:          tem = TREE_OPERAND (tem, 0);
                   1733: 
1.1.1.7 ! root     1734:        if (TREE_CODE (tem) == MODIFY_EXPR || TREE_CODE (tem) == INIT_EXPR)
1.1.1.6   root     1735:          return 0;
                   1736:       }
                   1737:       /* ... fall through ... */
1.1       root     1738: 
                   1739:     default:
1.1.1.3   root     1740:       /* Referencing a volatile value is a side effect, so don't warn.  */
                   1741:       if ((TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
                   1742:           || TREE_CODE_CLASS (TREE_CODE (exp)) == 'r')
                   1743:          && TREE_THIS_VOLATILE (exp))
                   1744:        return 0;
1.1       root     1745:       warning_with_file_and_line (emit_filename, emit_lineno,
                   1746:                                  "value computed is not used");
                   1747:       return 1;
                   1748:     }
                   1749: }
                   1750: 
                   1751: /* Clear out the memory of the last expression evaluated.  */
                   1752: 
                   1753: void
                   1754: clear_last_expr ()
                   1755: {
                   1756:   last_expr_type = 0;
                   1757: }
                   1758: 
                   1759: /* Begin a statement which will return a value.
                   1760:    Return the RTL_EXPR for this statement expr.
                   1761:    The caller must save that value and pass it to expand_end_stmt_expr.  */
                   1762: 
                   1763: tree
                   1764: expand_start_stmt_expr ()
                   1765: {
1.1.1.6   root     1766:   int momentary;
                   1767:   tree t;
                   1768: 
                   1769:   /* When generating bytecode just note down the stack depth */
                   1770:   if (output_bytecode)
                   1771:     return (build_int_2 (stack_depth, 0));
                   1772: 
1.1       root     1773:   /* Make the RTL_EXPR node temporary, not momentary,
                   1774:      so that rtl_expr_chain doesn't become garbage.  */
1.1.1.6   root     1775:   momentary = suspend_momentary ();
                   1776:   t = make_node (RTL_EXPR);
1.1       root     1777:   resume_momentary (momentary);
1.1.1.6   root     1778:   start_sequence_for_rtl_expr (t);
1.1       root     1779:   NO_DEFER_POP;
                   1780:   expr_stmts_for_value++;
                   1781:   return t;
                   1782: }
                   1783: 
                   1784: /* Restore the previous state at the end of a statement that returns a value.
                   1785:    Returns a tree node representing the statement's value and the
                   1786:    insns to compute the value.
                   1787: 
                   1788:    The nodes of that expression have been freed by now, so we cannot use them.
                   1789:    But we don't want to do that anyway; the expression has already been
                   1790:    evaluated and now we just want to use the value.  So generate a RTL_EXPR
                   1791:    with the proper type and RTL value.
                   1792: 
                   1793:    If the last substatement was not an expression,
                   1794:    return something with type `void'.  */
                   1795: 
                   1796: tree
                   1797: expand_end_stmt_expr (t)
                   1798:      tree t;
                   1799: {
1.1.1.6   root     1800:   if (output_bytecode)
                   1801:     {
                   1802:       int i;
                   1803:       tree t;
                   1804:       
                   1805:       
                   1806:       /* At this point, all expressions have been evaluated in order.
                   1807:         However, all expression values have been popped when evaluated,
                   1808:         which means we have to recover the last expression value.  This is
                   1809:         the last value removed by means of a `drop' instruction.  Instead
                   1810:         of adding code to inhibit dropping the last expression value, it
                   1811:         is here recovered by undoing the `drop'.  Since `drop' is
                   1812:         equivalent to `adjustackSI [1]', it can be undone with `adjstackSI
                   1813:         [-1]'. */
                   1814:       
                   1815:       bc_adjust_stack (-1);
                   1816:       
                   1817:       if (!last_expr_type)
                   1818:        last_expr_type = void_type_node;
                   1819:       
                   1820:       t = make_node (RTL_EXPR);
                   1821:       TREE_TYPE (t) = last_expr_type;
                   1822:       RTL_EXPR_RTL (t) = NULL;
                   1823:       RTL_EXPR_SEQUENCE (t) = NULL;
                   1824:       
                   1825:       /* Don't consider deleting this expr or containing exprs at tree level.  */
                   1826:       TREE_THIS_VOLATILE (t) = 1;
                   1827:       
                   1828:       last_expr_type = 0;
                   1829:       return t;
                   1830:     }
                   1831: 
1.1       root     1832:   OK_DEFER_POP;
                   1833: 
                   1834:   if (last_expr_type == 0)
                   1835:     {
                   1836:       last_expr_type = void_type_node;
                   1837:       last_expr_value = const0_rtx;
                   1838:     }
                   1839:   else if (last_expr_value == 0)
                   1840:     /* There are some cases where this can happen, such as when the
                   1841:        statement is void type.  */
                   1842:     last_expr_value = const0_rtx;
                   1843:   else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))
                   1844:     /* Remove any possible QUEUED.  */
                   1845:     last_expr_value = protect_from_queue (last_expr_value, 0);
                   1846: 
                   1847:   emit_queue ();
                   1848: 
                   1849:   TREE_TYPE (t) = last_expr_type;
                   1850:   RTL_EXPR_RTL (t) = last_expr_value;
                   1851:   RTL_EXPR_SEQUENCE (t) = get_insns ();
                   1852: 
                   1853:   rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);
                   1854: 
                   1855:   end_sequence ();
                   1856: 
                   1857:   /* Don't consider deleting this expr or containing exprs at tree level.  */
                   1858:   TREE_SIDE_EFFECTS (t) = 1;
                   1859:   /* Propagate volatility of the actual RTL expr.  */
                   1860:   TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);
                   1861: 
                   1862:   last_expr_type = 0;
                   1863:   expr_stmts_for_value--;
                   1864: 
                   1865:   return t;
                   1866: }
                   1867: 
                   1868: /* Generate RTL for the start of an if-then.  COND is the expression
                   1869:    whose truth should be tested.
                   1870: 
                   1871:    If EXITFLAG is nonzero, this conditional is visible to
                   1872:    `exit_something'.  */
                   1873: 
                   1874: void
                   1875: expand_start_cond (cond, exitflag)
                   1876:      tree cond;
                   1877:      int exitflag;
                   1878: {
                   1879:   struct nesting *thiscond = ALLOC_NESTING ();
                   1880: 
                   1881:   /* Make an entry on cond_stack for the cond we are entering.  */
                   1882: 
                   1883:   thiscond->next = cond_stack;
                   1884:   thiscond->all = nesting_stack;
                   1885:   thiscond->depth = ++nesting_depth;
                   1886:   thiscond->data.cond.next_label = gen_label_rtx ();
                   1887:   /* Before we encounter an `else', we don't need a separate exit label
                   1888:      unless there are supposed to be exit statements
                   1889:      to exit this conditional.  */
                   1890:   thiscond->exit_label = exitflag ? gen_label_rtx () : 0;
                   1891:   thiscond->data.cond.endif_label = thiscond->exit_label;
                   1892:   cond_stack = thiscond;
                   1893:   nesting_stack = thiscond;
                   1894: 
1.1.1.6   root     1895:   if (output_bytecode)
                   1896:     bc_expand_start_cond (cond, exitflag);
                   1897:   else
                   1898:     do_jump (cond, thiscond->data.cond.next_label, NULL_RTX);
1.1       root     1899: }
                   1900: 
                   1901: /* Generate RTL between then-clause and the elseif-clause
                   1902:    of an if-then-elseif-....  */
                   1903: 
                   1904: void
                   1905: expand_start_elseif (cond)
                   1906:      tree cond;
                   1907: {
                   1908:   if (cond_stack->data.cond.endif_label == 0)
                   1909:     cond_stack->data.cond.endif_label = gen_label_rtx ();
                   1910:   emit_jump (cond_stack->data.cond.endif_label);
                   1911:   emit_label (cond_stack->data.cond.next_label);
                   1912:   cond_stack->data.cond.next_label = gen_label_rtx ();
1.1.1.4   root     1913:   do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX);
1.1       root     1914: }
                   1915: 
                   1916: /* Generate RTL between the then-clause and the else-clause
                   1917:    of an if-then-else.  */
                   1918: 
                   1919: void
                   1920: expand_start_else ()
                   1921: {
                   1922:   if (cond_stack->data.cond.endif_label == 0)
                   1923:     cond_stack->data.cond.endif_label = gen_label_rtx ();
1.1.1.6   root     1924: 
                   1925:   if (output_bytecode)
                   1926:     {
                   1927:       bc_expand_start_else ();
                   1928:       return;
                   1929:     }
                   1930: 
1.1       root     1931:   emit_jump (cond_stack->data.cond.endif_label);
                   1932:   emit_label (cond_stack->data.cond.next_label);
                   1933:   cond_stack->data.cond.next_label = 0;  /* No more _else or _elseif calls. */
                   1934: }
                   1935: 
1.1.1.7 ! root     1936: /* After calling expand_start_else, turn this "else" into an "else if"
        !          1937:    by providing another condition.  */
        !          1938: 
        !          1939: void
        !          1940: expand_elseif (cond)
        !          1941:      tree cond;
        !          1942: {
        !          1943:   cond_stack->data.cond.next_label = gen_label_rtx ();
        !          1944:   do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX);
        !          1945: }
        !          1946: 
1.1       root     1947: /* Generate RTL for the end of an if-then.
                   1948:    Pop the record for it off of cond_stack.  */
                   1949: 
                   1950: void
                   1951: expand_end_cond ()
                   1952: {
                   1953:   struct nesting *thiscond = cond_stack;
                   1954: 
1.1.1.6   root     1955:   if (output_bytecode)
                   1956:     bc_expand_end_cond ();
                   1957:   else
                   1958:     {
                   1959:       do_pending_stack_adjust ();
                   1960:       if (thiscond->data.cond.next_label)
                   1961:        emit_label (thiscond->data.cond.next_label);
                   1962:       if (thiscond->data.cond.endif_label)
                   1963:        emit_label (thiscond->data.cond.endif_label);
                   1964:     }
1.1       root     1965: 
                   1966:   POPSTACK (cond_stack);
                   1967:   last_expr_type = 0;
                   1968: }
1.1.1.6   root     1969: 
                   1970: 
                   1971: /* Generate code for the start of an if-then.  COND is the expression
                   1972:    whose truth is to be tested; if EXITFLAG is nonzero this conditional
                   1973:    is to be visible to exit_something.  It is assumed that the caller
                   1974:    has pushed the previous context on the cond stack. */
1.1.1.7 ! root     1975: 
        !          1976: static void
1.1.1.6   root     1977: bc_expand_start_cond (cond, exitflag)
                   1978:      tree cond;
                   1979:      int exitflag;
                   1980: {
                   1981:   struct nesting *thiscond = cond_stack;
                   1982: 
                   1983:   thiscond->data.case_stmt.nominal_type = cond;
1.1.1.7 ! root     1984:   if (! exitflag)
        !          1985:     thiscond->exit_label = gen_label_rtx ();
1.1.1.6   root     1986:   bc_expand_expr (cond);
                   1987:   bc_emit_bytecode (xjumpifnot);
                   1988:   bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscond->exit_label));
                   1989: 
                   1990: #ifdef DEBUG_PRINT_CODE
                   1991:   fputc ('\n', stderr);
                   1992: #endif
                   1993: }
                   1994: 
                   1995: /* Generate the label for the end of an if with
                   1996:    no else- clause.  */
1.1.1.7 ! root     1997: 
        !          1998: static void
1.1.1.6   root     1999: bc_expand_end_cond ()
                   2000: {
                   2001:   struct nesting *thiscond = cond_stack;
                   2002: 
                   2003:   bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscond->exit_label));
                   2004: }
                   2005: 
                   2006: /* Generate code for the start of the else- clause of
                   2007:    an if-then-else.  */
1.1.1.7 ! root     2008: 
        !          2009: static void
1.1.1.6   root     2010: bc_expand_start_else ()
                   2011: {
                   2012:   struct nesting *thiscond = cond_stack;
                   2013: 
                   2014:   thiscond->data.cond.endif_label = thiscond->exit_label;
                   2015:   thiscond->exit_label = gen_label_rtx ();
                   2016:   bc_emit_bytecode (jump);
                   2017:   bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscond->exit_label));
                   2018: 
                   2019: #ifdef DEBUG_PRINT_CODE
                   2020:   fputc ('\n', stderr);
                   2021: #endif
                   2022: 
                   2023:   bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscond->data.cond.endif_label));
                   2024: }
1.1       root     2025: 
                   2026: /* Generate RTL for the start of a loop.  EXIT_FLAG is nonzero if this
                   2027:    loop should be exited by `exit_something'.  This is a loop for which
                   2028:    `expand_continue' will jump to the top of the loop.
                   2029: 
                   2030:    Make an entry on loop_stack to record the labels associated with
                   2031:    this loop.  */
                   2032: 
                   2033: struct nesting *
                   2034: expand_start_loop (exit_flag)
                   2035:      int exit_flag;
                   2036: {
                   2037:   register struct nesting *thisloop = ALLOC_NESTING ();
                   2038: 
                   2039:   /* Make an entry on loop_stack for the loop we are entering.  */
                   2040: 
                   2041:   thisloop->next = loop_stack;
                   2042:   thisloop->all = nesting_stack;
                   2043:   thisloop->depth = ++nesting_depth;
                   2044:   thisloop->data.loop.start_label = gen_label_rtx ();
                   2045:   thisloop->data.loop.end_label = gen_label_rtx ();
1.1.1.7 ! root     2046:   thisloop->data.loop.alt_end_label = 0;
1.1       root     2047:   thisloop->data.loop.continue_label = thisloop->data.loop.start_label;
                   2048:   thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0;
                   2049:   loop_stack = thisloop;
                   2050:   nesting_stack = thisloop;
                   2051: 
1.1.1.6   root     2052:   if (output_bytecode)
                   2053:     {
                   2054:       bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisloop->data.loop.start_label));
                   2055:       return thisloop;
                   2056:     }
                   2057: 
1.1       root     2058:   do_pending_stack_adjust ();
                   2059:   emit_queue ();
1.1.1.4   root     2060:   emit_note (NULL_PTR, NOTE_INSN_LOOP_BEG);
1.1       root     2061:   emit_label (thisloop->data.loop.start_label);
                   2062: 
                   2063:   return thisloop;
                   2064: }
                   2065: 
                   2066: /* Like expand_start_loop but for a loop where the continuation point
                   2067:    (for expand_continue_loop) will be specified explicitly.  */
                   2068: 
                   2069: struct nesting *
                   2070: expand_start_loop_continue_elsewhere (exit_flag)
                   2071:      int exit_flag;
                   2072: {
                   2073:   struct nesting *thisloop = expand_start_loop (exit_flag);
                   2074:   loop_stack->data.loop.continue_label = gen_label_rtx ();
                   2075:   return thisloop;
                   2076: }
                   2077: 
                   2078: /* Specify the continuation point for a loop started with
                   2079:    expand_start_loop_continue_elsewhere.
                   2080:    Use this at the point in the code to which a continue statement
                   2081:    should jump.  */
                   2082: 
                   2083: void
                   2084: expand_loop_continue_here ()
                   2085: {
1.1.1.6   root     2086:   if (output_bytecode)
                   2087:     {
                   2088:       bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (loop_stack->data.loop.continue_label));
                   2089:       return;
                   2090:     }
1.1       root     2091:   do_pending_stack_adjust ();
1.1.1.4   root     2092:   emit_note (NULL_PTR, NOTE_INSN_LOOP_CONT);
1.1       root     2093:   emit_label (loop_stack->data.loop.continue_label);
                   2094: }
                   2095: 
1.1.1.6   root     2096: /* End a loop.  */
1.1.1.7 ! root     2097: 
1.1.1.6   root     2098: static void
                   2099: bc_expand_end_loop ()
                   2100: {
                   2101:   struct nesting *thisloop = loop_stack;
                   2102: 
                   2103:   bc_emit_bytecode (jump);
                   2104:   bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thisloop->data.loop.start_label));
                   2105: 
                   2106: #ifdef DEBUG_PRINT_CODE
                   2107:   fputc ('\n', stderr);
                   2108: #endif
                   2109: 
                   2110:   bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisloop->exit_label));
                   2111:   POPSTACK (loop_stack);
                   2112:   last_expr_type = 0;
                   2113: }
                   2114: 
                   2115: 
1.1       root     2116: /* Finish a loop.  Generate a jump back to the top and the loop-exit label.
                   2117:    Pop the block off of loop_stack.  */
                   2118: 
                   2119: void
                   2120: expand_end_loop ()
                   2121: {
1.1.1.6   root     2122:   register rtx insn;
                   2123:   register rtx start_label;
1.1       root     2124:   rtx last_test_insn = 0;
                   2125:   int num_insns = 0;
1.1.1.6   root     2126:     
                   2127:   if (output_bytecode)
                   2128:     {
                   2129:       bc_expand_end_loop ();
                   2130:       return;
                   2131:     }
                   2132: 
                   2133:   insn = get_last_insn ();
                   2134:   start_label = loop_stack->data.loop.start_label;
1.1       root     2135: 
                   2136:   /* Mark the continue-point at the top of the loop if none elsewhere.  */
                   2137:   if (start_label == loop_stack->data.loop.continue_label)
                   2138:     emit_note_before (NOTE_INSN_LOOP_CONT, start_label);
                   2139: 
                   2140:   do_pending_stack_adjust ();
                   2141: 
                   2142:   /* If optimizing, perhaps reorder the loop.  If the loop
                   2143:      starts with a conditional exit, roll that to the end
                   2144:      where it will optimize together with the jump back.
                   2145: 
                   2146:      We look for the last conditional branch to the exit that we encounter
                   2147:      before hitting 30 insns or a CALL_INSN.  If we see an unconditional
                   2148:      branch to the exit first, use it.
                   2149: 
                   2150:      We must also stop at NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes
                   2151:      because moving them is not valid.  */
                   2152: 
                   2153:   if (optimize
                   2154:       &&
                   2155:       ! (GET_CODE (insn) == JUMP_INSN
                   2156:         && GET_CODE (PATTERN (insn)) == SET
                   2157:         && SET_DEST (PATTERN (insn)) == pc_rtx
                   2158:         && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE))
                   2159:     {
                   2160:       /* Scan insns from the top of the loop looking for a qualified
                   2161:         conditional exit.  */
                   2162:       for (insn = NEXT_INSN (loop_stack->data.loop.start_label); insn;
                   2163:           insn = NEXT_INSN (insn))
                   2164:        {
                   2165:          if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CODE_LABEL)
                   2166:            break;
                   2167: 
                   2168:          if (GET_CODE (insn) == NOTE
                   2169:              && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
                   2170:                  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
                   2171:            break;
                   2172: 
                   2173:          if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == INSN)
                   2174:            num_insns++;
                   2175: 
                   2176:          if (last_test_insn && num_insns > 30)
                   2177:            break;
                   2178: 
                   2179:          if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET
                   2180:              && SET_DEST (PATTERN (insn)) == pc_rtx
                   2181:              && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE
                   2182:              && ((GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == LABEL_REF
1.1.1.7 ! root     2183:                   && ((XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)
        !          2184:                        == loop_stack->data.loop.end_label)
        !          2185:                       || (XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)
        !          2186:                           == loop_stack->data.loop.alt_end_label)))
1.1       root     2187:                  || (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF
1.1.1.7 ! root     2188:                      && ((XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)
        !          2189:                           == loop_stack->data.loop.end_label)
        !          2190:                          || (XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)
        !          2191:                              == loop_stack->data.loop.alt_end_label)))))
1.1       root     2192:            last_test_insn = insn;
                   2193: 
                   2194:          if (last_test_insn == 0 && GET_CODE (insn) == JUMP_INSN
                   2195:              && GET_CODE (PATTERN (insn)) == SET
                   2196:              && SET_DEST (PATTERN (insn)) == pc_rtx
                   2197:              && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF
1.1.1.7 ! root     2198:              && ((XEXP (SET_SRC (PATTERN (insn)), 0)
        !          2199:                   == loop_stack->data.loop.end_label)
        !          2200:                  || (XEXP (SET_SRC (PATTERN (insn)), 0)
        !          2201:                      == loop_stack->data.loop.alt_end_label)))
1.1       root     2202:            /* Include BARRIER.  */
                   2203:            last_test_insn = NEXT_INSN (insn);
                   2204:        }
                   2205: 
                   2206:       if (last_test_insn != 0 && last_test_insn != get_last_insn ())
                   2207:        {
                   2208:          /* We found one.  Move everything from there up
                   2209:             to the end of the loop, and add a jump into the loop
                   2210:             to jump to there.  */
                   2211:          register rtx newstart_label = gen_label_rtx ();
                   2212:          register rtx start_move = start_label;
                   2213: 
1.1.1.2   root     2214:          /* If the start label is preceded by a NOTE_INSN_LOOP_CONT note,
1.1       root     2215:             then we want to move this note also.  */
                   2216:          if (GET_CODE (PREV_INSN (start_move)) == NOTE
                   2217:              && (NOTE_LINE_NUMBER (PREV_INSN (start_move))
                   2218:                  == NOTE_INSN_LOOP_CONT))
                   2219:            start_move = PREV_INSN (start_move);
                   2220: 
                   2221:          emit_label_after (newstart_label, PREV_INSN (start_move));
                   2222:          reorder_insns (start_move, last_test_insn, get_last_insn ());
                   2223:          emit_jump_insn_after (gen_jump (start_label),
                   2224:                                PREV_INSN (newstart_label));
                   2225:          emit_barrier_after (PREV_INSN (newstart_label));
                   2226:          start_label = newstart_label;
                   2227:        }
                   2228:     }
                   2229: 
                   2230:   emit_jump (start_label);
1.1.1.4   root     2231:   emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
1.1       root     2232:   emit_label (loop_stack->data.loop.end_label);
                   2233: 
                   2234:   POPSTACK (loop_stack);
                   2235: 
                   2236:   last_expr_type = 0;
                   2237: }
                   2238: 
                   2239: /* Generate a jump to the current loop's continue-point.
                   2240:    This is usually the top of the loop, but may be specified
                   2241:    explicitly elsewhere.  If not currently inside a loop,
                   2242:    return 0 and do nothing; caller will print an error message.  */
                   2243: 
                   2244: int
                   2245: expand_continue_loop (whichloop)
                   2246:      struct nesting *whichloop;
                   2247: {
                   2248:   last_expr_type = 0;
                   2249:   if (whichloop == 0)
                   2250:     whichloop = loop_stack;
                   2251:   if (whichloop == 0)
                   2252:     return 0;
1.1.1.4   root     2253:   expand_goto_internal (NULL_TREE, whichloop->data.loop.continue_label,
                   2254:                        NULL_RTX);
1.1       root     2255:   return 1;
                   2256: }
                   2257: 
                   2258: /* Generate a jump to exit the current loop.  If not currently inside a loop,
                   2259:    return 0 and do nothing; caller will print an error message.  */
                   2260: 
                   2261: int
                   2262: expand_exit_loop (whichloop)
                   2263:      struct nesting *whichloop;
                   2264: {
                   2265:   last_expr_type = 0;
                   2266:   if (whichloop == 0)
                   2267:     whichloop = loop_stack;
                   2268:   if (whichloop == 0)
                   2269:     return 0;
1.1.1.4   root     2270:   expand_goto_internal (NULL_TREE, whichloop->data.loop.end_label, NULL_RTX);
1.1       root     2271:   return 1;
                   2272: }
                   2273: 
                   2274: /* Generate a conditional jump to exit the current loop if COND
                   2275:    evaluates to zero.  If not currently inside a loop,
                   2276:    return 0 and do nothing; caller will print an error message.  */
                   2277: 
                   2278: int
                   2279: expand_exit_loop_if_false (whichloop, cond)
                   2280:      struct nesting *whichloop;
                   2281:      tree cond;
                   2282: {
                   2283:   last_expr_type = 0;
                   2284:   if (whichloop == 0)
                   2285:     whichloop = loop_stack;
                   2286:   if (whichloop == 0)
                   2287:     return 0;
1.1.1.6   root     2288:   if (output_bytecode)
                   2289:     {
                   2290:       bc_expand_expr (cond);
                   2291:       bc_expand_goto_internal (xjumpifnot,
                   2292:                               BYTECODE_BC_LABEL (whichloop->exit_label),
1.1.1.7 ! root     2293:                               NULL_TREE);
1.1.1.6   root     2294:     }
                   2295:   else
1.1.1.7 ! root     2296:     {
        !          2297:       /* In order to handle fixups, we actually create a conditional jump
        !          2298:         around a unconditional branch to exit the loop.  If fixups are
        !          2299:         necessary, they go before the unconditional branch.  */
        !          2300: 
        !          2301:       rtx label = gen_label_rtx ();
        !          2302:       rtx last_insn;
        !          2303: 
        !          2304:       do_jump (cond, NULL_RTX, label);
        !          2305:       last_insn = get_last_insn ();
        !          2306:       if (GET_CODE (last_insn) == CODE_LABEL)
        !          2307:        whichloop->data.loop.alt_end_label = last_insn;
        !          2308:       expand_goto_internal (NULL_TREE, whichloop->data.loop.end_label,
        !          2309:                            NULL_RTX);
        !          2310:       emit_label (label);
        !          2311:     }
1.1.1.6   root     2312: 
1.1       root     2313:   return 1;
                   2314: }
                   2315: 
                   2316: /* Return non-zero if we should preserve sub-expressions as separate
                   2317:    pseudos.  We never do so if we aren't optimizing.  We always do so
                   2318:    if -fexpensive-optimizations.
                   2319: 
                   2320:    Otherwise, we only do so if we are in the "early" part of a loop.  I.e.,
                   2321:    the loop may still be a small one.  */
                   2322: 
                   2323: int
                   2324: preserve_subexpressions_p ()
                   2325: {
                   2326:   rtx insn;
                   2327: 
                   2328:   if (flag_expensive_optimizations)
                   2329:     return 1;
                   2330: 
                   2331:   if (optimize == 0 || loop_stack == 0)
                   2332:     return 0;
                   2333: 
                   2334:   insn = get_last_insn_anywhere ();
                   2335: 
                   2336:   return (insn
                   2337:          && (INSN_UID (insn) - INSN_UID (loop_stack->data.loop.start_label)
                   2338:              < n_non_fixed_regs * 3));
                   2339: 
                   2340: }
                   2341: 
                   2342: /* Generate a jump to exit the current loop, conditional, binding contour
                   2343:    or case statement.  Not all such constructs are visible to this function,
                   2344:    only those started with EXIT_FLAG nonzero.  Individual languages use
                   2345:    the EXIT_FLAG parameter to control which kinds of constructs you can
                   2346:    exit this way.
                   2347: 
                   2348:    If not currently inside anything that can be exited,
                   2349:    return 0 and do nothing; caller will print an error message.  */
                   2350: 
                   2351: int
                   2352: expand_exit_something ()
                   2353: {
                   2354:   struct nesting *n;
                   2355:   last_expr_type = 0;
                   2356:   for (n = nesting_stack; n; n = n->all)
                   2357:     if (n->exit_label != 0)
                   2358:       {
1.1.1.4   root     2359:        expand_goto_internal (NULL_TREE, n->exit_label, NULL_RTX);
1.1       root     2360:        return 1;
                   2361:       }
                   2362: 
                   2363:   return 0;
                   2364: }
                   2365: 
                   2366: /* Generate RTL to return from the current function, with no value.
                   2367:    (That is, we do not do anything about returning any value.)  */
                   2368: 
                   2369: void
                   2370: expand_null_return ()
                   2371: {
                   2372:   struct nesting *block = block_stack;
                   2373:   rtx last_insn = 0;
                   2374: 
1.1.1.6   root     2375:   if (output_bytecode)
                   2376:     {
                   2377:       bc_emit_instruction (ret);
                   2378:       return;
                   2379:     }
                   2380: 
1.1       root     2381:   /* Does any pending block have cleanups?  */
                   2382: 
                   2383:   while (block && block->data.block.cleanups == 0)
                   2384:     block = block->next;
                   2385: 
                   2386:   /* If yes, use a goto to return, since that runs cleanups.  */
                   2387: 
                   2388:   expand_null_return_1 (last_insn, block != 0);
                   2389: }
                   2390: 
                   2391: /* Generate RTL to return from the current function, with value VAL.  */
                   2392: 
                   2393: void
                   2394: expand_value_return (val)
                   2395:      rtx val;
                   2396: {
                   2397:   struct nesting *block = block_stack;
                   2398:   rtx last_insn = get_last_insn ();
                   2399:   rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl));
                   2400: 
                   2401:   /* Copy the value to the return location
                   2402:      unless it's already there.  */
                   2403: 
                   2404:   if (return_reg != val)
1.1.1.4   root     2405:     {
                   2406: #ifdef PROMOTE_FUNCTION_RETURN
                   2407:       tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
                   2408:       int unsignedp = TREE_UNSIGNED (type);
1.1.1.7 ! root     2409:       enum machine_mode mode
        !          2410:        = promote_mode (type, DECL_MODE (DECL_RESULT (current_function_decl)),
        !          2411:                        &unsignedp, 1);
1.1.1.4   root     2412: 
                   2413:       if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
1.1.1.5   root     2414:        convert_move (return_reg, val, unsignedp);
1.1.1.4   root     2415:       else
                   2416: #endif
                   2417:        emit_move_insn (return_reg, val);
                   2418:     }
1.1       root     2419:   if (GET_CODE (return_reg) == REG
                   2420:       && REGNO (return_reg) < FIRST_PSEUDO_REGISTER)
                   2421:     emit_insn (gen_rtx (USE, VOIDmode, return_reg));
                   2422: 
                   2423:   /* Does any pending block have cleanups?  */
                   2424: 
                   2425:   while (block && block->data.block.cleanups == 0)
                   2426:     block = block->next;
                   2427: 
                   2428:   /* If yes, use a goto to return, since that runs cleanups.
                   2429:      Use LAST_INSN to put cleanups *before* the move insn emitted above.  */
                   2430: 
                   2431:   expand_null_return_1 (last_insn, block != 0);
                   2432: }
                   2433: 
                   2434: /* Output a return with no value.  If LAST_INSN is nonzero,
                   2435:    pretend that the return takes place after LAST_INSN.
                   2436:    If USE_GOTO is nonzero then don't use a return instruction;
                   2437:    go to the return label instead.  This causes any cleanups
                   2438:    of pending blocks to be executed normally.  */
                   2439: 
                   2440: static void
                   2441: expand_null_return_1 (last_insn, use_goto)
                   2442:      rtx last_insn;
                   2443:      int use_goto;
                   2444: {
                   2445:   rtx end_label = cleanup_label ? cleanup_label : return_label;
                   2446: 
                   2447:   clear_pending_stack_adjust ();
                   2448:   do_pending_stack_adjust ();
                   2449:   last_expr_type = 0;
                   2450: 
                   2451:   /* PCC-struct return always uses an epilogue.  */
                   2452:   if (current_function_returns_pcc_struct || use_goto)
                   2453:     {
                   2454:       if (end_label == 0)
                   2455:        end_label = return_label = gen_label_rtx ();
1.1.1.4   root     2456:       expand_goto_internal (NULL_TREE, end_label, last_insn);
1.1       root     2457:       return;
                   2458:     }
                   2459: 
                   2460:   /* Otherwise output a simple return-insn if one is available,
                   2461:      unless it won't do the job.  */
                   2462: #ifdef HAVE_return
                   2463:   if (HAVE_return && use_goto == 0 && cleanup_label == 0)
                   2464:     {
                   2465:       emit_jump_insn (gen_return ());
                   2466:       emit_barrier ();
                   2467:       return;
                   2468:     }
                   2469: #endif
                   2470: 
                   2471:   /* Otherwise jump to the epilogue.  */
1.1.1.4   root     2472:   expand_goto_internal (NULL_TREE, end_label, last_insn);
1.1       root     2473: }
                   2474: 
                   2475: /* Generate RTL to evaluate the expression RETVAL and return it
                   2476:    from the current function.  */
                   2477: 
                   2478: void
                   2479: expand_return (retval)
                   2480:      tree retval;
                   2481: {
                   2482:   /* If there are any cleanups to be performed, then they will
                   2483:      be inserted following LAST_INSN.  It is desirable
                   2484:      that the last_insn, for such purposes, should be the
                   2485:      last insn before computing the return value.  Otherwise, cleanups
                   2486:      which call functions can clobber the return value.  */
                   2487:   /* ??? rms: I think that is erroneous, because in C++ it would
                   2488:      run destructors on variables that might be used in the subsequent
                   2489:      computation of the return value.  */
                   2490:   rtx last_insn = 0;
                   2491:   register rtx val = 0;
                   2492:   register rtx op0;
                   2493:   tree retval_rhs;
                   2494:   int cleanups;
                   2495:   struct nesting *block;
                   2496: 
1.1.1.6   root     2497:   /* Bytecode returns are quite simple, just leave the result on the
                   2498:      arithmetic stack. */
                   2499:   if (output_bytecode)
                   2500:     {
                   2501:       bc_expand_expr (retval);
                   2502:       bc_emit_instruction (ret);
                   2503:       return;
                   2504:     }
                   2505:   
1.1       root     2506:   /* If function wants no value, give it none.  */
                   2507:   if (TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl))) == VOID_TYPE)
                   2508:     {
1.1.1.4   root     2509:       expand_expr (retval, NULL_RTX, VOIDmode, 0);
                   2510:       emit_queue ();
1.1       root     2511:       expand_null_return ();
                   2512:       return;
                   2513:     }
                   2514: 
                   2515:   /* Are any cleanups needed?  E.g. C++ destructors to be run?  */
1.1.1.7 ! root     2516:   /* This is not sufficient.  We also need to watch for cleanups of the
        !          2517:      expression we are about to expand.  Unfortunately, we cannot know
        !          2518:      if it has cleanups until we expand it, and we want to change how we
        !          2519:      expand it depending upon if we need cleanups.  We can't win.  */
        !          2520: #if 0
1.1       root     2521:   cleanups = any_pending_cleanups (1);
1.1.1.7 ! root     2522: #else
        !          2523:   cleanups = 1;
        !          2524: #endif
1.1       root     2525: 
                   2526:   if (TREE_CODE (retval) == RESULT_DECL)
                   2527:     retval_rhs = retval;
                   2528:   else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR)
                   2529:           && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
                   2530:     retval_rhs = TREE_OPERAND (retval, 1);
                   2531:   else if (TREE_TYPE (retval) == void_type_node)
                   2532:     /* Recognize tail-recursive call to void function.  */
                   2533:     retval_rhs = retval;
                   2534:   else
                   2535:     retval_rhs = NULL_TREE;
                   2536: 
                   2537:   /* Only use `last_insn' if there are cleanups which must be run.  */
                   2538:   if (cleanups || cleanup_label != 0)
                   2539:     last_insn = get_last_insn ();
                   2540: 
                   2541:   /* Distribute return down conditional expr if either of the sides
                   2542:      may involve tail recursion (see test below).  This enhances the number
                   2543:      of tail recursions we see.  Don't do this always since it can produce
                   2544:      sub-optimal code in some cases and we distribute assignments into
                   2545:      conditional expressions when it would help.  */
                   2546: 
                   2547:   if (optimize && retval_rhs != 0
                   2548:       && frame_offset == 0
                   2549:       && TREE_CODE (retval_rhs) == COND_EXPR
                   2550:       && (TREE_CODE (TREE_OPERAND (retval_rhs, 1)) == CALL_EXPR
                   2551:          || TREE_CODE (TREE_OPERAND (retval_rhs, 2)) == CALL_EXPR))
                   2552:     {
                   2553:       rtx label = gen_label_rtx ();
1.1.1.6   root     2554:       tree expr;
                   2555: 
1.1.1.4   root     2556:       do_jump (TREE_OPERAND (retval_rhs, 0), label, NULL_RTX);
1.1.1.6   root     2557:       expr = build (MODIFY_EXPR, TREE_TYPE (current_function_decl),
                   2558:                    DECL_RESULT (current_function_decl),
                   2559:                    TREE_OPERAND (retval_rhs, 1));
                   2560:       TREE_SIDE_EFFECTS (expr) = 1;
                   2561:       expand_return (expr);
1.1       root     2562:       emit_label (label);
1.1.1.6   root     2563: 
                   2564:       expr = build (MODIFY_EXPR, TREE_TYPE (current_function_decl),
                   2565:                    DECL_RESULT (current_function_decl),
                   2566:                    TREE_OPERAND (retval_rhs, 2));
                   2567:       TREE_SIDE_EFFECTS (expr) = 1;
                   2568:       expand_return (expr);
1.1       root     2569:       return;
                   2570:     }
                   2571: 
                   2572:   /* For tail-recursive call to current function,
                   2573:      just jump back to the beginning.
                   2574:      It's unsafe if any auto variable in this function
                   2575:      has its address taken; for simplicity,
                   2576:      require stack frame to be empty.  */
                   2577:   if (optimize && retval_rhs != 0
                   2578:       && frame_offset == 0
                   2579:       && TREE_CODE (retval_rhs) == CALL_EXPR
                   2580:       && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
                   2581:       && TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0) == current_function_decl
                   2582:       /* Finish checking validity, and if valid emit code
                   2583:         to set the argument variables for the new call.  */
                   2584:       && tail_recursion_args (TREE_OPERAND (retval_rhs, 1),
                   2585:                              DECL_ARGUMENTS (current_function_decl)))
                   2586:     {
                   2587:       if (tail_recursion_label == 0)
                   2588:        {
                   2589:          tail_recursion_label = gen_label_rtx ();
                   2590:          emit_label_after (tail_recursion_label,
                   2591:                            tail_recursion_reentry);
                   2592:        }
1.1.1.4   root     2593:       emit_queue ();
                   2594:       expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn);
1.1       root     2595:       emit_barrier ();
                   2596:       return;
                   2597:     }
                   2598: #ifdef HAVE_return
                   2599:   /* This optimization is safe if there are local cleanups
                   2600:      because expand_null_return takes care of them.
                   2601:      ??? I think it should also be safe when there is a cleanup label,
                   2602:      because expand_null_return takes care of them, too.
                   2603:      Any reason why not?  */
                   2604:   if (HAVE_return && cleanup_label == 0
1.1.1.6   root     2605:       && ! current_function_returns_pcc_struct
                   2606:       && BRANCH_COST <= 1)
1.1       root     2607:     {
                   2608:       /* If this is  return x == y;  then generate
                   2609:         if (x == y) return 1; else return 0;
1.1.1.6   root     2610:         if we can do it with explicit return insns and
                   2611:         branches are cheap.  */
1.1       root     2612:       if (retval_rhs)
                   2613:        switch (TREE_CODE (retval_rhs))
                   2614:          {
                   2615:          case EQ_EXPR:
                   2616:          case NE_EXPR:
                   2617:          case GT_EXPR:
                   2618:          case GE_EXPR:
                   2619:          case LT_EXPR:
                   2620:          case LE_EXPR:
                   2621:          case TRUTH_ANDIF_EXPR:
                   2622:          case TRUTH_ORIF_EXPR:
                   2623:          case TRUTH_AND_EXPR:
                   2624:          case TRUTH_OR_EXPR:
                   2625:          case TRUTH_NOT_EXPR:
1.1.1.5   root     2626:          case TRUTH_XOR_EXPR:
1.1       root     2627:            op0 = gen_label_rtx ();
                   2628:            jumpifnot (retval_rhs, op0);
                   2629:            expand_value_return (const1_rtx);
                   2630:            emit_label (op0);
                   2631:            expand_value_return (const0_rtx);
                   2632:            return;
                   2633:          }
                   2634:     }
                   2635: #endif /* HAVE_return */
                   2636: 
                   2637:   if (cleanups
                   2638:       && retval_rhs != 0
                   2639:       && TREE_TYPE (retval_rhs) != void_type_node
                   2640:       && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG)
                   2641:     {
                   2642:       /* Calculate the return value into a pseudo reg.  */
1.1.1.4   root     2643:       val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
1.1       root     2644:       emit_queue ();
                   2645:       /* All temporaries have now been used.  */
                   2646:       free_temp_slots ();
                   2647:       /* Return the calculated value, doing cleanups first.  */
                   2648:       expand_value_return (val);
                   2649:     }
                   2650:   else
                   2651:     {
                   2652:       /* No cleanups or no hard reg used;
                   2653:         calculate value into hard return reg.  */
1.1.1.6   root     2654:       expand_expr (retval, const0_rtx, VOIDmode, 0);
1.1       root     2655:       emit_queue ();
                   2656:       free_temp_slots ();
                   2657:       expand_value_return (DECL_RTL (DECL_RESULT (current_function_decl)));
                   2658:     }
                   2659: }
                   2660: 
                   2661: /* Return 1 if the end of the generated RTX is not a barrier.
                   2662:    This means code already compiled can drop through.  */
                   2663: 
                   2664: int
                   2665: drop_through_at_end_p ()
                   2666: {
                   2667:   rtx insn = get_last_insn ();
                   2668:   while (insn && GET_CODE (insn) == NOTE)
                   2669:     insn = PREV_INSN (insn);
                   2670:   return insn && GET_CODE (insn) != BARRIER;
                   2671: }
                   2672: 
                   2673: /* Emit code to alter this function's formal parms for a tail-recursive call.
                   2674:    ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
                   2675:    FORMALS is the chain of decls of formals.
                   2676:    Return 1 if this can be done;
                   2677:    otherwise return 0 and do not emit any code.  */
                   2678: 
                   2679: static int
                   2680: tail_recursion_args (actuals, formals)
                   2681:      tree actuals, formals;
                   2682: {
                   2683:   register tree a = actuals, f = formals;
                   2684:   register int i;
                   2685:   register rtx *argvec;
                   2686: 
                   2687:   /* Check that number and types of actuals are compatible
                   2688:      with the formals.  This is not always true in valid C code.
                   2689:      Also check that no formal needs to be addressable
                   2690:      and that all formals are scalars.  */
                   2691: 
                   2692:   /* Also count the args.  */
                   2693: 
                   2694:   for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++)
                   2695:     {
                   2696:       if (TREE_TYPE (TREE_VALUE (a)) != TREE_TYPE (f))
                   2697:        return 0;
                   2698:       if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode)
                   2699:        return 0;
                   2700:     }
                   2701:   if (a != 0 || f != 0)
                   2702:     return 0;
                   2703: 
                   2704:   /* Compute all the actuals.  */
                   2705: 
                   2706:   argvec = (rtx *) alloca (i * sizeof (rtx));
                   2707: 
                   2708:   for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
1.1.1.4   root     2709:     argvec[i] = expand_expr (TREE_VALUE (a), NULL_RTX, VOIDmode, 0);
1.1       root     2710: 
                   2711:   /* Find which actual values refer to current values of previous formals.
                   2712:      Copy each of them now, before any formal is changed.  */
                   2713: 
                   2714:   for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
                   2715:     {
                   2716:       int copy = 0;
                   2717:       register int j;
                   2718:       for (f = formals, j = 0; j < i; f = TREE_CHAIN (f), j++)
                   2719:        if (reg_mentioned_p (DECL_RTL (f), argvec[i]))
                   2720:          { copy = 1; break; }
                   2721:       if (copy)
                   2722:        argvec[i] = copy_to_reg (argvec[i]);
                   2723:     }
                   2724: 
                   2725:   /* Store the values of the actuals into the formals.  */
                   2726: 
                   2727:   for (f = formals, a = actuals, i = 0; f;
                   2728:        f = TREE_CHAIN (f), a = TREE_CHAIN (a), i++)
                   2729:     {
1.1.1.4   root     2730:       if (GET_MODE (DECL_RTL (f)) == GET_MODE (argvec[i]))
1.1       root     2731:        emit_move_insn (DECL_RTL (f), argvec[i]);
                   2732:       else
                   2733:        convert_move (DECL_RTL (f), argvec[i],
                   2734:                      TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))));
                   2735:     }
                   2736: 
                   2737:   free_temp_slots ();
                   2738:   return 1;
                   2739: }
                   2740: 
                   2741: /* Generate the RTL code for entering a binding contour.
                   2742:    The variables are declared one by one, by calls to `expand_decl'.
                   2743: 
                   2744:    EXIT_FLAG is nonzero if this construct should be visible to
                   2745:    `exit_something'.  */
                   2746: 
                   2747: void
                   2748: expand_start_bindings (exit_flag)
                   2749:      int exit_flag;
                   2750: {
                   2751:   struct nesting *thisblock = ALLOC_NESTING ();
1.1.1.7 ! root     2752:   rtx note = output_bytecode ? 0 : emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
1.1       root     2753: 
                   2754:   /* Make an entry on block_stack for the block we are entering.  */
                   2755: 
                   2756:   thisblock->next = block_stack;
                   2757:   thisblock->all = nesting_stack;
                   2758:   thisblock->depth = ++nesting_depth;
                   2759:   thisblock->data.block.stack_level = 0;
                   2760:   thisblock->data.block.cleanups = 0;
                   2761:   thisblock->data.block.function_call_count = 0;
                   2762: #if 0
                   2763:   if (block_stack)
                   2764:     {
                   2765:       if (block_stack->data.block.cleanups == NULL_TREE
                   2766:          && (block_stack->data.block.outer_cleanups == NULL_TREE
                   2767:              || block_stack->data.block.outer_cleanups == empty_cleanup_list))
                   2768:        thisblock->data.block.outer_cleanups = empty_cleanup_list;
                   2769:       else
                   2770:        thisblock->data.block.outer_cleanups
                   2771:          = tree_cons (NULL_TREE, block_stack->data.block.cleanups,
                   2772:                       block_stack->data.block.outer_cleanups);
                   2773:     }
                   2774:   else
                   2775:     thisblock->data.block.outer_cleanups = 0;
                   2776: #endif
                   2777: #if 1
                   2778:   if (block_stack
                   2779:       && !(block_stack->data.block.cleanups == NULL_TREE
                   2780:           && block_stack->data.block.outer_cleanups == NULL_TREE))
                   2781:     thisblock->data.block.outer_cleanups
                   2782:       = tree_cons (NULL_TREE, block_stack->data.block.cleanups,
                   2783:                   block_stack->data.block.outer_cleanups);
                   2784:   else
                   2785:     thisblock->data.block.outer_cleanups = 0;
                   2786: #endif
                   2787:   thisblock->data.block.label_chain = 0;
                   2788:   thisblock->data.block.innermost_stack_block = stack_block_stack;
                   2789:   thisblock->data.block.first_insn = note;
                   2790:   thisblock->data.block.block_start_count = ++block_start_count;
                   2791:   thisblock->exit_label = exit_flag ? gen_label_rtx () : 0;
                   2792:   block_stack = thisblock;
                   2793:   nesting_stack = thisblock;
                   2794: 
1.1.1.6   root     2795:   if (!output_bytecode)
                   2796:     {
                   2797:       /* Make a new level for allocating stack slots.  */
                   2798:       push_temp_slots ();
                   2799:     }
1.1       root     2800: }
                   2801: 
1.1.1.4   root     2802: /* Given a pointer to a BLOCK node, save a pointer to the most recently
                   2803:    generated NOTE_INSN_BLOCK_END in the BLOCK_END_NOTE field of the given
                   2804:    BLOCK node.  */
                   2805: 
                   2806: void
                   2807: remember_end_note (block)
                   2808:      register tree block;
                   2809: {
                   2810:   BLOCK_END_NOTE (block) = last_block_end_note;
                   2811:   last_block_end_note = NULL_RTX;
                   2812: }
                   2813: 
1.1       root     2814: /* Generate RTL code to terminate a binding contour.
                   2815:    VARS is the chain of VAR_DECL nodes
                   2816:    for the variables bound in this contour.
                   2817:    MARK_ENDS is nonzero if we should put a note at the beginning
                   2818:    and end of this binding contour.
                   2819: 
                   2820:    DONT_JUMP_IN is nonzero if it is not valid to jump into this contour.
                   2821:    (That is true automatically if the contour has a saved stack level.)  */
                   2822: 
                   2823: void
                   2824: expand_end_bindings (vars, mark_ends, dont_jump_in)
                   2825:      tree vars;
                   2826:      int mark_ends;
                   2827:      int dont_jump_in;
                   2828: {
                   2829:   register struct nesting *thisblock = block_stack;
                   2830:   register tree decl;
                   2831: 
1.1.1.6   root     2832:   if (output_bytecode)
                   2833:     {
                   2834:       bc_expand_end_bindings (vars, mark_ends, dont_jump_in);
                   2835:       return;
                   2836:     }
                   2837: 
1.1       root     2838:   if (warn_unused)
                   2839:     for (decl = vars; decl; decl = TREE_CHAIN (decl))
1.1.1.4   root     2840:       if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL
                   2841:          && ! DECL_IN_SYSTEM_HEADER (decl))
1.1       root     2842:        warning_with_decl (decl, "unused variable `%s'");
                   2843: 
                   2844:   if (thisblock->exit_label)
                   2845:     {
                   2846:       do_pending_stack_adjust ();
                   2847:       emit_label (thisblock->exit_label);
                   2848:     }
                   2849: 
                   2850:   /* If necessary, make a handler for nonlocal gotos taking
                   2851:      place in the function calls in this block.  */
                   2852:   if (function_call_count != thisblock->data.block.function_call_count
                   2853:       && nonlocal_labels
                   2854:       /* Make handler for outermost block
                   2855:         if there were any nonlocal gotos to this function.  */
                   2856:       && (thisblock->next == 0 ? current_function_has_nonlocal_label
                   2857:          /* Make handler for inner block if it has something
                   2858:             special to do when you jump out of it.  */
                   2859:          : (thisblock->data.block.cleanups != 0
                   2860:             || thisblock->data.block.stack_level != 0)))
                   2861:     {
                   2862:       tree link;
                   2863:       rtx afterward = gen_label_rtx ();
                   2864:       rtx handler_label = gen_label_rtx ();
                   2865:       rtx save_receiver = gen_reg_rtx (Pmode);
1.1.1.6   root     2866:       rtx insns;
1.1       root     2867: 
                   2868:       /* Don't let jump_optimize delete the handler.  */
                   2869:       LABEL_PRESERVE_P (handler_label) = 1;
                   2870: 
                   2871:       /* Record the handler address in the stack slot for that purpose,
                   2872:         during this block, saving and restoring the outer value.  */
                   2873:       if (thisblock->next != 0)
                   2874:        {
                   2875:          emit_move_insn (nonlocal_goto_handler_slot, save_receiver);
1.1.1.6   root     2876: 
                   2877:          start_sequence ();
                   2878:          emit_move_insn (save_receiver, nonlocal_goto_handler_slot);
                   2879:          insns = get_insns ();
                   2880:          end_sequence ();
                   2881:          emit_insns_before (insns, thisblock->data.block.first_insn);
                   2882:        }
                   2883: 
                   2884:       start_sequence ();
                   2885:       emit_move_insn (nonlocal_goto_handler_slot,
                   2886:                      gen_rtx (LABEL_REF, Pmode, handler_label));
                   2887:       insns = get_insns ();
                   2888:       end_sequence ();
                   2889:       emit_insns_before (insns, thisblock->data.block.first_insn);
1.1       root     2890: 
                   2891:       /* Jump around the handler; it runs only when specially invoked.  */
                   2892:       emit_jump (afterward);
                   2893:       emit_label (handler_label);
                   2894: 
                   2895: #ifdef HAVE_nonlocal_goto
                   2896:       if (! HAVE_nonlocal_goto)
                   2897: #endif
                   2898:        /* First adjust our frame pointer to its actual value.  It was
                   2899:           previously set to the start of the virtual area corresponding to
                   2900:           the stacked variables when we branched here and now needs to be
                   2901:           adjusted to the actual hardware fp value.
                   2902: 
                   2903:           Assignments are to virtual registers are converted by
                   2904:           instantiate_virtual_regs into the corresponding assignment
                   2905:           to the underlying register (fp in this case) that makes
                   2906:           the original assignment true.
                   2907:           So the following insn will actually be
                   2908:           decrementing fp by STARTING_FRAME_OFFSET.  */
1.1.1.7 ! root     2909:        emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
1.1       root     2910: 
1.1.1.6   root     2911: #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
1.1       root     2912:       if (fixed_regs[ARG_POINTER_REGNUM])
                   2913:        {
1.1.1.4   root     2914: #ifdef ELIMINABLE_REGS
                   2915:          /* If the argument pointer can be eliminated in favor of the
                   2916:             frame pointer, we don't need to restore it.  We assume here
                   2917:             that if such an elimination is present, it can always be used.
                   2918:             This is the case on all known machines; if we don't make this
                   2919:             assumption, we do unnecessary saving on many machines.  */
                   2920:          static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
                   2921:          int i;
                   2922: 
                   2923:          for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
                   2924:            if (elim_regs[i].from == ARG_POINTER_REGNUM
1.1.1.6   root     2925:                && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
1.1.1.4   root     2926:              break;
                   2927: 
                   2928:          if (i == sizeof elim_regs / sizeof elim_regs [0])
                   2929: #endif
                   2930:            {
                   2931:              /* Now restore our arg pointer from the address at which it
                   2932:                 was saved in our stack frame.
                   2933:                 If there hasn't be space allocated for it yet, make
                   2934:                 some now.  */
                   2935:              if (arg_pointer_save_area == 0)
                   2936:                arg_pointer_save_area
                   2937:                  = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
                   2938:              emit_move_insn (virtual_incoming_args_rtx,
                   2939:                              /* We need a pseudo here, or else
                   2940:                                 instantiate_virtual_regs_1 complains.  */
                   2941:                              copy_to_reg (arg_pointer_save_area));
                   2942:            }
1.1       root     2943:        }
                   2944: #endif
                   2945: 
                   2946:       /* The handler expects the desired label address in the static chain
                   2947:         register.  It tests the address and does an appropriate jump
                   2948:         to whatever label is desired.  */
                   2949:       for (link = nonlocal_labels; link; link = TREE_CHAIN (link))
                   2950:        /* Skip any labels we shouldn't be able to jump to from here.  */
                   2951:        if (! DECL_TOO_LATE (TREE_VALUE (link)))
                   2952:          {
                   2953:            rtx not_this = gen_label_rtx ();
                   2954:            rtx this = gen_label_rtx ();
                   2955:            do_jump_if_equal (static_chain_rtx,
                   2956:                              gen_rtx (LABEL_REF, Pmode, DECL_RTL (TREE_VALUE (link))),
                   2957:                              this, 0);
                   2958:            emit_jump (not_this);
                   2959:            emit_label (this);
                   2960:            expand_goto (TREE_VALUE (link));
                   2961:            emit_label (not_this);
                   2962:          }
                   2963:       /* If label is not recognized, abort.  */
                   2964:       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "abort"), 0,
                   2965:                         VOIDmode, 0);
                   2966:       emit_label (afterward);
                   2967:     }
                   2968: 
                   2969:   /* Don't allow jumping into a block that has cleanups or a stack level.  */
                   2970:   if (dont_jump_in
                   2971:       || thisblock->data.block.stack_level != 0
                   2972:       || thisblock->data.block.cleanups != 0)
                   2973:     {
                   2974:       struct label_chain *chain;
                   2975: 
                   2976:       /* Any labels in this block are no longer valid to go to.
                   2977:         Mark them to cause an error message.  */
                   2978:       for (chain = thisblock->data.block.label_chain; chain; chain = chain->next)
                   2979:        {
                   2980:          DECL_TOO_LATE (chain->label) = 1;
                   2981:          /* If any goto without a fixup came to this label,
                   2982:             that must be an error, because gotos without fixups
                   2983:             come from outside all saved stack-levels and all cleanups.  */
                   2984:          if (TREE_ADDRESSABLE (chain->label))
                   2985:            error_with_decl (chain->label,
                   2986:                             "label `%s' used before containing binding contour");
                   2987:        }
                   2988:     }
                   2989: 
                   2990:   /* Restore stack level in effect before the block
                   2991:      (only if variable-size objects allocated).  */
                   2992:   /* Perform any cleanups associated with the block.  */
                   2993: 
                   2994:   if (thisblock->data.block.stack_level != 0
                   2995:       || thisblock->data.block.cleanups != 0)
                   2996:     {
1.1.1.7 ! root     2997:       /* Only clean up here if this point can actually be reached.  */
        !          2998:       if (GET_CODE (get_last_insn ()) != BARRIER)
        !          2999:        {
        !          3000:          /* Don't let cleanups affect ({...}) constructs.  */
        !          3001:          int old_expr_stmts_for_value = expr_stmts_for_value;
        !          3002:          rtx old_last_expr_value = last_expr_value;
        !          3003:          tree old_last_expr_type = last_expr_type;
        !          3004:          expr_stmts_for_value = 0;
1.1       root     3005: 
1.1.1.7 ! root     3006:          /* Do the cleanups.  */
        !          3007:          expand_cleanups (thisblock->data.block.cleanups, NULL_TREE);
        !          3008:          do_pending_stack_adjust ();
        !          3009: 
        !          3010:          expr_stmts_for_value = old_expr_stmts_for_value;
        !          3011:          last_expr_value = old_last_expr_value;
        !          3012:          last_expr_type = old_last_expr_type;
1.1       root     3013: 
1.1.1.7 ! root     3014:          /* Restore the stack level.  */
        !          3015: 
        !          3016:          if (thisblock->data.block.stack_level != 0)
        !          3017:            {
        !          3018:              emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
        !          3019:                                  thisblock->data.block.stack_level, NULL_RTX);
        !          3020:              if (nonlocal_goto_handler_slot != 0)
        !          3021:                emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level,
        !          3022:                                 NULL_RTX);
        !          3023:            }
1.1       root     3024:        }
                   3025: 
                   3026:       /* Any gotos out of this block must also do these things.
1.1.1.3   root     3027:         Also report any gotos with fixups that came to labels in this
                   3028:         level.  */
1.1       root     3029:       fixup_gotos (thisblock,
                   3030:                   thisblock->data.block.stack_level,
                   3031:                   thisblock->data.block.cleanups,
                   3032:                   thisblock->data.block.first_insn,
                   3033:                   dont_jump_in);
                   3034:     }
                   3035: 
1.1.1.4   root     3036:   /* Mark the beginning and end of the scope if requested.
                   3037:      We do this now, after running cleanups on the variables
                   3038:      just going out of scope, so they are in scope for their cleanups.  */
                   3039: 
                   3040:   if (mark_ends)
                   3041:     last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
                   3042:   else
                   3043:     /* Get rid of the beginning-mark if we don't make an end-mark.  */
                   3044:     NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;
                   3045: 
1.1       root     3046:   /* If doing stupid register allocation, make sure lives of all
                   3047:      register variables declared here extend thru end of scope.  */
                   3048: 
                   3049:   if (obey_regdecls)
                   3050:     for (decl = vars; decl; decl = TREE_CHAIN (decl))
                   3051:       {
                   3052:        rtx rtl = DECL_RTL (decl);
                   3053:        if (TREE_CODE (decl) == VAR_DECL && rtl != 0)
                   3054:          use_variable (rtl);
                   3055:       }
                   3056: 
                   3057:   /* Restore block_stack level for containing block.  */
                   3058: 
                   3059:   stack_block_stack = thisblock->data.block.innermost_stack_block;
                   3060:   POPSTACK (block_stack);
                   3061: 
                   3062:   /* Pop the stack slot nesting and free any slots at this level.  */
                   3063:   pop_temp_slots ();
                   3064: }
1.1.1.6   root     3065: 
                   3066: 
                   3067: /* End a binding contour.
                   3068:    VARS is the chain of VAR_DECL nodes for the variables bound
                   3069:    in this contour.  MARK_ENDS is nonzer if we should put a note
                   3070:    at the beginning and end of this binding contour.
                   3071:    DONT_JUMP_IN is nonzero if it is not valid to jump into this
                   3072:    contour.  */
                   3073: 
1.1.1.7 ! root     3074: static void
1.1.1.6   root     3075: bc_expand_end_bindings (vars, mark_ends, dont_jump_in)
                   3076:      tree vars;
                   3077:      int mark_ends;
                   3078:      int dont_jump_in;
                   3079: {
                   3080:   struct nesting *thisbind = nesting_stack;
                   3081:   tree decl;
                   3082: 
                   3083:   if (warn_unused)
                   3084:     for (decl = vars; decl; decl = TREE_CHAIN (decl))
                   3085:       if (! TREE_USED (TREE_VALUE (decl)) && TREE_CODE (TREE_VALUE (decl)) == VAR_DECL)
                   3086:        warning_with_decl (decl, "unused variable `%s'");
                   3087: 
1.1.1.7 ! root     3088:   if (thisbind->exit_label)
        !          3089:     bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisbind->exit_label));
1.1.1.6   root     3090: 
                   3091:   /* Pop block/bindings off stack */
                   3092:   POPSTACK (block_stack);
                   3093: }
1.1       root     3094: 
                   3095: /* Generate RTL for the automatic variable declaration DECL.
                   3096:    (Other kinds of declarations are simply ignored if seen here.)
                   3097:    CLEANUP is an expression to be executed at exit from this binding contour;
                   3098:    for example, in C++, it might call the destructor for this variable.
                   3099: 
                   3100:    If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
                   3101:    either before or after calling `expand_decl' but before compiling
                   3102:    any subsequent expressions.  This is because CLEANUP may be expanded
                   3103:    more than once, on different branches of execution.
                   3104:    For the same reason, CLEANUP may not contain a CALL_EXPR
                   3105:    except as its topmost node--else `preexpand_calls' would get confused.
                   3106: 
                   3107:    If CLEANUP is nonzero and DECL is zero, we record a cleanup
                   3108:    that is not associated with any particular variable.
                   3109: 
                   3110:    There is no special support here for C++ constructors.
                   3111:    They should be handled by the proper code in DECL_INITIAL.  */
                   3112: 
                   3113: void
                   3114: expand_decl (decl)
                   3115:      register tree decl;
                   3116: {
                   3117:   struct nesting *thisblock = block_stack;
1.1.1.6   root     3118:   tree type;
                   3119: 
                   3120:   if (output_bytecode)
                   3121:     {
                   3122:       bc_expand_decl (decl, 0);
                   3123:       return;
                   3124:     }
                   3125: 
                   3126:   type = TREE_TYPE (decl);
1.1       root     3127: 
                   3128:   /* Only automatic variables need any expansion done.
                   3129:      Static and external variables, and external functions,
                   3130:      will be handled by `assemble_variable' (called from finish_decl).
                   3131:      TYPE_DECL and CONST_DECL require nothing.
                   3132:      PARM_DECLs are handled in `assign_parms'.  */
                   3133: 
                   3134:   if (TREE_CODE (decl) != VAR_DECL)
                   3135:     return;
1.1.1.4   root     3136:   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1.1       root     3137:     return;
                   3138: 
                   3139:   /* Create the RTL representation for the variable.  */
                   3140: 
                   3141:   if (type == error_mark_node)
                   3142:     DECL_RTL (decl) = gen_rtx (MEM, BLKmode, const0_rtx);
                   3143:   else if (DECL_SIZE (decl) == 0)
                   3144:     /* Variable with incomplete type.  */
                   3145:     {
                   3146:       if (DECL_INITIAL (decl) == 0)
                   3147:        /* Error message was already done; now avoid a crash.  */
                   3148:        DECL_RTL (decl) = assign_stack_temp (DECL_MODE (decl), 0, 1);
                   3149:       else
                   3150:        /* An initializer is going to decide the size of this array.
                   3151:           Until we know the size, represent its address with a reg.  */
                   3152:        DECL_RTL (decl) = gen_rtx (MEM, BLKmode, gen_reg_rtx (Pmode));
                   3153:     }
                   3154:   else if (DECL_MODE (decl) != BLKmode
                   3155:           /* If -ffloat-store, don't put explicit float vars
                   3156:              into regs.  */
                   3157:           && !(flag_float_store
                   3158:                && TREE_CODE (type) == REAL_TYPE)
                   3159:           && ! TREE_THIS_VOLATILE (decl)
                   3160:           && ! TREE_ADDRESSABLE (decl)
1.1.1.4   root     3161:           && (DECL_REGISTER (decl) || ! obey_regdecls))
1.1       root     3162:     {
                   3163:       /* Automatic variable that can go in a register.  */
1.1.1.4   root     3164:       int unsignedp = TREE_UNSIGNED (type);
1.1.1.7 ! root     3165:       enum machine_mode reg_mode
        !          3166:        = promote_mode (type, DECL_MODE (decl), &unsignedp, 0);
1.1.1.4   root     3167: 
1.1.1.6   root     3168:       if (TREE_CODE (type) == COMPLEX_TYPE)
                   3169:        {
                   3170:          rtx realpart, imagpart;
                   3171:          enum machine_mode partmode = TYPE_MODE (TREE_TYPE (type));
                   3172: 
                   3173:          /* For a complex type variable, make a CONCAT of two pseudos
                   3174:             so that the real and imaginary parts
                   3175:             can be allocated separately.  */
                   3176:          realpart = gen_reg_rtx (partmode);
                   3177:          REG_USERVAR_P (realpart) = 1;
                   3178:          imagpart = gen_reg_rtx (partmode);
                   3179:          REG_USERVAR_P (imagpart) = 1;
                   3180:          DECL_RTL (decl) = gen_rtx (CONCAT, reg_mode, realpart, imagpart);
                   3181:        }
                   3182:       else
                   3183:        {
                   3184:          DECL_RTL (decl) = gen_reg_rtx (reg_mode);
                   3185:          if (TREE_CODE (type) == POINTER_TYPE)
                   3186:            mark_reg_pointer (DECL_RTL (decl));
                   3187:          REG_USERVAR_P (DECL_RTL (decl)) = 1;
                   3188:        }
1.1       root     3189:     }
                   3190:   else if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
                   3191:     {
                   3192:       /* Variable of fixed size that goes on the stack.  */
                   3193:       rtx oldaddr = 0;
                   3194:       rtx addr;
                   3195: 
                   3196:       /* If we previously made RTL for this decl, it must be an array
                   3197:         whose size was determined by the initializer.
                   3198:         The old address was a register; set that register now
                   3199:         to the proper address.  */
                   3200:       if (DECL_RTL (decl) != 0)
                   3201:        {
                   3202:          if (GET_CODE (DECL_RTL (decl)) != MEM
                   3203:              || GET_CODE (XEXP (DECL_RTL (decl), 0)) != REG)
                   3204:            abort ();
                   3205:          oldaddr = XEXP (DECL_RTL (decl), 0);
                   3206:        }
                   3207: 
                   3208:       DECL_RTL (decl)
                   3209:        = assign_stack_temp (DECL_MODE (decl),
                   3210:                             ((TREE_INT_CST_LOW (DECL_SIZE (decl))
                   3211:                               + BITS_PER_UNIT - 1)
                   3212:                              / BITS_PER_UNIT),
                   3213:                             1);
                   3214: 
                   3215:       /* Set alignment we actually gave this decl.  */
                   3216:       DECL_ALIGN (decl) = (DECL_MODE (decl) == BLKmode ? BIGGEST_ALIGNMENT
                   3217:                           : GET_MODE_BITSIZE (DECL_MODE (decl)));
                   3218: 
                   3219:       if (oldaddr)
                   3220:        {
                   3221:          addr = force_operand (XEXP (DECL_RTL (decl), 0), oldaddr);
                   3222:          if (addr != oldaddr)
                   3223:            emit_move_insn (oldaddr, addr);
                   3224:        }
                   3225: 
                   3226:       /* If this is a memory ref that contains aggregate components,
                   3227:         mark it as such for cse and loop optimize.  */
1.1.1.7 ! root     3228:       MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));
1.1       root     3229: #if 0
                   3230:       /* If this is in memory because of -ffloat-store,
                   3231:         set the volatile bit, to prevent optimizations from
                   3232:         undoing the effects.  */
                   3233:       if (flag_float_store && TREE_CODE (type) == REAL_TYPE)
                   3234:        MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
                   3235: #endif
                   3236:     }
                   3237:   else
                   3238:     /* Dynamic-size object: must push space on the stack.  */
                   3239:     {
                   3240:       rtx address, size;
                   3241: 
                   3242:       /* Record the stack pointer on entry to block, if have
                   3243:         not already done so.  */
                   3244:       if (thisblock->data.block.stack_level == 0)
                   3245:        {
                   3246:          do_pending_stack_adjust ();
1.1.1.3   root     3247:          emit_stack_save (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
                   3248:                           &thisblock->data.block.stack_level,
                   3249:                           thisblock->data.block.first_insn);
1.1       root     3250:          stack_block_stack = thisblock;
                   3251:        }
                   3252: 
                   3253:       /* Compute the variable's size, in bytes.  */
                   3254:       size = expand_expr (size_binop (CEIL_DIV_EXPR,
                   3255:                                      DECL_SIZE (decl),
                   3256:                                      size_int (BITS_PER_UNIT)),
1.1.1.4   root     3257:                          NULL_RTX, VOIDmode, 0);
1.1       root     3258:       free_temp_slots ();
                   3259: 
                   3260:       /* Allocate space on the stack for the variable.  */
1.1.1.4   root     3261:       address = allocate_dynamic_stack_space (size, NULL_RTX,
                   3262:                                              DECL_ALIGN (decl));
1.1       root     3263: 
                   3264:       /* Reference the variable indirect through that rtx.  */
                   3265:       DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);
                   3266: 
1.1.1.3   root     3267:       /* If this is a memory ref that contains aggregate components,
                   3268:         mark it as such for cse and loop optimize.  */
1.1.1.7 ! root     3269:       MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));
1.1.1.3   root     3270: 
1.1       root     3271:       /* Indicate the alignment we actually gave this variable.  */
                   3272: #ifdef STACK_BOUNDARY
                   3273:       DECL_ALIGN (decl) = STACK_BOUNDARY;
                   3274: #else
                   3275:       DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
                   3276: #endif
                   3277:     }
                   3278: 
                   3279:   if (TREE_THIS_VOLATILE (decl))
                   3280:     MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
1.1.1.5   root     3281: #if 0 /* A variable is not necessarily unchanging
                   3282:         just because it is const.  RTX_UNCHANGING_P
                   3283:         means no change in the function,
                   3284:         not merely no change in the variable's scope.
                   3285:         It is correct to set RTX_UNCHANGING_P if the variable's scope
                   3286:         is the whole function.  There's no convenient way to test that.  */
1.1       root     3287:   if (TREE_READONLY (decl))
                   3288:     RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
1.1.1.5   root     3289: #endif
1.1       root     3290: 
                   3291:   /* If doing stupid register allocation, make sure life of any
                   3292:      register variable starts here, at the start of its scope.  */
                   3293: 
                   3294:   if (obey_regdecls)
                   3295:     use_variable (DECL_RTL (decl));
                   3296: }
1.1.1.6   root     3297: 
                   3298: 
                   3299: /* Generate code for the automatic variable declaration DECL.  For
                   3300:    most variables this just means we give it a stack offset.  The
                   3301:    compiler sometimes emits cleanups without variables and we will
                   3302:    have to deal with those too.  */
                   3303: 
1.1.1.7 ! root     3304: static void
1.1.1.6   root     3305: bc_expand_decl (decl, cleanup)
                   3306:      tree decl;
                   3307:      tree cleanup;
                   3308: {
                   3309:   tree type;
                   3310: 
                   3311:   if (!decl)
                   3312:     {
                   3313:       /* A cleanup with no variable.  */
                   3314:       if (!cleanup)
                   3315:        abort ();
                   3316: 
                   3317:       return;
                   3318:     }
                   3319: 
                   3320:   /* Only auto variables need any work.  */
                   3321:   if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl) || DECL_EXTERNAL (decl))
                   3322:     return;
                   3323: 
                   3324:   type = TREE_TYPE (decl);
                   3325: 
                   3326:   if (type == error_mark_node)
                   3327:     DECL_RTL (decl) = bc_gen_rtx ((char *) 0, 0, (struct bc_label *) 0);
                   3328: 
                   3329:   else if (DECL_SIZE (decl) == 0)
                   3330: 
                   3331:     /* Variable with incomplete type.  The stack offset herein will be
                   3332:        fixed later in expand_decl_init ().  */
                   3333:     DECL_RTL (decl) = bc_gen_rtx ((char *) 0, 0, (struct bc_label *) 0);
                   3334: 
                   3335:   else if (TREE_CONSTANT (DECL_SIZE (decl)))
                   3336:     {
                   3337:       DECL_RTL (decl) = bc_allocate_local (TREE_INT_CST_LOW (DECL_SIZE (decl)) / BITS_PER_UNIT,
                   3338:                                           DECL_ALIGN (decl));
                   3339:     }
                   3340:   else
                   3341:     DECL_RTL (decl) = bc_allocate_variable_array (DECL_SIZE (decl));
                   3342: }
1.1       root     3343: 
                   3344: /* Emit code to perform the initialization of a declaration DECL.  */
                   3345: 
                   3346: void
                   3347: expand_decl_init (decl)
                   3348:      tree decl;
                   3349: {
1.1.1.2   root     3350:   int was_used = TREE_USED (decl);
                   3351: 
1.1.1.7 ! root     3352:   if (output_bytecode)
        !          3353:     {
        !          3354:       bc_expand_decl_init (decl);
        !          3355:       return;
        !          3356:     }
        !          3357: 
1.1.1.6   root     3358:   /* If this is a CONST_DECL, we don't have to generate any code, but
                   3359:      if DECL_INITIAL is a constant, call expand_expr to force TREE_CST_RTL
                   3360:      to be set while in the obstack containing the constant.  If we don't
                   3361:      do this, we can lose if we have functions nested three deep and the middle
                   3362:      function makes a CONST_DECL whose DECL_INITIAL is a STRING_CST while
                   3363:      the innermost function is the first to expand that STRING_CST.  */
                   3364:   if (TREE_CODE (decl) == CONST_DECL)
                   3365:     {
                   3366:       if (DECL_INITIAL (decl) && TREE_CONSTANT (DECL_INITIAL (decl)))
                   3367:        expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
                   3368:                     EXPAND_INITIALIZER);
                   3369:       return;
                   3370:     }
                   3371: 
1.1       root     3372:   if (TREE_STATIC (decl))
                   3373:     return;
                   3374: 
                   3375:   /* Compute and store the initial value now.  */
                   3376: 
                   3377:   if (DECL_INITIAL (decl) == error_mark_node)
                   3378:     {
                   3379:       enum tree_code code = TREE_CODE (TREE_TYPE (decl));
                   3380:       if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
                   3381:          || code == POINTER_TYPE)
                   3382:        expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node),
                   3383:                           0, 0);
                   3384:       emit_queue ();
                   3385:     }
                   3386:   else if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) != TREE_LIST)
                   3387:     {
                   3388:       emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
                   3389:       expand_assignment (decl, DECL_INITIAL (decl), 0, 0);
                   3390:       emit_queue ();
                   3391:     }
                   3392: 
1.1.1.2   root     3393:   /* Don't let the initialization count as "using" the variable.  */
                   3394:   TREE_USED (decl) = was_used;
                   3395: 
1.1       root     3396:   /* Free any temporaries we made while initializing the decl.  */
                   3397:   free_temp_slots ();
                   3398: }
                   3399: 
1.1.1.6   root     3400: /* Expand initialization for variable-sized types. Allocate array
                   3401:    using newlocalSI and set local variable, which is a pointer to the
                   3402:    storage. */
                   3403: 
1.1.1.7 ! root     3404: static void
1.1.1.6   root     3405: bc_expand_variable_local_init (decl)
                   3406:      tree decl;
                   3407: {
                   3408:   /* Evaluate size expression and coerce to SI */
                   3409:   bc_expand_expr (DECL_SIZE (decl));
                   3410: 
                   3411:   /* Type sizes are always (?) of TREE_CODE INTEGER_CST, so
                   3412:      no coercion is necessary (?) */
                   3413: 
                   3414: /*  emit_typecode_conversion (preferred_typecode (TYPE_MODE (DECL_SIZE (decl)),
                   3415:                                                TREE_UNSIGNED (DECL_SIZE (decl))), SIcode); */
                   3416: 
                   3417:   /* Emit code to allocate array */
                   3418:   bc_emit_instruction (newlocalSI);
                   3419: 
                   3420:   /* Store array pointer in local variable. This is the only instance
                   3421:      where we actually want the address of the pointer to the
                   3422:      variable-size block, rather than the pointer itself.  We avoid
                   3423:      using expand_address() since that would cause the pointer to be
                   3424:      pushed rather than its address. Hence the hard-coded reference;
                   3425:      notice also that the variable is always local (no global
                   3426:      variable-size type variables). */
                   3427: 
                   3428:   bc_load_localaddr (DECL_RTL (decl));
                   3429:   bc_emit_instruction (storeP);
                   3430: }
                   3431: 
                   3432: 
                   3433: /* Emit code to initialize a declaration.  */
1.1.1.7 ! root     3434: 
        !          3435: static void
1.1.1.6   root     3436: bc_expand_decl_init (decl)
                   3437:      tree decl;
                   3438: {
                   3439:   int org_stack_depth;
                   3440: 
                   3441:   /* Statical initializers are handled elsewhere */
                   3442: 
                   3443:   if (TREE_STATIC (decl))
                   3444:     return;
                   3445: 
                   3446:   /* Memory original stack depth */
                   3447:   org_stack_depth = stack_depth;
                   3448: 
                   3449:   /* If the type is variable-size, we first create its space (we ASSUME
                   3450:      it CAN'T be static).  We do this regardless of whether there's an
                   3451:      initializer assignment or not. */
                   3452: 
                   3453:   if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
                   3454:     bc_expand_variable_local_init (decl);
                   3455: 
                   3456:   /* Expand initializer assignment */
                   3457:   if (DECL_INITIAL (decl) == error_mark_node)
                   3458:     {
                   3459:       enum tree_code code = TREE_CODE (TREE_TYPE (decl));
                   3460: 
                   3461:       if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
                   3462:          || code == POINTER_TYPE)
                   3463: 
                   3464:        expand_assignment (TREE_TYPE (decl), decl, 0, 0);
                   3465:     }
                   3466:   else if (DECL_INITIAL (decl))
                   3467:     expand_assignment (TREE_TYPE (decl), decl, 0, 0);
                   3468: 
                   3469:   /* Restore stack depth */
                   3470:   if (org_stack_depth > stack_depth)
                   3471:     abort ();
                   3472: 
                   3473:   bc_adjust_stack (stack_depth - org_stack_depth);
                   3474: }
                   3475:  
                   3476: 
1.1       root     3477: /* CLEANUP is an expression to be executed at exit from this binding contour;
                   3478:    for example, in C++, it might call the destructor for this variable.
                   3479: 
                   3480:    If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
                   3481:    either before or after calling `expand_decl' but before compiling
                   3482:    any subsequent expressions.  This is because CLEANUP may be expanded
                   3483:    more than once, on different branches of execution.
                   3484:    For the same reason, CLEANUP may not contain a CALL_EXPR
                   3485:    except as its topmost node--else `preexpand_calls' would get confused.
                   3486: 
                   3487:    If CLEANUP is nonzero and DECL is zero, we record a cleanup
                   3488:    that is not associated with any particular variable.   */
                   3489: 
                   3490: int
                   3491: expand_decl_cleanup (decl, cleanup)
                   3492:      tree decl, cleanup;
                   3493: {
                   3494:   struct nesting *thisblock = block_stack;
                   3495: 
                   3496:   /* Error if we are not in any block.  */
                   3497:   if (thisblock == 0)
                   3498:     return 0;
                   3499: 
                   3500:   /* Record the cleanup if there is one.  */
                   3501: 
                   3502:   if (cleanup != 0)
                   3503:     {
                   3504:       thisblock->data.block.cleanups
                   3505:        = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
                   3506:       /* If this block has a cleanup, it belongs in stack_block_stack.  */
                   3507:       stack_block_stack = thisblock;
1.1.1.7 ! root     3508:       (*interim_eh_hook) (NULL_TREE);
1.1       root     3509:     }
                   3510:   return 1;
                   3511: }
                   3512: 
                   3513: /* DECL is an anonymous union.  CLEANUP is a cleanup for DECL.
                   3514:    DECL_ELTS is the list of elements that belong to DECL's type.
                   3515:    In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup.  */
                   3516: 
                   3517: void
                   3518: expand_anon_union_decl (decl, cleanup, decl_elts)
                   3519:      tree decl, cleanup, decl_elts;
                   3520: {
                   3521:   struct nesting *thisblock = block_stack;
                   3522:   rtx x;
                   3523: 
                   3524:   expand_decl (decl, cleanup);
                   3525:   x = DECL_RTL (decl);
                   3526: 
                   3527:   while (decl_elts)
                   3528:     {
                   3529:       tree decl_elt = TREE_VALUE (decl_elts);
                   3530:       tree cleanup_elt = TREE_PURPOSE (decl_elts);
                   3531:       enum machine_mode mode = TYPE_MODE (TREE_TYPE (decl_elt));
                   3532: 
1.1.1.7 ! root     3533:       /* Propagate the union's alignment to the elements.  */
        !          3534:       DECL_ALIGN (decl_elt) = DECL_ALIGN (decl);
        !          3535: 
        !          3536:       /* If the element has BLKmode and the union doesn't, the union is
        !          3537:          aligned such that the element doesn't need to have BLKmode, so
        !          3538:          change the element's mode to the appropriate one for its size.  */
        !          3539:       if (mode == BLKmode && DECL_MODE (decl) != BLKmode)
        !          3540:        DECL_MODE (decl_elt) = mode
        !          3541:          = mode_for_size (TREE_INT_CST_LOW (DECL_SIZE (decl_elt)),
        !          3542:                           MODE_INT, 1);
        !          3543: 
1.1       root     3544:       /* (SUBREG (MEM ...)) at RTL generation time is invalid, so we
                   3545:          instead create a new MEM rtx with the proper mode.  */
                   3546:       if (GET_CODE (x) == MEM)
                   3547:        {
                   3548:          if (mode == GET_MODE (x))
                   3549:            DECL_RTL (decl_elt) = x;
                   3550:          else
                   3551:            {
                   3552:              DECL_RTL (decl_elt) = gen_rtx (MEM, mode, copy_rtx (XEXP (x, 0)));
                   3553:              MEM_IN_STRUCT_P (DECL_RTL (decl_elt)) = MEM_IN_STRUCT_P (x);
                   3554:              RTX_UNCHANGING_P (DECL_RTL (decl_elt)) = RTX_UNCHANGING_P (x);
                   3555:            }
                   3556:        }
                   3557:       else if (GET_CODE (x) == REG)
                   3558:        {
                   3559:          if (mode == GET_MODE (x))
                   3560:            DECL_RTL (decl_elt) = x;
                   3561:          else
                   3562:            DECL_RTL (decl_elt) = gen_rtx (SUBREG, mode, x, 0);
                   3563:        }
                   3564:       else
                   3565:        abort ();
                   3566: 
                   3567:       /* Record the cleanup if there is one.  */
                   3568: 
                   3569:       if (cleanup != 0)
                   3570:        thisblock->data.block.cleanups
                   3571:          = temp_tree_cons (decl_elt, cleanup_elt,
                   3572:                            thisblock->data.block.cleanups);
                   3573: 
                   3574:       decl_elts = TREE_CHAIN (decl_elts);
                   3575:     }
                   3576: }
                   3577: 
                   3578: /* Expand a list of cleanups LIST.
                   3579:    Elements may be expressions or may be nested lists.
                   3580: 
                   3581:    If DONT_DO is nonnull, then any list-element
                   3582:    whose TREE_PURPOSE matches DONT_DO is omitted.
                   3583:    This is sometimes used to avoid a cleanup associated with
                   3584:    a value that is being returned out of the scope.  */
                   3585: 
                   3586: static void
                   3587: expand_cleanups (list, dont_do)
                   3588:      tree list;
                   3589:      tree dont_do;
                   3590: {
                   3591:   tree tail;
                   3592:   for (tail = list; tail; tail = TREE_CHAIN (tail))
                   3593:     if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do)
                   3594:       {
                   3595:        if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
                   3596:          expand_cleanups (TREE_VALUE (tail), dont_do);
                   3597:        else
                   3598:          {
1.1.1.7 ! root     3599:            (*interim_eh_hook) (TREE_VALUE (tail));
        !          3600: 
1.1       root     3601:            /* Cleanups may be run multiple times.  For example,
                   3602:               when exiting a binding contour, we expand the
                   3603:               cleanups associated with that contour.  When a goto
                   3604:               within that binding contour has a target outside that
                   3605:               contour, it will expand all cleanups from its scope to
                   3606:               the target.  Though the cleanups are expanded multiple
                   3607:               times, the control paths are non-overlapping so the
                   3608:               cleanups will not be executed twice.  */
                   3609:            expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
                   3610:            free_temp_slots ();
                   3611:          }
                   3612:       }
                   3613: }
                   3614: 
                   3615: /* Move all cleanups from the current block_stack
                   3616:    to the containing block_stack, where they are assumed to
                   3617:    have been created.  If anything can cause a temporary to
                   3618:    be created, but not expanded for more than one level of
                   3619:    block_stacks, then this code will have to change.  */
                   3620: 
                   3621: void
                   3622: move_cleanups_up ()
                   3623: {
                   3624:   struct nesting *block = block_stack;
                   3625:   struct nesting *outer = block->next;
                   3626: 
                   3627:   outer->data.block.cleanups
                   3628:     = chainon (block->data.block.cleanups,
                   3629:               outer->data.block.cleanups);
                   3630:   block->data.block.cleanups = 0;
                   3631: }
                   3632: 
                   3633: tree
                   3634: last_cleanup_this_contour ()
                   3635: {
                   3636:   if (block_stack == 0)
                   3637:     return 0;
                   3638: 
                   3639:   return block_stack->data.block.cleanups;
                   3640: }
                   3641: 
                   3642: /* Return 1 if there are any pending cleanups at this point.
                   3643:    If THIS_CONTOUR is nonzero, check the current contour as well.
                   3644:    Otherwise, look only at the contours that enclose this one.  */
                   3645: 
                   3646: int
                   3647: any_pending_cleanups (this_contour)
                   3648:      int this_contour;
                   3649: {
                   3650:   struct nesting *block;
                   3651: 
                   3652:   if (block_stack == 0)
                   3653:     return 0;
                   3654: 
                   3655:   if (this_contour && block_stack->data.block.cleanups != NULL)
                   3656:     return 1;
                   3657:   if (block_stack->data.block.cleanups == 0
                   3658:       && (block_stack->data.block.outer_cleanups == 0
                   3659: #if 0
                   3660:          || block_stack->data.block.outer_cleanups == empty_cleanup_list
                   3661: #endif
                   3662:          ))
                   3663:     return 0;
                   3664: 
                   3665:   for (block = block_stack->next; block; block = block->next)
                   3666:     if (block->data.block.cleanups != 0)
                   3667:       return 1;
                   3668: 
                   3669:   return 0;
                   3670: }
                   3671: 
                   3672: /* Enter a case (Pascal) or switch (C) statement.
                   3673:    Push a block onto case_stack and nesting_stack
                   3674:    to accumulate the case-labels that are seen
                   3675:    and to record the labels generated for the statement.
                   3676: 
                   3677:    EXIT_FLAG is nonzero if `exit_something' should exit this case stmt.
                   3678:    Otherwise, this construct is transparent for `exit_something'.
                   3679: 
                   3680:    EXPR is the index-expression to be dispatched on.
                   3681:    TYPE is its nominal type.  We could simply convert EXPR to this type,
                   3682:    but instead we take short cuts.  */
                   3683: 
                   3684: void
                   3685: expand_start_case (exit_flag, expr, type, printname)
                   3686:      int exit_flag;
                   3687:      tree expr;
                   3688:      tree type;
                   3689:      char *printname;
                   3690: {
                   3691:   register struct nesting *thiscase = ALLOC_NESTING ();
                   3692: 
                   3693:   /* Make an entry on case_stack for the case we are entering.  */
                   3694: 
                   3695:   thiscase->next = case_stack;
                   3696:   thiscase->all = nesting_stack;
                   3697:   thiscase->depth = ++nesting_depth;
                   3698:   thiscase->exit_label = exit_flag ? gen_label_rtx () : 0;
                   3699:   thiscase->data.case_stmt.case_list = 0;
                   3700:   thiscase->data.case_stmt.index_expr = expr;
                   3701:   thiscase->data.case_stmt.nominal_type = type;
                   3702:   thiscase->data.case_stmt.default_label = 0;
                   3703:   thiscase->data.case_stmt.num_ranges = 0;
                   3704:   thiscase->data.case_stmt.printname = printname;
                   3705:   thiscase->data.case_stmt.seenlabel = 0;
                   3706:   case_stack = thiscase;
                   3707:   nesting_stack = thiscase;
                   3708: 
1.1.1.6   root     3709:   if (output_bytecode)
                   3710:     {
                   3711:       bc_expand_start_case (thiscase, expr, type, printname);
                   3712:       return;
                   3713:     }
                   3714: 
1.1       root     3715:   do_pending_stack_adjust ();
                   3716: 
                   3717:   /* Make sure case_stmt.start points to something that won't
                   3718:      need any transformation before expand_end_case.  */
                   3719:   if (GET_CODE (get_last_insn ()) != NOTE)
1.1.1.4   root     3720:     emit_note (NULL_PTR, NOTE_INSN_DELETED);
1.1       root     3721: 
                   3722:   thiscase->data.case_stmt.start = get_last_insn ();
                   3723: }
                   3724: 
1.1.1.6   root     3725: 
                   3726: /* Enter a case statement. It is assumed that the caller has pushed
                   3727:    the current context onto the case stack. */
1.1.1.7 ! root     3728: 
        !          3729: static void
1.1.1.6   root     3730: bc_expand_start_case (thiscase, expr, type, printname)
                   3731:      struct nesting *thiscase;
                   3732:      tree expr;
                   3733:      tree type;
                   3734:      char *printname;
                   3735: {
                   3736:   bc_expand_expr (expr);
                   3737:   bc_expand_conversion (TREE_TYPE (expr), type);
                   3738: 
                   3739:   /* For cases, the skip is a place we jump to that's emitted after
                   3740:      the size of the jump table is known.  */
                   3741: 
                   3742:   thiscase->data.case_stmt.skip_label = gen_label_rtx ();
                   3743:   bc_emit_bytecode (jump);
                   3744:   bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->data.case_stmt.skip_label));
                   3745: 
                   3746: #ifdef DEBUG_PRINT_CODE
                   3747:   fputc ('\n', stderr);
                   3748: #endif
                   3749: }
                   3750: 
                   3751: 
1.1       root     3752: /* Start a "dummy case statement" within which case labels are invalid
                   3753:    and are not connected to any larger real case statement.
                   3754:    This can be used if you don't want to let a case statement jump
                   3755:    into the middle of certain kinds of constructs.  */
                   3756: 
                   3757: void
                   3758: expand_start_case_dummy ()
                   3759: {
                   3760:   register struct nesting *thiscase = ALLOC_NESTING ();
                   3761: 
                   3762:   /* Make an entry on case_stack for the dummy.  */
                   3763: 
                   3764:   thiscase->next = case_stack;
                   3765:   thiscase->all = nesting_stack;
                   3766:   thiscase->depth = ++nesting_depth;
                   3767:   thiscase->exit_label = 0;
                   3768:   thiscase->data.case_stmt.case_list = 0;
                   3769:   thiscase->data.case_stmt.start = 0;
                   3770:   thiscase->data.case_stmt.nominal_type = 0;
                   3771:   thiscase->data.case_stmt.default_label = 0;
                   3772:   thiscase->data.case_stmt.num_ranges = 0;
                   3773:   case_stack = thiscase;
                   3774:   nesting_stack = thiscase;
                   3775: }
                   3776: 
                   3777: /* End a dummy case statement.  */
                   3778: 
                   3779: void
                   3780: expand_end_case_dummy ()
                   3781: {
                   3782:   POPSTACK (case_stack);
                   3783: }
                   3784: 
                   3785: /* Return the data type of the index-expression
                   3786:    of the innermost case statement, or null if none.  */
                   3787: 
                   3788: tree
                   3789: case_index_expr_type ()
                   3790: {
                   3791:   if (case_stack)
                   3792:     return TREE_TYPE (case_stack->data.case_stmt.index_expr);
                   3793:   return 0;
                   3794: }
                   3795: 
                   3796: /* Accumulate one case or default label inside a case or switch statement.
                   3797:    VALUE is the value of the case (a null pointer, for a default label).
1.1.1.6   root     3798:    The function CONVERTER, when applied to arguments T and V,
                   3799:    converts the value V to the type T.
1.1       root     3800: 
                   3801:    If not currently inside a case or switch statement, return 1 and do
                   3802:    nothing.  The caller will print a language-specific error message.
                   3803:    If VALUE is a duplicate or overlaps, return 2 and do nothing
                   3804:    except store the (first) duplicate node in *DUPLICATE.
                   3805:    If VALUE is out of range, return 3 and do nothing.
                   3806:    If we are jumping into the scope of a cleaup or var-sized array, return 5.
                   3807:    Return 0 on success.
                   3808: 
                   3809:    Extended to handle range statements.  */
                   3810: 
                   3811: int
1.1.1.6   root     3812: pushcase (value, converter, label, duplicate)
1.1       root     3813:      register tree value;
1.1.1.6   root     3814:      tree (*converter) PROTO((tree, tree));
1.1       root     3815:      register tree label;
                   3816:      tree *duplicate;
                   3817: {
                   3818:   register struct case_node **l;
                   3819:   register struct case_node *n;
                   3820:   tree index_type;
                   3821:   tree nominal_type;
                   3822: 
1.1.1.6   root     3823:   if (output_bytecode)
                   3824:     return bc_pushcase (value, label);
                   3825: 
1.1       root     3826:   /* Fail if not inside a real case statement.  */
                   3827:   if (! (case_stack && case_stack->data.case_stmt.start))
                   3828:     return 1;
                   3829: 
                   3830:   if (stack_block_stack
                   3831:       && stack_block_stack->depth > case_stack->depth)
                   3832:     return 5;
                   3833: 
                   3834:   index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
                   3835:   nominal_type = case_stack->data.case_stmt.nominal_type;
                   3836: 
                   3837:   /* If the index is erroneous, avoid more problems: pretend to succeed.  */
                   3838:   if (index_type == error_mark_node)
                   3839:     return 0;
                   3840: 
                   3841:   /* Convert VALUE to the type in which the comparisons are nominally done.  */
                   3842:   if (value != 0)
1.1.1.6   root     3843:     value = (*converter) (nominal_type, value);
1.1       root     3844: 
                   3845:   /* If this is the first label, warn if any insns have been emitted.  */
                   3846:   if (case_stack->data.case_stmt.seenlabel == 0)
                   3847:     {
                   3848:       rtx insn;
                   3849:       for (insn = case_stack->data.case_stmt.start;
                   3850:           insn;
                   3851:           insn = NEXT_INSN (insn))
                   3852:        {
                   3853:          if (GET_CODE (insn) == CODE_LABEL)
                   3854:            break;
                   3855:          if (GET_CODE (insn) != NOTE
                   3856:              && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
                   3857:            {
                   3858:              warning ("unreachable code at beginning of %s",
                   3859:                       case_stack->data.case_stmt.printname);
                   3860:              break;
                   3861:            }
                   3862:        }
                   3863:     }
                   3864:   case_stack->data.case_stmt.seenlabel = 1;
                   3865: 
                   3866:   /* Fail if this value is out of range for the actual type of the index
                   3867:      (which may be narrower than NOMINAL_TYPE).  */
                   3868:   if (value != 0 && ! int_fits_type_p (value, index_type))
                   3869:     return 3;
                   3870: 
                   3871:   /* Fail if this is a duplicate or overlaps another entry.  */
                   3872:   if (value == 0)
                   3873:     {
                   3874:       if (case_stack->data.case_stmt.default_label != 0)
                   3875:        {
                   3876:          *duplicate = case_stack->data.case_stmt.default_label;
                   3877:          return 2;
                   3878:        }
                   3879:       case_stack->data.case_stmt.default_label = label;
                   3880:     }
                   3881:   else
                   3882:     {
                   3883:       /* Find the elt in the chain before which to insert the new value,
                   3884:         to keep the chain sorted in increasing order.
                   3885:         But report an error if this element is a duplicate.  */
                   3886:       for (l = &case_stack->data.case_stmt.case_list;
                   3887:           /* Keep going past elements distinctly less than VALUE.  */
                   3888:           *l != 0 && tree_int_cst_lt ((*l)->high, value);
                   3889:           l = &(*l)->right)
                   3890:        ;
                   3891:       if (*l)
                   3892:        {
                   3893:          /* Element we will insert before must be distinctly greater;
                   3894:             overlap means error.  */
                   3895:          if (! tree_int_cst_lt (value, (*l)->low))
                   3896:            {
                   3897:              *duplicate = (*l)->code_label;
                   3898:              return 2;
                   3899:            }
                   3900:        }
                   3901: 
                   3902:       /* Add this label to the chain, and succeed.
                   3903:         Copy VALUE so it is on temporary rather than momentary
                   3904:         obstack and will thus survive till the end of the case statement.  */
                   3905:       n = (struct case_node *) oballoc (sizeof (struct case_node));
                   3906:       n->left = 0;
                   3907:       n->right = *l;
                   3908:       n->high = n->low = copy_node (value);
                   3909:       n->code_label = label;
                   3910:       *l = n;
                   3911:     }
                   3912: 
                   3913:   expand_label (label);
                   3914:   return 0;
                   3915: }
                   3916: 
                   3917: /* Like pushcase but this case applies to all values
                   3918:    between VALUE1 and VALUE2 (inclusive).
                   3919:    The return value is the same as that of pushcase
                   3920:    but there is one additional error code:
                   3921:    4 means the specified range was empty.  */
                   3922: 
                   3923: int
1.1.1.6   root     3924: pushcase_range (value1, value2, converter, label, duplicate)
1.1       root     3925:      register tree value1, value2;
1.1.1.6   root     3926:      tree (*converter) PROTO((tree, tree));
1.1       root     3927:      register tree label;
                   3928:      tree *duplicate;
                   3929: {
                   3930:   register struct case_node **l;
                   3931:   register struct case_node *n;
                   3932:   tree index_type;
                   3933:   tree nominal_type;
                   3934: 
                   3935:   /* Fail if not inside a real case statement.  */
                   3936:   if (! (case_stack && case_stack->data.case_stmt.start))
                   3937:     return 1;
                   3938: 
                   3939:   if (stack_block_stack
                   3940:       && stack_block_stack->depth > case_stack->depth)
                   3941:     return 5;
                   3942: 
                   3943:   index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
                   3944:   nominal_type = case_stack->data.case_stmt.nominal_type;
                   3945: 
                   3946:   /* If the index is erroneous, avoid more problems: pretend to succeed.  */
                   3947:   if (index_type == error_mark_node)
                   3948:     return 0;
                   3949: 
                   3950:   /* If this is the first label, warn if any insns have been emitted.  */
                   3951:   if (case_stack->data.case_stmt.seenlabel == 0)
                   3952:     {
                   3953:       rtx insn;
                   3954:       for (insn = case_stack->data.case_stmt.start;
                   3955:           insn;
                   3956:           insn = NEXT_INSN (insn))
                   3957:        {
                   3958:          if (GET_CODE (insn) == CODE_LABEL)
                   3959:            break;
                   3960:          if (GET_CODE (insn) != NOTE
                   3961:              && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
                   3962:            {
                   3963:              warning ("unreachable code at beginning of %s",
                   3964:                       case_stack->data.case_stmt.printname);
                   3965:              break;
                   3966:            }
                   3967:        }
                   3968:     }
                   3969:   case_stack->data.case_stmt.seenlabel = 1;
                   3970: 
                   3971:   /* Convert VALUEs to type in which the comparisons are nominally done.  */
                   3972:   if (value1 == 0)  /* Negative infinity. */
                   3973:     value1 = TYPE_MIN_VALUE(index_type);
1.1.1.6   root     3974:   value1 = (*converter) (nominal_type, value1);
1.1       root     3975: 
                   3976:   if (value2 == 0)  /* Positive infinity. */
                   3977:     value2 = TYPE_MAX_VALUE(index_type);
1.1.1.6   root     3978:   value2 = (*converter) (nominal_type, value2);
1.1       root     3979: 
                   3980:   /* Fail if these values are out of range.  */
                   3981:   if (! int_fits_type_p (value1, index_type))
                   3982:     return 3;
                   3983: 
                   3984:   if (! int_fits_type_p (value2, index_type))
                   3985:     return 3;
                   3986: 
                   3987:   /* Fail if the range is empty.  */
                   3988:   if (tree_int_cst_lt (value2, value1))
                   3989:     return 4;
                   3990: 
                   3991:   /* If the bounds are equal, turn this into the one-value case.  */
                   3992:   if (tree_int_cst_equal (value1, value2))
1.1.1.6   root     3993:     return pushcase (value1, converter, label, duplicate);
1.1       root     3994: 
                   3995:   /* Find the elt in the chain before which to insert the new value,
                   3996:      to keep the chain sorted in increasing order.
                   3997:      But report an error if this element is a duplicate.  */
                   3998:   for (l = &case_stack->data.case_stmt.case_list;
                   3999:        /* Keep going past elements distinctly less than this range.  */
                   4000:        *l != 0 && tree_int_cst_lt ((*l)->high, value1);
                   4001:        l = &(*l)->right)
                   4002:     ;
                   4003:   if (*l)
                   4004:     {
                   4005:       /* Element we will insert before must be distinctly greater;
                   4006:         overlap means error.  */
                   4007:       if (! tree_int_cst_lt (value2, (*l)->low))
                   4008:        {
                   4009:          *duplicate = (*l)->code_label;
                   4010:          return 2;
                   4011:        }
                   4012:     }
                   4013: 
                   4014:   /* Add this label to the chain, and succeed.
                   4015:      Copy VALUE1, VALUE2 so they are on temporary rather than momentary
                   4016:      obstack and will thus survive till the end of the case statement.  */
                   4017: 
                   4018:   n = (struct case_node *) oballoc (sizeof (struct case_node));
                   4019:   n->left = 0;
                   4020:   n->right = *l;
                   4021:   n->low = copy_node (value1);
                   4022:   n->high = copy_node (value2);
                   4023:   n->code_label = label;
                   4024:   *l = n;
                   4025: 
                   4026:   expand_label (label);
                   4027: 
                   4028:   case_stack->data.case_stmt.num_ranges++;
                   4029: 
                   4030:   return 0;
                   4031: }
1.1.1.6   root     4032: 
                   4033: 
                   4034: /* Accumulate one case or default label; VALUE is the value of the
                   4035:    case, or nil for a default label.  If not currently inside a case,
                   4036:    return 1 and do nothing.  If VALUE is a duplicate or overlaps, return
                   4037:    2 and do nothing.  If VALUE is out of range, return 3 and do nothing.
                   4038:    Return 0 on success.  This function is a leftover from the earlier
                   4039:    bytecode compiler, which was based on gcc 1.37.  It should be
                   4040:    merged into pushcase. */
                   4041: 
1.1.1.7 ! root     4042: static int
1.1.1.6   root     4043: bc_pushcase (value, label)
                   4044:      tree value;
                   4045:      tree label;
                   4046: {
                   4047:   struct nesting *thiscase = case_stack;
                   4048:   struct case_node *case_label, *new_label;
                   4049: 
                   4050:   if (! thiscase)
                   4051:     return 1;
                   4052: 
                   4053:   /* Fail if duplicate, overlap, or out of type range.  */
                   4054:   if (value)
                   4055:     {
                   4056:       value = convert (thiscase->data.case_stmt.nominal_type, value);
                   4057:       if (! int_fits_type_p (value, thiscase->data.case_stmt.nominal_type))
                   4058:        return 3;
                   4059: 
                   4060:       for (case_label = thiscase->data.case_stmt.case_list;
                   4061:           case_label->left; case_label = case_label->left)
                   4062:        if (! tree_int_cst_lt (case_label->left->high, value))
                   4063:          break;
                   4064: 
                   4065:       if (case_label != thiscase->data.case_stmt.case_list
                   4066:          && ! tree_int_cst_lt (case_label->high, value)
                   4067:          || case_label->left && ! tree_int_cst_lt (value, case_label->left->low))
                   4068:        return 2;
                   4069: 
                   4070:       new_label = (struct case_node *) oballoc (sizeof (struct case_node));
                   4071:       new_label->low = new_label->high = copy_node (value);
                   4072:       new_label->code_label = label;
                   4073:       new_label->left = case_label->left;
                   4074: 
                   4075:       case_label->left = new_label;
                   4076:       thiscase->data.case_stmt.num_ranges++;
                   4077:     }
                   4078:   else
                   4079:     {
                   4080:       if (thiscase->data.case_stmt.default_label)
                   4081:        return 2;
                   4082:       thiscase->data.case_stmt.default_label = label;
                   4083:     }
                   4084: 
                   4085:   expand_label (label);
                   4086:   return 0;
                   4087: }
1.1       root     4088: 
1.1.1.7 ! root     4089: /* Returns the number of possible values of TYPE.
        !          4090:    Returns -1 if the number is unknown or variable.
        !          4091:    Returns -2 if the number does not fit in a HOST_WIDE_INT.
        !          4092:    Sets *SPARENESS to 2 if TYPE is an ENUMERAL_TYPE whose values
        !          4093:    do not increase monotonically (there may be duplicates);
        !          4094:    to 1 if the values increase monotonically, but not always by 1;
        !          4095:    otherwise sets it to 0.  */
        !          4096: 
        !          4097: HOST_WIDE_INT
        !          4098: all_cases_count (type, spareness)
        !          4099:      tree type;
        !          4100:      int *spareness;
        !          4101: {
        !          4102:   HOST_WIDE_INT count, count_high = 0;
        !          4103:   *spareness = 0;
        !          4104: 
        !          4105:   switch (TREE_CODE (type))
        !          4106:     {
        !          4107:       tree t;
        !          4108:     case BOOLEAN_TYPE:
        !          4109:       count = 2;
        !          4110:       break;
        !          4111:     case CHAR_TYPE:
        !          4112:       count = 1 << BITS_PER_UNIT;
        !          4113:       break;
        !          4114:     default:
        !          4115:     case INTEGER_TYPE:
        !          4116:       if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
        !          4117:          || TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST)
        !          4118:        return -1;
        !          4119:       else
        !          4120:        {
        !          4121:          /* count
        !          4122:             = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
        !          4123:             - TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + 1
        !          4124:             but with overflow checking. */
        !          4125:          tree mint = TYPE_MIN_VALUE (type);
        !          4126:          tree maxt = TYPE_MAX_VALUE (type);
        !          4127:          HOST_WIDE_INT lo, hi;
        !          4128:          neg_double(TREE_INT_CST_LOW (mint), TREE_INT_CST_HIGH (mint),
        !          4129:                     &lo, &hi);
        !          4130:          add_double(TREE_INT_CST_LOW (maxt), TREE_INT_CST_HIGH (maxt),
        !          4131:                     lo, hi, &lo, &hi);
        !          4132:          add_double (lo, hi, 1, 0, &lo, &hi);
        !          4133:          if (hi != 0 || lo < 0)
        !          4134:            return -2;
        !          4135:          count = lo;
        !          4136:        }
        !          4137:       break;
        !          4138:     case ENUMERAL_TYPE:
        !          4139:       count = 0;
        !          4140:       for (t = TYPE_VALUES (type); t != NULL_TREE; t = TREE_CHAIN (t))
        !          4141:        {
        !          4142:          if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
        !          4143:              || TREE_CODE (TREE_VALUE (t)) != INTEGER_CST
        !          4144:              || TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + count
        !          4145:              != TREE_INT_CST_LOW (TREE_VALUE (t)))
        !          4146:            *spareness = 1;
        !          4147:          count++;
        !          4148:        }
        !          4149:       if (*spareness == 1)
        !          4150:        {
        !          4151:          tree prev = TREE_VALUE (TYPE_VALUES (type));
        !          4152:          for (t = TYPE_VALUES (type); t = TREE_CHAIN (t), t != NULL_TREE; )
        !          4153:            {
        !          4154:              if (! tree_int_cst_lt (prev, TREE_VALUE (t)))
        !          4155:                {
        !          4156:                  *spareness = 2;
        !          4157:                  break;
        !          4158:                }
        !          4159:              prev = TREE_VALUE (t);
        !          4160:            }
        !          4161:          
        !          4162:        }
        !          4163:     }
        !          4164:   return count;
        !          4165: }
        !          4166: 
        !          4167: 
        !          4168: #define BITARRAY_TEST(ARRAY, INDEX) \
        !          4169:   ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\
        !          4170:                          & (1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR)))
        !          4171: #define BITARRAY_SET(ARRAY, INDEX) \
        !          4172:   ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\
        !          4173:                          |= 1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR))
        !          4174: 
        !          4175: /* Set the elements of the bitstring CASES_SEEN (which has length COUNT),
        !          4176:    with the case values we have seen, assuming the case expression
        !          4177:    has the given TYPE.
        !          4178:    SPARSENESS is as determined by all_cases_count.
        !          4179: 
        !          4180:    The time needed is propotional to COUNT, unless
        !          4181:    SPARSENESS is 2, in which case quadratic time is needed.  */
        !          4182: 
        !          4183: void
        !          4184: mark_seen_cases (type, cases_seen, count, sparseness)
        !          4185:      tree type;
        !          4186:      unsigned char *cases_seen;
        !          4187:      long count;
        !          4188:      int sparseness;
        !          4189: {
        !          4190:   long i;
        !          4191: 
        !          4192:   tree next_node_to_try = NULL_TREE;
        !          4193:   long next_node_offset = 0;
        !          4194: 
        !          4195:   register struct case_node *n;
        !          4196:   tree val = make_node (INTEGER_CST);
        !          4197:   TREE_TYPE (val) = type;
        !          4198:   for (n = case_stack->data.case_stmt.case_list; n;
        !          4199:        n = n->right)
        !          4200:     {
        !          4201:       TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (n->low);
        !          4202:       TREE_INT_CST_HIGH (val) = TREE_INT_CST_HIGH (n->low);
        !          4203:       while ( ! tree_int_cst_lt (n->high, val))
        !          4204:        {
        !          4205:          /* Calculate (into xlo) the "offset" of the integer (val).
        !          4206:             The element with lowest value has offset 0, the next smallest
        !          4207:             element has offset 1, etc.  */
        !          4208: 
        !          4209:          HOST_WIDE_INT xlo, xhi;
        !          4210:          tree t;
        !          4211:          if (sparseness == 2)
        !          4212:            {
        !          4213:              /* This less efficient loop is only needed to handle
        !          4214:                 duplicate case values (multiple enum constants
        !          4215:                 with the same value).  */
        !          4216:              for (t = TYPE_VALUES (type), xlo = 0;  t != NULL_TREE;
        !          4217:                   t = TREE_CHAIN (t), xlo++)
        !          4218:                {
        !          4219:                  if (tree_int_cst_equal (val, TREE_VALUE (t)))
        !          4220:                    BITARRAY_SET (cases_seen, xlo);
        !          4221:                }
        !          4222:            }
        !          4223:          else
        !          4224:            {
        !          4225:              if (sparseness && TYPE_VALUES (type) != NULL_TREE)
        !          4226:                {
        !          4227:                  /* The TYPE_VALUES will be in increasing order, so
        !          4228:                     starting searching where we last ended.  */
        !          4229:                  t = next_node_to_try;
        !          4230:                  xlo = next_node_offset;
        !          4231:                  xhi = 0;
        !          4232:                  for (;;)
        !          4233:                    {
        !          4234:                      if (t == NULL_TREE)
        !          4235:                        {
        !          4236:                          t = TYPE_VALUES (type);
        !          4237:                          xlo = 0;
        !          4238:                        }
        !          4239:                      if (tree_int_cst_equal (val, TREE_VALUE (t)))
        !          4240:                        {
        !          4241:                          next_node_to_try = TREE_CHAIN (t);
        !          4242:                          next_node_offset = xlo + 1;
        !          4243:                          break;
        !          4244:                        }
        !          4245:                      xlo++;
        !          4246:                      t = TREE_CHAIN (t);
        !          4247:                      if (t == next_node_to_try)
        !          4248:                        break;
        !          4249:                    }
        !          4250:                }
        !          4251:              else
        !          4252:                {
        !          4253:                  t = TYPE_MIN_VALUE (type);
        !          4254:                  if (t)
        !          4255:                    neg_double (TREE_INT_CST_LOW (t), TREE_INT_CST_HIGH (t),
        !          4256:                                &xlo, &xhi);
        !          4257:                  else
        !          4258:                    xlo = xhi = 0;
        !          4259:                  add_double (xlo, xhi,
        !          4260:                              TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
        !          4261:                              &xlo, &xhi);
        !          4262:                }
        !          4263:              
        !          4264:              if (xhi == 0 && xlo >= 0 && xlo < count)
        !          4265:                BITARRAY_SET (cases_seen, xlo);
        !          4266:            }
        !          4267:          add_double (TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
        !          4268:                      1, 0,
        !          4269:                      &TREE_INT_CST_LOW (val), &TREE_INT_CST_HIGH (val));
        !          4270:        }
        !          4271:     }
        !          4272: }
        !          4273: 
1.1       root     4274: /* Called when the index of a switch statement is an enumerated type
                   4275:    and there is no default label.
                   4276: 
                   4277:    Checks that all enumeration literals are covered by the case
                   4278:    expressions of a switch.  Also, warn if there are any extra
                   4279:    switch cases that are *not* elements of the enumerated type.
                   4280: 
                   4281:    If all enumeration literals were covered by the case expressions,
                   4282:    turn one of the expressions into the default expression since it should
                   4283:    not be possible to fall through such a switch.  */
                   4284: 
                   4285: void
                   4286: check_for_full_enumeration_handling (type)
                   4287:      tree type;
                   4288: {
                   4289:   register struct case_node *n;
                   4290:   register struct case_node **l;
                   4291:   register tree chain;
                   4292:   int all_values = 1;
                   4293: 
1.1.1.7 ! root     4294:   /* True iff the selector type is a numbered set mode. */
        !          4295:   int sparseness = 0;
        !          4296: 
        !          4297:   /* The number of possible selector values. */
        !          4298:   HOST_WIDE_INT size;
        !          4299: 
        !          4300:   /* For each possible selector value. a one iff it has been matched
        !          4301:      by a case value alternative. */
        !          4302:   unsigned char *cases_seen;
        !          4303: 
        !          4304:   /* The allocated size of cases_seen, in chars. */
        !          4305:   long bytes_needed;
        !          4306:   tree t;
        !          4307: 
1.1.1.6   root     4308:   if (output_bytecode)
                   4309:     {
                   4310:       bc_check_for_full_enumeration_handling (type);
                   4311:       return;
                   4312:     }
                   4313: 
1.1.1.7 ! root     4314:   if (! warn_switch)
        !          4315:     return;
        !          4316: 
        !          4317:   size = all_cases_count (type, &sparseness);
        !          4318:   bytes_needed = (size + HOST_BITS_PER_CHAR) / HOST_BITS_PER_CHAR;
        !          4319: 
        !          4320:   if (size > 0 && size < 600000
        !          4321:       /* We deliberately use malloc here - not xmalloc. */
        !          4322:       && (cases_seen = (unsigned char *) malloc (bytes_needed)) != NULL)
        !          4323:     {
        !          4324:       long i;
        !          4325:       tree v = TYPE_VALUES (type);
        !          4326:       bzero (cases_seen, bytes_needed);
        !          4327: 
        !          4328:       /* The time complexity of this code is normally O(N), where
        !          4329:         N being the number of members in the enumerated type.
        !          4330:         However, if type is a ENUMERAL_TYPE whose values do not
        !          4331:         increase monotonically, quadratic time may be needed. */
        !          4332: 
        !          4333:       mark_seen_cases (type, cases_seen, size, sparseness);
1.1       root     4334: 
1.1.1.7 ! root     4335:       for (i = 0;  v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v))
1.1       root     4336:        {
1.1.1.7 ! root     4337:          if (BITARRAY_TEST(cases_seen, i) == 0)
1.1.1.4   root     4338:            warning ("enumeration value `%s' not handled in switch",
1.1.1.7 ! root     4339:                     IDENTIFIER_POINTER (TREE_PURPOSE (v)));
1.1       root     4340:        }
1.1.1.7 ! root     4341: 
        !          4342:       free (cases_seen);
1.1       root     4343:     }
                   4344: 
                   4345:   /* Now we go the other way around; we warn if there are case
1.1.1.5   root     4346:      expressions that don't correspond to enumerators.  This can
1.1       root     4347:      occur since C and C++ don't enforce type-checking of
                   4348:      assignments to enumeration variables. */
                   4349: 
                   4350:   if (warn_switch)
                   4351:     for (n = case_stack->data.case_stmt.case_list; n; n = n->right)
                   4352:       {
                   4353:        for (chain = TYPE_VALUES (type);
                   4354:             chain && !tree_int_cst_equal (n->low, TREE_VALUE (chain));
                   4355:             chain = TREE_CHAIN (chain))
                   4356:          ;
                   4357: 
                   4358:        if (!chain)
1.1.1.5   root     4359:          {
                   4360:            if (TYPE_NAME (type) == 0)
                   4361:              warning ("case value `%d' not in enumerated type",
                   4362:                       TREE_INT_CST_LOW (n->low));
                   4363:            else
                   4364:              warning ("case value `%d' not in enumerated type `%s'",
                   4365:                       TREE_INT_CST_LOW (n->low),
                   4366:                       IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type))
                   4367:                                            == IDENTIFIER_NODE)
                   4368:                                           ? TYPE_NAME (type)
                   4369:                                           : DECL_NAME (TYPE_NAME (type))));
                   4370:          }
1.1.1.4   root     4371:        if (!tree_int_cst_equal (n->low, n->high))
                   4372:          {
                   4373:            for (chain = TYPE_VALUES (type);
                   4374:                 chain && !tree_int_cst_equal (n->high, TREE_VALUE (chain));
                   4375:                 chain = TREE_CHAIN (chain))
                   4376:              ;
                   4377: 
                   4378:            if (!chain)
1.1.1.5   root     4379:              {
                   4380:                if (TYPE_NAME (type) == 0)
                   4381:                  warning ("case value `%d' not in enumerated type",
                   4382:                           TREE_INT_CST_LOW (n->high));
                   4383:                else
                   4384:                  warning ("case value `%d' not in enumerated type `%s'",
                   4385:                           TREE_INT_CST_LOW (n->high),
                   4386:                           IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type))
                   4387:                                                == IDENTIFIER_NODE)
                   4388:                                               ? TYPE_NAME (type)
                   4389:                                               : DECL_NAME (TYPE_NAME (type))));
                   4390:              }
1.1.1.4   root     4391:          }
1.1       root     4392:       }
                   4393: 
1.1.1.5   root     4394: #if 0
                   4395:   /* ??? This optimization is disabled because it causes valid programs to
                   4396:      fail.  ANSI C does not guarantee that an expression with enum type
                   4397:      will have a value that is the same as one of the enumation literals.  */
                   4398: 
1.1       root     4399:   /* If all values were found as case labels, make one of them the default
                   4400:      label.  Thus, this switch will never fall through.  We arbitrarily pick
                   4401:      the last one to make the default since this is likely the most
                   4402:      efficient choice.  */
                   4403: 
                   4404:   if (all_values)
                   4405:     {
                   4406:       for (l = &case_stack->data.case_stmt.case_list;
                   4407:           (*l)->right != 0;
                   4408:           l = &(*l)->right)
                   4409:        ;
                   4410: 
                   4411:       case_stack->data.case_stmt.default_label = (*l)->code_label;
                   4412:       *l = 0;
                   4413:     }
1.1.1.5   root     4414: #endif /* 0 */
1.1       root     4415: }
1.1.1.6   root     4416: 
                   4417: 
                   4418: /* Check that all enumeration literals are covered by the case
                   4419:    expressions of a switch.  Also warn if there are any cases
                   4420:    that are not elements of the enumerated type.  */
1.1.1.7 ! root     4421: 
        !          4422: static void
1.1.1.6   root     4423: bc_check_for_full_enumeration_handling (type)
                   4424:      tree type;
                   4425: {
                   4426:   struct nesting *thiscase = case_stack;
                   4427:   struct case_node *c;
                   4428:   tree e;
                   4429: 
                   4430:   /* Check for enums not handled.  */
                   4431:   for (e = TYPE_VALUES (type); e; e = TREE_CHAIN (e))
                   4432:     {
                   4433:       for (c = thiscase->data.case_stmt.case_list->left;
                   4434:           c && tree_int_cst_lt (c->high, TREE_VALUE (e));
                   4435:           c = c->left)
                   4436:        ;
                   4437:       if (! (c && tree_int_cst_equal (c->low, TREE_VALUE (e))))
                   4438:        warning ("enumerated value `%s' not handled in switch",
                   4439:                 IDENTIFIER_POINTER (TREE_PURPOSE (e)));
                   4440:     }
                   4441: 
                   4442:   /* Check for cases not in the enumeration.  */
                   4443:   for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left)
                   4444:     {
                   4445:       for (e = TYPE_VALUES (type);
                   4446:           e && !tree_int_cst_equal (c->low, TREE_VALUE (e));
                   4447:           e = TREE_CHAIN (e))
                   4448:        ;
                   4449:       if (! e)
                   4450:        warning ("case value `%d' not in enumerated type `%s'",
                   4451:                 TREE_INT_CST_LOW (c->low),
                   4452:                 IDENTIFIER_POINTER (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
                   4453:                                     ? TYPE_NAME (type)
                   4454:                                     : DECL_NAME (TYPE_NAME (type))));
                   4455:     }
                   4456: }
1.1       root     4457: 
                   4458: /* Terminate a case (Pascal) or switch (C) statement
1.1.1.4   root     4459:    in which ORIG_INDEX is the expression to be tested.
1.1       root     4460:    Generate the code to test it and jump to the right place.  */
                   4461: 
                   4462: void
                   4463: expand_end_case (orig_index)
                   4464:      tree orig_index;
                   4465: {
1.1.1.6   root     4466:   tree minval, maxval, range, orig_minval;
1.1       root     4467:   rtx default_label = 0;
                   4468:   register struct case_node *n;
                   4469:   int count;
                   4470:   rtx index;
1.1.1.6   root     4471:   rtx table_label;
1.1       root     4472:   int ncases;
                   4473:   rtx *labelvec;
                   4474:   register int i;
                   4475:   rtx before_case;
                   4476:   register struct nesting *thiscase = case_stack;
1.1.1.7 ! root     4477:   tree index_expr, index_type;
1.1.1.6   root     4478:   int unsignedp;
                   4479: 
                   4480:   if (output_bytecode)
                   4481:     {
                   4482:       bc_expand_end_case (orig_index);
                   4483:       return;
                   4484:     }
                   4485: 
                   4486:   table_label = gen_label_rtx ();
                   4487:   index_expr = thiscase->data.case_stmt.index_expr;
1.1.1.7 ! root     4488:   index_type = TREE_TYPE (index_expr);
        !          4489:   unsignedp = TREE_UNSIGNED (index_type);
1.1       root     4490: 
                   4491:   do_pending_stack_adjust ();
                   4492: 
                   4493:   /* An ERROR_MARK occurs for various reasons including invalid data type.  */
1.1.1.7 ! root     4494:   if (index_type != error_mark_node)
1.1       root     4495:     {
                   4496:       /* If switch expression was an enumerated type, check that all
                   4497:         enumeration literals are covered by the cases.
                   4498:         No sense trying this if there's a default case, however.  */
                   4499: 
                   4500:       if (!thiscase->data.case_stmt.default_label
                   4501:          && TREE_CODE (TREE_TYPE (orig_index)) == ENUMERAL_TYPE
                   4502:          && TREE_CODE (index_expr) != INTEGER_CST)
                   4503:        check_for_full_enumeration_handling (TREE_TYPE (orig_index));
                   4504: 
                   4505:       /* If this is the first label, warn if any insns have been emitted.  */
                   4506:       if (thiscase->data.case_stmt.seenlabel == 0)
                   4507:        {
                   4508:          rtx insn;
                   4509:          for (insn = get_last_insn ();
                   4510:               insn != case_stack->data.case_stmt.start;
                   4511:               insn = PREV_INSN (insn))
                   4512:            if (GET_CODE (insn) != NOTE
                   4513:                && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn))!= USE))
                   4514:              {
                   4515:                warning ("unreachable code at beginning of %s",
                   4516:                         case_stack->data.case_stmt.printname);
                   4517:                break;
                   4518:              }
                   4519:        }
                   4520: 
                   4521:       /* If we don't have a default-label, create one here,
                   4522:         after the body of the switch.  */
                   4523:       if (thiscase->data.case_stmt.default_label == 0)
                   4524:        {
                   4525:          thiscase->data.case_stmt.default_label
                   4526:            = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
                   4527:          expand_label (thiscase->data.case_stmt.default_label);
                   4528:        }
                   4529:       default_label = label_rtx (thiscase->data.case_stmt.default_label);
                   4530: 
                   4531:       before_case = get_last_insn ();
                   4532: 
                   4533:       /* Simplify the case-list before we count it.  */
                   4534:       group_case_nodes (thiscase->data.case_stmt.case_list);
                   4535: 
                   4536:       /* Get upper and lower bounds of case values.
                   4537:         Also convert all the case values to the index expr's data type.  */
                   4538: 
                   4539:       count = 0;
                   4540:       for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
                   4541:        {
                   4542:          /* Check low and high label values are integers.  */
                   4543:          if (TREE_CODE (n->low) != INTEGER_CST)
                   4544:            abort ();
                   4545:          if (TREE_CODE (n->high) != INTEGER_CST)
                   4546:            abort ();
                   4547: 
1.1.1.7 ! root     4548:          n->low = convert (index_type, n->low);
        !          4549:          n->high = convert (index_type, n->high);
1.1       root     4550: 
                   4551:          /* Count the elements and track the largest and smallest
                   4552:             of them (treating them as signed even if they are not).  */
                   4553:          if (count++ == 0)
                   4554:            {
                   4555:              minval = n->low;
                   4556:              maxval = n->high;
                   4557:            }
                   4558:          else
                   4559:            {
                   4560:              if (INT_CST_LT (n->low, minval))
                   4561:                minval = n->low;
                   4562:              if (INT_CST_LT (maxval, n->high))
                   4563:                maxval = n->high;
                   4564:            }
                   4565:          /* A range counts double, since it requires two compares.  */
                   4566:          if (! tree_int_cst_equal (n->low, n->high))
                   4567:            count++;
                   4568:        }
                   4569: 
1.1.1.6   root     4570:       orig_minval = minval;
                   4571: 
1.1       root     4572:       /* Compute span of values.  */
                   4573:       if (count != 0)
1.1.1.7 ! root     4574:        range = fold (build (MINUS_EXPR, index_type, maxval, minval));
1.1       root     4575: 
1.1.1.7 ! root     4576:       if (count == 0)
1.1       root     4577:        {
                   4578:          expand_expr (index_expr, const0_rtx, VOIDmode, 0);
                   4579:          emit_queue ();
                   4580:          emit_jump (default_label);
                   4581:        }
1.1.1.6   root     4582: 
1.1       root     4583:       /* If range of values is much bigger than number of values,
                   4584:         make a sequence of conditional branches instead of a dispatch.
                   4585:         If the switch-index is a constant, do it this way
                   4586:         because we can optimize it.  */
1.1.1.4   root     4587: 
                   4588: #ifndef CASE_VALUES_THRESHOLD
1.1       root     4589: #ifdef HAVE_casesi
1.1.1.4   root     4590: #define CASE_VALUES_THRESHOLD (HAVE_casesi ? 4 : 5)
1.1       root     4591: #else
1.1.1.4   root     4592:       /* If machine does not have a case insn that compares the
                   4593:         bounds, this means extra overhead for dispatch tables
                   4594:         which raises the threshold for using them.  */
                   4595: #define CASE_VALUES_THRESHOLD 5
                   4596: #endif /* HAVE_casesi */
                   4597: #endif /* CASE_VALUES_THRESHOLD */
                   4598: 
                   4599:       else if (TREE_INT_CST_HIGH (range) != 0
                   4600:               || count < CASE_VALUES_THRESHOLD
                   4601:               || ((unsigned HOST_WIDE_INT) (TREE_INT_CST_LOW (range))
                   4602:                   > 10 * count)
1.1       root     4603:               || TREE_CODE (index_expr) == INTEGER_CST
1.1.1.2   root     4604:               /* These will reduce to a constant.  */
1.1       root     4605:               || (TREE_CODE (index_expr) == CALL_EXPR
                   4606:                   && TREE_CODE (TREE_OPERAND (index_expr, 0)) == ADDR_EXPR
                   4607:                   && TREE_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == FUNCTION_DECL
1.1.1.2   root     4608:                   && DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == BUILT_IN_CLASSIFY_TYPE)
                   4609:               || (TREE_CODE (index_expr) == COMPOUND_EXPR
                   4610:                   && TREE_CODE (TREE_OPERAND (index_expr, 1)) == INTEGER_CST))
1.1       root     4611:        {
1.1.1.4   root     4612:          index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
1.1       root     4613: 
                   4614:          /* If the index is a short or char that we do not have
                   4615:             an insn to handle comparisons directly, convert it to
                   4616:             a full integer now, rather than letting each comparison
                   4617:             generate the conversion.  */
                   4618: 
                   4619:          if (GET_MODE_CLASS (GET_MODE (index)) == MODE_INT
                   4620:              && (cmp_optab->handlers[(int) GET_MODE(index)].insn_code
                   4621:                  == CODE_FOR_nothing))
                   4622:            {
                   4623:              enum machine_mode wider_mode;
                   4624:              for (wider_mode = GET_MODE (index); wider_mode != VOIDmode;
                   4625:                   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
                   4626:                if (cmp_optab->handlers[(int) wider_mode].insn_code
                   4627:                    != CODE_FOR_nothing)
                   4628:                  {
                   4629:                    index = convert_to_mode (wider_mode, index, unsignedp);
                   4630:                    break;
                   4631:                  }
                   4632:            }
                   4633: 
                   4634:          emit_queue ();
                   4635:          do_pending_stack_adjust ();
                   4636: 
                   4637:          index = protect_from_queue (index, 0);
                   4638:          if (GET_CODE (index) == MEM)
                   4639:            index = copy_to_reg (index);
                   4640:          if (GET_CODE (index) == CONST_INT
                   4641:              || TREE_CODE (index_expr) == INTEGER_CST)
                   4642:            {
                   4643:              /* Make a tree node with the proper constant value
                   4644:                 if we don't already have one.  */
                   4645:              if (TREE_CODE (index_expr) != INTEGER_CST)
                   4646:                {
                   4647:                  index_expr
                   4648:                    = build_int_2 (INTVAL (index),
1.1.1.7 ! root     4649:                                   unsignedp || INTVAL (index) >= 0 ? 0 : -1);
        !          4650:                  index_expr = convert (index_type, index_expr);
1.1       root     4651:                }
                   4652: 
                   4653:              /* For constant index expressions we need only
                   4654:                 issue a unconditional branch to the appropriate
                   4655:                 target code.  The job of removing any unreachable
                   4656:                 code is left to the optimisation phase if the
                   4657:                 "-O" option is specified.  */
1.1.1.7 ! root     4658:              for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
        !          4659:                if (! tree_int_cst_lt (index_expr, n->low)
        !          4660:                    && ! tree_int_cst_lt (n->high, index_expr))
        !          4661:                  break;
        !          4662: 
1.1       root     4663:              if (n)
                   4664:                emit_jump (label_rtx (n->code_label));
                   4665:              else
                   4666:                emit_jump (default_label);
                   4667:            }
                   4668:          else
                   4669:            {
                   4670:              /* If the index expression is not constant we generate
                   4671:                 a binary decision tree to select the appropriate
                   4672:                 target code.  This is done as follows:
                   4673: 
                   4674:                 The list of cases is rearranged into a binary tree,
                   4675:                 nearly optimal assuming equal probability for each case.
                   4676: 
                   4677:                 The tree is transformed into RTL, eliminating
                   4678:                 redundant test conditions at the same time.
                   4679: 
                   4680:                 If program flow could reach the end of the
                   4681:                 decision tree an unconditional jump to the
                   4682:                 default code is emitted.  */
                   4683: 
                   4684:              use_cost_table
                   4685:                = (TREE_CODE (TREE_TYPE (orig_index)) != ENUMERAL_TYPE
                   4686:                   && estimate_case_costs (thiscase->data.case_stmt.case_list));
1.1.1.4   root     4687:              balance_case_nodes (&thiscase->data.case_stmt.case_list, 
                   4688:                                  NULL_PTR);
1.1       root     4689:              emit_case_nodes (index, thiscase->data.case_stmt.case_list,
1.1.1.7 ! root     4690:                               default_label, index_type);
1.1       root     4691:              emit_jump_if_reachable (default_label);
                   4692:            }
                   4693:        }
                   4694:       else
                   4695:        {
                   4696:          int win = 0;
                   4697: #ifdef HAVE_casesi
                   4698:          if (HAVE_casesi)
                   4699:            {
1.1.1.3   root     4700:              enum machine_mode index_mode = SImode;
                   4701:              int index_bits = GET_MODE_BITSIZE (index_mode);
1.1.1.7 ! root     4702:              rtx op1, op2;
        !          4703:              enum machine_mode op_mode;
1.1.1.3   root     4704: 
1.1       root     4705:              /* Convert the index to SImode.  */
1.1.1.7 ! root     4706:              if (GET_MODE_BITSIZE (TYPE_MODE (index_type))
1.1.1.3   root     4707:                  > GET_MODE_BITSIZE (index_mode))
1.1       root     4708:                {
1.1.1.7 ! root     4709:                  enum machine_mode omode = TYPE_MODE (index_type);
1.1.1.4   root     4710:                  rtx rangertx = expand_expr (range, NULL_RTX, VOIDmode, 0);
1.1.1.3   root     4711: 
                   4712:                  /* We must handle the endpoints in the original mode.  */
1.1.1.7 ! root     4713:                  index_expr = build (MINUS_EXPR, index_type,
1.1       root     4714:                                      index_expr, minval);
                   4715:                  minval = integer_zero_node;
1.1.1.4   root     4716:                  index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
1.1.1.6   root     4717:                  emit_cmp_insn (rangertx, index, LTU, NULL_RTX, omode, 1, 0);
1.1.1.3   root     4718:                  emit_jump_insn (gen_bltu (default_label));
                   4719:                  /* Now we can safely truncate.  */
                   4720:                  index = convert_to_mode (index_mode, index, 0);
                   4721:                }
                   4722:              else
                   4723:                {
1.1.1.7 ! root     4724:                  if (TYPE_MODE (index_type) != index_mode)
        !          4725:                    {
        !          4726:                      index_expr = convert (type_for_size (index_bits, 0),
        !          4727:                                            index_expr);
        !          4728:                      index_type = TREE_TYPE (index_expr);
        !          4729:                    }
        !          4730: 
1.1.1.4   root     4731:                  index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
1.1       root     4732:                }
                   4733:              emit_queue ();
                   4734:              index = protect_from_queue (index, 0);
                   4735:              do_pending_stack_adjust ();
                   4736: 
1.1.1.7 ! root     4737:              op_mode = insn_operand_mode[(int)CODE_FOR_casesi][0];
        !          4738:              if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][0])
        !          4739:                  (index, op_mode))
        !          4740:                index = copy_to_mode_reg (op_mode, index);
        !          4741: 
        !          4742:              op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0);
        !          4743: 
        !          4744:              op_mode = insn_operand_mode[(int)CODE_FOR_casesi][1];
        !          4745:              if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][1])
        !          4746:                  (op1, op_mode))
        !          4747:                op1 = copy_to_mode_reg (op_mode, op1);
        !          4748: 
        !          4749:              op2 = expand_expr (range, NULL_RTX, VOIDmode, 0);
        !          4750: 
        !          4751:              op_mode = insn_operand_mode[(int)CODE_FOR_casesi][2];
        !          4752:              if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][2])
        !          4753:                  (op2, op_mode))
        !          4754:                op2 = copy_to_mode_reg (op_mode, op2);
        !          4755: 
        !          4756:              emit_jump_insn (gen_casesi (index, op1, op2,
1.1       root     4757:                                          table_label, default_label));
                   4758:              win = 1;
                   4759:            }
                   4760: #endif
                   4761: #ifdef HAVE_tablejump
                   4762:          if (! win && HAVE_tablejump)
                   4763:            {
                   4764:              index_expr = convert (thiscase->data.case_stmt.nominal_type,
1.1.1.7 ! root     4765:                                    fold (build (MINUS_EXPR, index_type,
1.1.1.2   root     4766:                                                 index_expr, minval)));
1.1.1.7 ! root     4767:              index_type = TREE_TYPE (index_expr);
1.1.1.4   root     4768:              index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
1.1       root     4769:              emit_queue ();
                   4770:              index = protect_from_queue (index, 0);
                   4771:              do_pending_stack_adjust ();
                   4772: 
1.1.1.7 ! root     4773:              do_tablejump (index, TYPE_MODE (index_type),
1.1.1.4   root     4774:                            expand_expr (range, NULL_RTX, VOIDmode, 0),
1.1       root     4775:                            table_label, default_label);
                   4776:              win = 1;
                   4777:            }
                   4778: #endif
                   4779:          if (! win)
                   4780:            abort ();
                   4781: 
                   4782:          /* Get table of labels to jump to, in order of case index.  */
                   4783: 
                   4784:          ncases = TREE_INT_CST_LOW (range) + 1;
                   4785:          labelvec = (rtx *) alloca (ncases * sizeof (rtx));
1.1.1.7 ! root     4786:          bzero ((char *) labelvec, ncases * sizeof (rtx));
1.1       root     4787: 
                   4788:          for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
                   4789:            {
1.1.1.4   root     4790:              register HOST_WIDE_INT i
1.1.1.6   root     4791:                = TREE_INT_CST_LOW (n->low) - TREE_INT_CST_LOW (orig_minval);
1.1       root     4792: 
                   4793:              while (1)
                   4794:                {
                   4795:                  labelvec[i]
                   4796:                    = gen_rtx (LABEL_REF, Pmode, label_rtx (n->code_label));
1.1.1.6   root     4797:                  if (i + TREE_INT_CST_LOW (orig_minval)
1.1       root     4798:                      == TREE_INT_CST_LOW (n->high))
                   4799:                    break;
                   4800:                  i++;
                   4801:                }
                   4802:            }
                   4803: 
                   4804:          /* Fill in the gaps with the default.  */
                   4805:          for (i = 0; i < ncases; i++)
                   4806:            if (labelvec[i] == 0)
                   4807:              labelvec[i] = gen_rtx (LABEL_REF, Pmode, default_label);
                   4808: 
                   4809:          /* Output the table */
                   4810:          emit_label (table_label);
                   4811: 
                   4812:          /* This would be a lot nicer if CASE_VECTOR_PC_RELATIVE
1.1.1.4   root     4813:             were an expression, instead of an #ifdef/#ifndef.  */
1.1       root     4814:          if (
                   4815: #ifdef CASE_VECTOR_PC_RELATIVE
                   4816:              1 ||
                   4817: #endif
                   4818:              flag_pic)
                   4819:            emit_jump_insn (gen_rtx (ADDR_DIFF_VEC, CASE_VECTOR_MODE,
                   4820:                                     gen_rtx (LABEL_REF, Pmode, table_label),
                   4821:                                     gen_rtvec_v (ncases, labelvec)));
                   4822:          else
                   4823:            emit_jump_insn (gen_rtx (ADDR_VEC, CASE_VECTOR_MODE,
                   4824:                                     gen_rtvec_v (ncases, labelvec)));
                   4825: 
                   4826:          /* If the case insn drops through the table,
                   4827:             after the table we must jump to the default-label.
                   4828:             Otherwise record no drop-through after the table.  */
                   4829: #ifdef CASE_DROPS_THROUGH
                   4830:          emit_jump (default_label);
                   4831: #else
                   4832:          emit_barrier ();
                   4833: #endif
                   4834:        }
                   4835: 
1.1.1.3   root     4836:       before_case = squeeze_notes (NEXT_INSN (before_case), get_last_insn ());
                   4837:       reorder_insns (before_case, get_last_insn (),
1.1       root     4838:                     thiscase->data.case_stmt.start);
                   4839:     }
1.1.1.7 ! root     4840: 
1.1       root     4841:   if (thiscase->exit_label)
                   4842:     emit_label (thiscase->exit_label);
                   4843: 
                   4844:   POPSTACK (case_stack);
                   4845: 
                   4846:   free_temp_slots ();
                   4847: }
                   4848: 
1.1.1.6   root     4849: 
                   4850: /* Terminate a case statement.  EXPR is the original index
                   4851:    expression.  */
1.1.1.7 ! root     4852: 
        !          4853: static void
1.1.1.6   root     4854: bc_expand_end_case (expr)
                   4855:      tree expr;
                   4856: {
                   4857:   struct nesting *thiscase = case_stack;
                   4858:   enum bytecode_opcode opcode;
                   4859:   struct bc_label *jump_label;
                   4860:   struct case_node *c;
                   4861: 
                   4862:   bc_emit_bytecode (jump);
                   4863:   bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->exit_label));
                   4864: 
                   4865: #ifdef DEBUG_PRINT_CODE
                   4866:   fputc ('\n', stderr);
                   4867: #endif
                   4868: 
                   4869:   /* Now that the size of the jump table is known, emit the actual
                   4870:      indexed jump instruction.  */
                   4871:   bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscase->data.case_stmt.skip_label));
                   4872: 
                   4873:   opcode = TYPE_MODE (thiscase->data.case_stmt.nominal_type) == SImode
                   4874:     ? TREE_UNSIGNED (thiscase->data.case_stmt.nominal_type) ? caseSU : caseSI
                   4875:       : TREE_UNSIGNED (thiscase->data.case_stmt.nominal_type) ? caseDU : caseDI;
                   4876: 
                   4877:   bc_emit_bytecode (opcode);
                   4878: 
                   4879:   /* Now emit the case instructions literal arguments, in order.
                   4880:      In addition to the value on the stack, it uses:
                   4881:      1.  The address of the jump table.
                   4882:      2.  The size of the jump table.
                   4883:      3.  The default label.  */
                   4884: 
                   4885:   jump_label = bc_get_bytecode_label ();
                   4886:   bc_emit_bytecode_labelref (jump_label);
                   4887:   bc_emit_bytecode_const ((char *) &thiscase->data.case_stmt.num_ranges,
                   4888:                          sizeof thiscase->data.case_stmt.num_ranges);
                   4889: 
                   4890:   if (thiscase->data.case_stmt.default_label)
                   4891:     bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (thiscase->data.case_stmt.default_label)));
                   4892:   else
                   4893:     bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->exit_label));
                   4894: 
                   4895:   /* Output the jump table.  */
                   4896: 
                   4897:   bc_align_bytecode (3 /* PTR_ALIGN */);
                   4898:   bc_emit_bytecode_labeldef (jump_label);
                   4899: 
                   4900:   if (TYPE_MODE (thiscase->data.case_stmt.nominal_type) == SImode)
                   4901:     for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left)
                   4902:       {
                   4903:        opcode = TREE_INT_CST_LOW (c->low);
                   4904:        bc_emit_bytecode_const ((char *) &opcode, sizeof opcode);
                   4905: 
                   4906:        opcode = TREE_INT_CST_LOW (c->high);
                   4907:        bc_emit_bytecode_const ((char *) &opcode, sizeof opcode);
                   4908: 
                   4909:        bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (c->code_label)));
                   4910:       }
                   4911:   else
                   4912:     if (TYPE_MODE (thiscase->data.case_stmt.nominal_type) == DImode)
                   4913:       for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left)
                   4914:        {
                   4915:          bc_emit_bytecode_DI_const (c->low);
                   4916:          bc_emit_bytecode_DI_const (c->high);
                   4917: 
                   4918:          bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (c->code_label)));
                   4919:        }
                   4920:     else
                   4921:       /* Bad mode */
                   4922:       abort ();
                   4923: 
                   4924:     
                   4925:   bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscase->exit_label));
                   4926: 
                   4927:   /* Possibly issue enumeration warnings.  */
                   4928: 
                   4929:   if (!thiscase->data.case_stmt.default_label
                   4930:       && TREE_CODE (TREE_TYPE (expr)) == ENUMERAL_TYPE
                   4931:       && TREE_CODE (expr) != INTEGER_CST
                   4932:       && warn_switch)
                   4933:     check_for_full_enumeration_handling (TREE_TYPE (expr));
                   4934: 
                   4935: 
                   4936: #ifdef DEBUG_PRINT_CODE
                   4937:   fputc ('\n', stderr);
                   4938: #endif
                   4939: 
                   4940:   POPSTACK (case_stack);
                   4941: }
                   4942: 
                   4943: 
                   4944: /* Return unique bytecode ID. */
1.1.1.7 ! root     4945: 
1.1.1.6   root     4946: int 
                   4947: bc_new_uid ()
                   4948: {
                   4949:   static int bc_uid = 0;
                   4950: 
                   4951:   return (++bc_uid);
                   4952: }
                   4953: 
1.1       root     4954: /* Generate code to jump to LABEL if OP1 and OP2 are equal.  */
                   4955: 
                   4956: static void
                   4957: do_jump_if_equal (op1, op2, label, unsignedp)
                   4958:      rtx op1, op2, label;
                   4959:      int unsignedp;
                   4960: {
                   4961:   if (GET_CODE (op1) == CONST_INT
                   4962:       && GET_CODE (op2) == CONST_INT)
                   4963:     {
                   4964:       if (INTVAL (op1) == INTVAL (op2))
                   4965:        emit_jump (label);
                   4966:     }
                   4967:   else
                   4968:     {
                   4969:       enum machine_mode mode = GET_MODE (op1);
                   4970:       if (mode == VOIDmode)
                   4971:        mode = GET_MODE (op2);
1.1.1.4   root     4972:       emit_cmp_insn (op1, op2, EQ, NULL_RTX, mode, unsignedp, 0);
1.1       root     4973:       emit_jump_insn (gen_beq (label));
                   4974:     }
                   4975: }
                   4976: 
                   4977: /* Not all case values are encountered equally.  This function
                   4978:    uses a heuristic to weight case labels, in cases where that
                   4979:    looks like a reasonable thing to do.
                   4980: 
                   4981:    Right now, all we try to guess is text, and we establish the
                   4982:    following weights:
                   4983: 
                   4984:        chars above space:      16
                   4985:        digits:                 16
                   4986:        default:                12
                   4987:        space, punct:           8
                   4988:        tab:                    4
                   4989:        newline:                2
                   4990:        other "\" chars:        1
                   4991:        remaining chars:        0
                   4992: 
                   4993:    If we find any cases in the switch that are not either -1 or in the range
                   4994:    of valid ASCII characters, or are control characters other than those
                   4995:    commonly used with "\", don't treat this switch scanning text.
                   4996: 
                   4997:    Return 1 if these nodes are suitable for cost estimation, otherwise
                   4998:    return 0.  */
                   4999: 
                   5000: static int
                   5001: estimate_case_costs (node)
                   5002:      case_node_ptr node;
                   5003: {
                   5004:   tree min_ascii = build_int_2 (-1, -1);
                   5005:   tree max_ascii = convert (TREE_TYPE (node->high), build_int_2 (127, 0));
                   5006:   case_node_ptr n;
                   5007:   int i;
                   5008: 
                   5009:   /* If we haven't already made the cost table, make it now.  Note that the
                   5010:      lower bound of the table is -1, not zero.  */
                   5011: 
                   5012:   if (cost_table == NULL)
                   5013:     {
                   5014:       cost_table = ((short *) xmalloc (129 * sizeof (short))) + 1;
1.1.1.7 ! root     5015:       bzero ((char *) (cost_table - 1), 129 * sizeof (short));
1.1       root     5016: 
                   5017:       for (i = 0; i < 128; i++)
                   5018:        {
                   5019:          if (isalnum (i))
                   5020:            cost_table[i] = 16;
                   5021:          else if (ispunct (i))
                   5022:            cost_table[i] = 8;
                   5023:          else if (iscntrl (i))
                   5024:            cost_table[i] = -1;
                   5025:        }
                   5026: 
                   5027:       cost_table[' '] = 8;
                   5028:       cost_table['\t'] = 4;
                   5029:       cost_table['\0'] = 4;
                   5030:       cost_table['\n'] = 2;
                   5031:       cost_table['\f'] = 1;
                   5032:       cost_table['\v'] = 1;
                   5033:       cost_table['\b'] = 1;
                   5034:     }
                   5035: 
                   5036:   /* See if all the case expressions look like text.  It is text if the
                   5037:      constant is >= -1 and the highest constant is <= 127.  Do all comparisons
                   5038:      as signed arithmetic since we don't want to ever access cost_table with a
                   5039:      value less than -1.  Also check that none of the constants in a range
                   5040:      are strange control characters.  */
                   5041: 
                   5042:   for (n = node; n; n = n->right)
                   5043:     {
                   5044:       if ((INT_CST_LT (n->low, min_ascii)) || INT_CST_LT (max_ascii, n->high))
                   5045:        return 0;
                   5046: 
                   5047:       for (i = TREE_INT_CST_LOW (n->low); i <= TREE_INT_CST_LOW (n->high); i++)
                   5048:        if (cost_table[i] < 0)
                   5049:          return 0;
                   5050:     }
                   5051: 
                   5052:   /* All interesting values are within the range of interesting
                   5053:      ASCII characters.  */
                   5054:   return 1;
                   5055: }
                   5056: 
                   5057: /* Scan an ordered list of case nodes
                   5058:    combining those with consecutive values or ranges.
                   5059: 
                   5060:    Eg. three separate entries 1: 2: 3: become one entry 1..3:  */
                   5061: 
                   5062: static void
                   5063: group_case_nodes (head)
                   5064:      case_node_ptr head;
                   5065: {
                   5066:   case_node_ptr node = head;
                   5067: 
                   5068:   while (node)
                   5069:     {
                   5070:       rtx lb = next_real_insn (label_rtx (node->code_label));
                   5071:       case_node_ptr np = node;
                   5072: 
                   5073:       /* Try to group the successors of NODE with NODE.  */
                   5074:       while (((np = np->right) != 0)
                   5075:             /* Do they jump to the same place?  */
                   5076:             && next_real_insn (label_rtx (np->code_label)) == lb
                   5077:             /* Are their ranges consecutive?  */
                   5078:             && tree_int_cst_equal (np->low,
                   5079:                                    fold (build (PLUS_EXPR,
                   5080:                                                 TREE_TYPE (node->high),
                   5081:                                                 node->high,
                   5082:                                                 integer_one_node)))
                   5083:             /* An overflow is not consecutive.  */
                   5084:             && tree_int_cst_lt (node->high,
                   5085:                                 fold (build (PLUS_EXPR,
                   5086:                                              TREE_TYPE (node->high),
                   5087:                                              node->high,
                   5088:                                              integer_one_node))))
                   5089:        {
                   5090:          node->high = np->high;
                   5091:        }
                   5092:       /* NP is the first node after NODE which can't be grouped with it.
                   5093:         Delete the nodes in between, and move on to that node.  */
                   5094:       node->right = np;
                   5095:       node = np;
                   5096:     }
                   5097: }
                   5098: 
                   5099: /* Take an ordered list of case nodes
                   5100:    and transform them into a near optimal binary tree,
1.1.1.3   root     5101:    on the assumption that any target code selection value is as
1.1       root     5102:    likely as any other.
                   5103: 
                   5104:    The transformation is performed by splitting the ordered
                   5105:    list into two equal sections plus a pivot.  The parts are
                   5106:    then attached to the pivot as left and right branches.  Each
                   5107:    branch is is then transformed recursively.  */
                   5108: 
                   5109: static void
                   5110: balance_case_nodes (head, parent)
                   5111:      case_node_ptr *head;
                   5112:      case_node_ptr parent;
                   5113: {
                   5114:   register case_node_ptr np;
                   5115: 
                   5116:   np = *head;
                   5117:   if (np)
                   5118:     {
                   5119:       int cost = 0;
                   5120:       int i = 0;
                   5121:       int ranges = 0;
                   5122:       register case_node_ptr *npp;
                   5123:       case_node_ptr left;
                   5124: 
                   5125:       /* Count the number of entries on branch.  Also count the ranges.  */
                   5126: 
                   5127:       while (np)
                   5128:        {
                   5129:          if (!tree_int_cst_equal (np->low, np->high))
                   5130:            {
                   5131:              ranges++;
                   5132:              if (use_cost_table)
                   5133:                cost += cost_table[TREE_INT_CST_LOW (np->high)];
                   5134:            }
                   5135: 
                   5136:          if (use_cost_table)
                   5137:            cost += cost_table[TREE_INT_CST_LOW (np->low)];
                   5138: 
                   5139:          i++;
                   5140:          np = np->right;
                   5141:        }
                   5142: 
                   5143:       if (i > 2)
                   5144:        {
                   5145:          /* Split this list if it is long enough for that to help.  */
                   5146:          npp = head;
                   5147:          left = *npp;
                   5148:          if (use_cost_table)
                   5149:            {
                   5150:              /* Find the place in the list that bisects the list's total cost,
                   5151:                 Here I gets half the total cost.  */
                   5152:              int n_moved = 0;
                   5153:              i = (cost + 1) / 2;
                   5154:              while (1)
                   5155:                {
                   5156:                  /* Skip nodes while their cost does not reach that amount.  */
                   5157:                  if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
                   5158:                    i -= cost_table[TREE_INT_CST_LOW ((*npp)->high)];
                   5159:                  i -= cost_table[TREE_INT_CST_LOW ((*npp)->low)];
                   5160:                  if (i <= 0)
                   5161:                    break;
                   5162:                  npp = &(*npp)->right;
                   5163:                  n_moved += 1;
                   5164:                }
                   5165:              if (n_moved == 0)
                   5166:                {
                   5167:                  /* Leave this branch lopsided, but optimize left-hand
                   5168:                     side and fill in `parent' fields for right-hand side.  */
                   5169:                  np = *head;
                   5170:                  np->parent = parent;
                   5171:                  balance_case_nodes (&np->left, np);
                   5172:                  for (; np->right; np = np->right)
                   5173:                    np->right->parent = np;
                   5174:                  return;
                   5175:                }
                   5176:            }
                   5177:          /* If there are just three nodes, split at the middle one.  */
                   5178:          else if (i == 3)
                   5179:            npp = &(*npp)->right;
                   5180:          else
                   5181:            {
                   5182:              /* Find the place in the list that bisects the list's total cost,
                   5183:                 where ranges count as 2.
                   5184:                 Here I gets half the total cost.  */
                   5185:              i = (i + ranges + 1) / 2;
                   5186:              while (1)
                   5187:                {
                   5188:                  /* Skip nodes while their cost does not reach that amount.  */
                   5189:                  if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
                   5190:                    i--;
                   5191:                  i--;
                   5192:                  if (i <= 0)
                   5193:                    break;
                   5194:                  npp = &(*npp)->right;
                   5195:                }
                   5196:            }
                   5197:          *head = np = *npp;
                   5198:          *npp = 0;
                   5199:          np->parent = parent;
                   5200:          np->left = left;
                   5201: 
                   5202:          /* Optimize each of the two split parts.  */
                   5203:          balance_case_nodes (&np->left, np);
                   5204:          balance_case_nodes (&np->right, np);
                   5205:        }
                   5206:       else
                   5207:        {
                   5208:          /* Else leave this branch as one level,
                   5209:             but fill in `parent' fields.  */
                   5210:          np = *head;
                   5211:          np->parent = parent;
                   5212:          for (; np->right; np = np->right)
                   5213:            np->right->parent = np;
                   5214:        }
                   5215:     }
                   5216: }
                   5217: 
                   5218: /* Search the parent sections of the case node tree
                   5219:    to see if a test for the lower bound of NODE would be redundant.
                   5220:    INDEX_TYPE is the type of the index expression.
                   5221: 
                   5222:    The instructions to generate the case decision tree are
                   5223:    output in the same order as nodes are processed so it is
                   5224:    known that if a parent node checks the range of the current
                   5225:    node minus one that the current node is bounded at its lower
                   5226:    span.  Thus the test would be redundant.  */
                   5227: 
                   5228: static int
                   5229: node_has_low_bound (node, index_type)
                   5230:      case_node_ptr node;
                   5231:      tree index_type;
                   5232: {
                   5233:   tree low_minus_one;
                   5234:   case_node_ptr pnode;
                   5235: 
                   5236:   /* If the lower bound of this node is the lowest value in the index type,
                   5237:      we need not test it.  */
                   5238: 
                   5239:   if (tree_int_cst_equal (node->low, TYPE_MIN_VALUE (index_type)))
                   5240:     return 1;
                   5241: 
                   5242:   /* If this node has a left branch, the value at the left must be less
                   5243:      than that at this node, so it cannot be bounded at the bottom and
                   5244:      we need not bother testing any further.  */
                   5245: 
                   5246:   if (node->left)
                   5247:     return 0;
                   5248: 
                   5249:   low_minus_one = fold (build (MINUS_EXPR, TREE_TYPE (node->low),
                   5250:                               node->low, integer_one_node));
                   5251: 
                   5252:   /* If the subtraction above overflowed, we can't verify anything.
                   5253:      Otherwise, look for a parent that tests our value - 1.  */
                   5254: 
                   5255:   if (! tree_int_cst_lt (low_minus_one, node->low))
                   5256:     return 0;
                   5257: 
                   5258:   for (pnode = node->parent; pnode; pnode = pnode->parent)
                   5259:     if (tree_int_cst_equal (low_minus_one, pnode->high))
                   5260:       return 1;
                   5261: 
                   5262:   return 0;
                   5263: }
                   5264: 
                   5265: /* Search the parent sections of the case node tree
                   5266:    to see if a test for the upper bound of NODE would be redundant.
                   5267:    INDEX_TYPE is the type of the index expression.
                   5268: 
                   5269:    The instructions to generate the case decision tree are
                   5270:    output in the same order as nodes are processed so it is
                   5271:    known that if a parent node checks the range of the current
                   5272:    node plus one that the current node is bounded at its upper
                   5273:    span.  Thus the test would be redundant.  */
                   5274: 
                   5275: static int
                   5276: node_has_high_bound (node, index_type)
                   5277:      case_node_ptr node;
                   5278:      tree index_type;
                   5279: {
                   5280:   tree high_plus_one;
                   5281:   case_node_ptr pnode;
                   5282: 
                   5283:   /* If the upper bound of this node is the highest value in the type
                   5284:      of the index expression, we need not test against it.  */
                   5285: 
                   5286:   if (tree_int_cst_equal (node->high, TYPE_MAX_VALUE (index_type)))
                   5287:     return 1;
                   5288: 
                   5289:   /* If this node has a right branch, the value at the right must be greater
                   5290:      than that at this node, so it cannot be bounded at the top and
                   5291:      we need not bother testing any further.  */
                   5292: 
                   5293:   if (node->right)
                   5294:     return 0;
                   5295: 
                   5296:   high_plus_one = fold (build (PLUS_EXPR, TREE_TYPE (node->high),
                   5297:                               node->high, integer_one_node));
                   5298: 
                   5299:   /* If the addition above overflowed, we can't verify anything.
                   5300:      Otherwise, look for a parent that tests our value + 1.  */
                   5301: 
                   5302:   if (! tree_int_cst_lt (node->high, high_plus_one))
                   5303:     return 0;
                   5304: 
                   5305:   for (pnode = node->parent; pnode; pnode = pnode->parent)
                   5306:     if (tree_int_cst_equal (high_plus_one, pnode->low))
                   5307:       return 1;
                   5308: 
                   5309:   return 0;
                   5310: }
                   5311: 
                   5312: /* Search the parent sections of the
                   5313:    case node tree to see if both tests for the upper and lower
                   5314:    bounds of NODE would be redundant.  */
                   5315: 
                   5316: static int
                   5317: node_is_bounded (node, index_type)
                   5318:      case_node_ptr node;
                   5319:      tree index_type;
                   5320: {
                   5321:   return (node_has_low_bound (node, index_type)
                   5322:          && node_has_high_bound (node, index_type));
                   5323: }
                   5324: 
                   5325: /*  Emit an unconditional jump to LABEL unless it would be dead code.  */
                   5326: 
                   5327: static void
                   5328: emit_jump_if_reachable (label)
                   5329:      rtx label;
                   5330: {
                   5331:   if (GET_CODE (get_last_insn ()) != BARRIER)
                   5332:     emit_jump (label);
                   5333: }
                   5334: 
                   5335: /* Emit step-by-step code to select a case for the value of INDEX.
                   5336:    The thus generated decision tree follows the form of the
                   5337:    case-node binary tree NODE, whose nodes represent test conditions.
                   5338:    INDEX_TYPE is the type of the index of the switch.
                   5339: 
                   5340:    Care is taken to prune redundant tests from the decision tree
                   5341:    by detecting any boundary conditions already checked by
                   5342:    emitted rtx.  (See node_has_high_bound, node_has_low_bound
                   5343:    and node_is_bounded, above.)
                   5344: 
                   5345:    Where the test conditions can be shown to be redundant we emit
                   5346:    an unconditional jump to the target code.  As a further
                   5347:    optimization, the subordinates of a tree node are examined to
                   5348:    check for bounded nodes.  In this case conditional and/or
                   5349:    unconditional jumps as a result of the boundary check for the
                   5350:    current node are arranged to target the subordinates associated
                   5351:    code for out of bound conditions on the current node node.
                   5352: 
1.1.1.4   root     5353:    We can assume that when control reaches the code generated here,
1.1       root     5354:    the index value has already been compared with the parents
                   5355:    of this node, and determined to be on the same side of each parent
                   5356:    as this node is.  Thus, if this node tests for the value 51,
                   5357:    and a parent tested for 52, we don't need to consider
                   5358:    the possibility of a value greater than 51.  If another parent
                   5359:    tests for the value 50, then this node need not test anything.  */
                   5360: 
                   5361: static void
                   5362: emit_case_nodes (index, node, default_label, index_type)
                   5363:      rtx index;
                   5364:      case_node_ptr node;
                   5365:      rtx default_label;
                   5366:      tree index_type;
                   5367: {
                   5368:   /* If INDEX has an unsigned type, we must make unsigned branches.  */
                   5369:   int unsignedp = TREE_UNSIGNED (index_type);
                   5370:   typedef rtx rtx_function ();
                   5371:   rtx_function *gen_bgt_pat = unsignedp ? gen_bgtu : gen_bgt;
                   5372:   rtx_function *gen_bge_pat = unsignedp ? gen_bgeu : gen_bge;
                   5373:   rtx_function *gen_blt_pat = unsignedp ? gen_bltu : gen_blt;
                   5374:   rtx_function *gen_ble_pat = unsignedp ? gen_bleu : gen_ble;
                   5375:   enum machine_mode mode = GET_MODE (index);
                   5376: 
                   5377:   /* See if our parents have already tested everything for us.
                   5378:      If they have, emit an unconditional jump for this node.  */
                   5379:   if (node_is_bounded (node, index_type))
                   5380:     emit_jump (label_rtx (node->code_label));
                   5381: 
                   5382:   else if (tree_int_cst_equal (node->low, node->high))
                   5383:     {
                   5384:       /* Node is single valued.  First see if the index expression matches
                   5385:         this node and then check our children, if any. */
                   5386: 
1.1.1.4   root     5387:       do_jump_if_equal (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
1.1       root     5388:                        label_rtx (node->code_label), unsignedp);
                   5389: 
                   5390:       if (node->right != 0 && node->left != 0)
                   5391:        {
                   5392:          /* This node has children on both sides.
                   5393:             Dispatch to one side or the other
                   5394:             by comparing the index value with this node's value.
                   5395:             If one subtree is bounded, check that one first,
                   5396:             so we can avoid real branches in the tree.  */
                   5397: 
                   5398:          if (node_is_bounded (node->right, index_type))
                   5399:            {
1.1.1.4   root     5400:              emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
                   5401:                                                 VOIDmode, 0),
                   5402:                             GT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5403: 
                   5404:              emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
                   5405:              emit_case_nodes (index, node->left, default_label, index_type);
                   5406:            }
                   5407: 
                   5408:          else if (node_is_bounded (node->left, index_type))
                   5409:            {
1.1.1.4   root     5410:              emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
1.1       root     5411:                                                 VOIDmode, 0),
1.1.1.4   root     5412:                             LT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5413:              emit_jump_insn ((*gen_blt_pat) (label_rtx (node->left->code_label)));
                   5414:              emit_case_nodes (index, node->right, default_label, index_type);
                   5415:            }
                   5416: 
                   5417:          else
                   5418:            {
                   5419:              /* Neither node is bounded.  First distinguish the two sides;
                   5420:                 then emit the code for one side at a time.  */
                   5421: 
                   5422:              tree test_label
                   5423:                = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
                   5424: 
                   5425:              /* See if the value is on the right.  */
1.1.1.4   root     5426:              emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
1.1       root     5427:                                                 VOIDmode, 0),
1.1.1.4   root     5428:                             GT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5429:              emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label)));
                   5430: 
                   5431:              /* Value must be on the left.
                   5432:                 Handle the left-hand subtree.  */
                   5433:              emit_case_nodes (index, node->left, default_label, index_type);
                   5434:              /* If left-hand subtree does nothing,
                   5435:                 go to default.  */
                   5436:              emit_jump_if_reachable (default_label);
                   5437: 
                   5438:              /* Code branches here for the right-hand subtree.  */
                   5439:              expand_label (test_label);
                   5440:              emit_case_nodes (index, node->right, default_label, index_type);
                   5441:            }
                   5442:        }
                   5443: 
                   5444:       else if (node->right != 0 && node->left == 0)
                   5445:        {
                   5446:          /* Here we have a right child but no left so we issue conditional
                   5447:             branch to default and process the right child.
                   5448: 
                   5449:             Omit the conditional branch to default if we it avoid only one
                   5450:             right child; it costs too much space to save so little time.  */
                   5451: 
                   5452:          if (node->right->right || node->right->left
                   5453:              || !tree_int_cst_equal (node->right->low, node->right->high))
                   5454:            {
                   5455:              if (!node_has_low_bound (node, index_type))
                   5456:                {
1.1.1.4   root     5457:                  emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
                   5458:                                                     VOIDmode, 0),
                   5459:                                 LT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5460:                  emit_jump_insn ((*gen_blt_pat) (default_label));
                   5461:                }
                   5462: 
                   5463:              emit_case_nodes (index, node->right, default_label, index_type);
                   5464:            }
                   5465:          else
                   5466:            /* We cannot process node->right normally
                   5467:               since we haven't ruled out the numbers less than
                   5468:               this node's value.  So handle node->right explicitly.  */
                   5469:            do_jump_if_equal (index,
1.1.1.4   root     5470:                              expand_expr (node->right->low, NULL_RTX,
                   5471:                                           VOIDmode, 0),
1.1       root     5472:                              label_rtx (node->right->code_label), unsignedp);
                   5473:        }
                   5474: 
                   5475:       else if (node->right == 0 && node->left != 0)
                   5476:        {
                   5477:          /* Just one subtree, on the left.  */
                   5478: 
                   5479: #if 0 /* The following code and comment were formerly part
                   5480:         of the condition here, but they didn't work
                   5481:         and I don't understand what the idea was.  -- rms.  */
                   5482:          /* If our "most probable entry" is less probable
                   5483:             than the default label, emit a jump to
                   5484:             the default label using condition codes
                   5485:             already lying around.  With no right branch,
                   5486:             a branch-greater-than will get us to the default
                   5487:             label correctly.  */
                   5488:          if (use_cost_table
                   5489:               && cost_table[TREE_INT_CST_LOW (node->high)] < 12)
                   5490:            ;
                   5491: #endif /* 0 */
                   5492:          if (node->left->left || node->left->right
                   5493:              || !tree_int_cst_equal (node->left->low, node->left->high))
                   5494:            {
                   5495:              if (!node_has_high_bound (node, index_type))
                   5496:                {
1.1.1.4   root     5497:                  emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
                   5498:                                                     VOIDmode, 0),
                   5499:                                 GT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5500:                  emit_jump_insn ((*gen_bgt_pat) (default_label));
                   5501:                }
                   5502: 
                   5503:              emit_case_nodes (index, node->left, default_label, index_type);
                   5504:            }
                   5505:          else
                   5506:            /* We cannot process node->left normally
                   5507:               since we haven't ruled out the numbers less than
                   5508:               this node's value.  So handle node->left explicitly.  */
                   5509:            do_jump_if_equal (index,
1.1.1.4   root     5510:                              expand_expr (node->left->low, NULL_RTX,
                   5511:                                           VOIDmode, 0),
1.1       root     5512:                              label_rtx (node->left->code_label), unsignedp);
                   5513:        }
                   5514:     }
                   5515:   else
                   5516:     {
                   5517:       /* Node is a range.  These cases are very similar to those for a single
                   5518:         value, except that we do not start by testing whether this node
                   5519:         is the one to branch to.  */
                   5520: 
                   5521:       if (node->right != 0 && node->left != 0)
                   5522:        {
                   5523:          /* Node has subtrees on both sides.
                   5524:             If the right-hand subtree is bounded,
                   5525:             test for it first, since we can go straight there.
                   5526:             Otherwise, we need to make a branch in the control structure,
                   5527:             then handle the two subtrees.  */
                   5528:          tree test_label = 0;
                   5529: 
1.1.1.4   root     5530:          emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
                   5531:                                             VOIDmode, 0),
                   5532:                         GT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5533: 
                   5534:          if (node_is_bounded (node->right, index_type))
                   5535:            /* Right hand node is fully bounded so we can eliminate any
                   5536:               testing and branch directly to the target code.  */
                   5537:            emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
                   5538:          else
                   5539:            {
                   5540:              /* Right hand node requires testing.
                   5541:                 Branch to a label where we will handle it later.  */
                   5542: 
                   5543:              test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
                   5544:              emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label)));
                   5545:            }
                   5546: 
                   5547:          /* Value belongs to this node or to the left-hand subtree.  */
                   5548: 
1.1.1.4   root     5549:          emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
                   5550:                         GE, NULL_RTX, mode, unsignedp, 0);
1.1       root     5551:          emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
                   5552: 
                   5553:          /* Handle the left-hand subtree.  */
                   5554:          emit_case_nodes (index, node->left, default_label, index_type);
                   5555: 
                   5556:          /* If right node had to be handled later, do that now.  */
                   5557: 
                   5558:          if (test_label)
                   5559:            {
                   5560:              /* If the left-hand subtree fell through,
                   5561:                 don't let it fall into the right-hand subtree.  */
                   5562:              emit_jump_if_reachable (default_label);
                   5563: 
                   5564:              expand_label (test_label);
                   5565:              emit_case_nodes (index, node->right, default_label, index_type);
                   5566:            }
                   5567:        }
                   5568: 
                   5569:       else if (node->right != 0 && node->left == 0)
                   5570:        {
                   5571:          /* Deal with values to the left of this node,
                   5572:             if they are possible.  */
                   5573:          if (!node_has_low_bound (node, index_type))
                   5574:            {
1.1.1.4   root     5575:              emit_cmp_insn (index, expand_expr (node->low, NULL_RTX,
                   5576:                                                 VOIDmode, 0),
                   5577:                             LT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5578:              emit_jump_insn ((*gen_blt_pat) (default_label));
                   5579:            }
                   5580: 
                   5581:          /* Value belongs to this node or to the right-hand subtree.  */
                   5582: 
1.1.1.4   root     5583:          emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
                   5584:                                             VOIDmode, 0),
                   5585:                         LE, NULL_RTX, mode, unsignedp, 0);
1.1       root     5586:          emit_jump_insn ((*gen_ble_pat) (label_rtx (node->code_label)));
                   5587: 
                   5588:          emit_case_nodes (index, node->right, default_label, index_type);
                   5589:        }
                   5590: 
                   5591:       else if (node->right == 0 && node->left != 0)
                   5592:        {
                   5593:          /* Deal with values to the right of this node,
                   5594:             if they are possible.  */
                   5595:          if (!node_has_high_bound (node, index_type))
                   5596:            {
1.1.1.4   root     5597:              emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
                   5598:                                                 VOIDmode, 0),
                   5599:                             GT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5600:              emit_jump_insn ((*gen_bgt_pat) (default_label));
                   5601:            }
                   5602: 
                   5603:          /* Value belongs to this node or to the left-hand subtree.  */
                   5604: 
1.1.1.4   root     5605:          emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
                   5606:                         GE, NULL_RTX, mode, unsignedp, 0);
1.1       root     5607:          emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
                   5608: 
                   5609:          emit_case_nodes (index, node->left, default_label, index_type);
                   5610:        }
                   5611: 
                   5612:       else
                   5613:        {
                   5614:          /* Node has no children so we check low and high bounds to remove
                   5615:             redundant tests.  Only one of the bounds can exist,
                   5616:             since otherwise this node is bounded--a case tested already.  */
                   5617: 
                   5618:          if (!node_has_high_bound (node, index_type))
                   5619:            {
1.1.1.4   root     5620:              emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
                   5621:                                                 VOIDmode, 0),
                   5622:                             GT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5623:              emit_jump_insn ((*gen_bgt_pat) (default_label));
                   5624:            }
                   5625: 
                   5626:          if (!node_has_low_bound (node, index_type))
                   5627:            {
1.1.1.4   root     5628:              emit_cmp_insn (index, expand_expr (node->low, NULL_RTX,
                   5629:                                                 VOIDmode, 0),
                   5630:                             LT, NULL_RTX, mode, unsignedp, 0);
1.1       root     5631:              emit_jump_insn ((*gen_blt_pat) (default_label));
                   5632:            }
                   5633: 
                   5634:          emit_jump (label_rtx (node->code_label));
                   5635:        }
                   5636:     }
                   5637: }
                   5638: 
                   5639: /* These routines are used by the loop unrolling code.  They copy BLOCK trees
                   5640:    so that the debugging info will be correct for the unrolled loop.  */
                   5641: 
1.1.1.4   root     5642: /* Indexed by block number, contains a pointer to the N'th block node.  */
1.1       root     5643: 
1.1.1.4   root     5644: static tree *block_vector;
1.1       root     5645: 
                   5646: void
1.1.1.4   root     5647: find_loop_tree_blocks ()
1.1       root     5648: {
1.1.1.4   root     5649:   tree block = DECL_INITIAL (current_function_decl);
1.1       root     5650: 
1.1.1.4   root     5651:   /* There first block is for the function body, and does not have
                   5652:      corresponding block notes.  Don't include it in the block vector.  */
                   5653:   block = BLOCK_SUBBLOCKS (block);
1.1       root     5654: 
1.1.1.4   root     5655:   block_vector = identify_blocks (block, get_insns ());
1.1       root     5656: }
                   5657: 
                   5658: void
1.1.1.4   root     5659: unroll_block_trees ()
1.1       root     5660: {
1.1.1.4   root     5661:   tree block = DECL_INITIAL (current_function_decl);
1.1       root     5662: 
1.1.1.4   root     5663:   reorder_blocks (block_vector, block, get_insns ());
1.1       root     5664: }
1.1.1.4   root     5665: 

unix.superglobalmegacorp.com

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