Annotation of gcc/stmt.c, revision 1.1.1.8

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

unix.superglobalmegacorp.com

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