Annotation of gcc/explow.c, revision 1.1.1.1

1.1       root        1: /* Subroutines for manipulating rtx's in semantically interesting ways.
                      2:    Copyright (C) 1987, 1991 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: 
                     21: #include "config.h"
                     22: #include "rtl.h"
                     23: #include "tree.h"
                     24: #include "flags.h"
                     25: #include "expr.h"
                     26: #include "hard-reg-set.h"
                     27: #include "insn-config.h"
                     28: #include "recog.h"
                     29: #include "insn-flags.h"
                     30: #include "insn-codes.h"
                     31: 
                     32: /* Return an rtx for the sum of X and the integer C.  */
                     33: 
                     34: rtx
                     35: plus_constant (x, c)
                     36:      register rtx x;
                     37:      register int c;
                     38: {
                     39:   register RTX_CODE code;
                     40:   register enum machine_mode mode;
                     41:   register rtx tem;
                     42:   int all_constant = 0;
                     43: 
                     44:   if (c == 0)
                     45:     return x;
                     46: 
                     47:  restart:
                     48: 
                     49:   code = GET_CODE (x);
                     50:   mode = GET_MODE (x);
                     51:   switch (code)
                     52:     {
                     53:     case CONST_INT:
                     54:       return gen_rtx (CONST_INT, VOIDmode, (INTVAL (x) + c));
                     55: 
                     56:     case CONST_DOUBLE:
                     57:       {
                     58:        int l1 = CONST_DOUBLE_LOW (x);
                     59:        int h1 = CONST_DOUBLE_HIGH (x);
                     60:        int l2 = c;
                     61:        int h2 = c < 0 ? ~0 : 0;
                     62:        int lv, hv;
                     63: 
                     64:        add_double (l1, h1, l2, h2, &lv, &hv);
                     65: 
                     66:        return immed_double_const (lv, hv, VOIDmode);
                     67:       }
                     68: 
                     69:     case MEM:
                     70:       /* If this is a reference to the constant pool, try replacing it with
                     71:         a reference to a new constant.  If the resulting address isn't
                     72:         valid, don't return it because we have no way to validize it.  */
                     73:       if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
                     74:          && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
                     75:        {
                     76:          tem
                     77:            = force_const_mem (GET_MODE (x),
                     78:                               plus_constant (get_pool_constant (XEXP (x, 0)),
                     79:                                              c));
                     80:          if (memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
                     81:            return tem;
                     82:        }
                     83:       break;
                     84: 
                     85:     case CONST:
                     86:       /* If adding to something entirely constant, set a flag
                     87:         so that we can add a CONST around the result.  */
                     88:       x = XEXP (x, 0);
                     89:       all_constant = 1;
                     90:       goto restart;
                     91: 
                     92:     case SYMBOL_REF:
                     93:     case LABEL_REF:
                     94:       all_constant = 1;
                     95:       break;
                     96: 
                     97:     case PLUS:
                     98:       /* The interesting case is adding the integer to a sum.
                     99:         Look for constant term in the sum and combine
                    100:         with C.  For an integer constant term, we make a combined
                    101:         integer.  For a constant term that is not an explicit integer,
                    102:         we cannot really combine, but group them together anyway.  */
                    103:       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
                    104:        {
                    105:          c += INTVAL (XEXP (x, 0));
                    106:          x = XEXP (x, 1);
                    107:        }
                    108:       else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
                    109:        {
                    110:          c += INTVAL (XEXP (x, 1));
                    111:          x = XEXP (x, 0);
                    112:        }
                    113:       else if (CONSTANT_P (XEXP (x, 0)))
                    114:        return gen_rtx (PLUS, mode,
                    115:                        plus_constant (XEXP (x, 0), c),
                    116:                        XEXP (x, 1));
                    117:       else if (CONSTANT_P (XEXP (x, 1)))
                    118:        return gen_rtx (PLUS, mode,
                    119:                        XEXP (x, 0),
                    120:                        plus_constant (XEXP (x, 1), c));
                    121:     }
                    122: 
                    123:   if (c != 0)
                    124:     x = gen_rtx (PLUS, mode, x, gen_rtx (CONST_INT, VOIDmode, c));
                    125: 
                    126:   if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
                    127:     return x;
                    128:   else if (all_constant)
                    129:     return gen_rtx (CONST, mode, x);
                    130:   else
                    131:     return x;
                    132: }
                    133: 
                    134: /* This is the same a `plus_constant', except that it handles LO_SUM.  */
                    135: 
                    136: rtx
                    137: plus_constant_for_output (x, c)
                    138:      register rtx x;
                    139:      register int c;
                    140: {
                    141:   register RTX_CODE code = GET_CODE (x);
                    142:   register enum machine_mode mode = GET_MODE (x);
                    143:   int all_constant = 0;
                    144: 
                    145:   if (GET_CODE (x) == LO_SUM)
                    146:     return gen_rtx (LO_SUM, mode, XEXP (x, 0),
                    147:                    plus_constant_for_output (XEXP (x, 1), c));
                    148: 
                    149:   else
                    150:     return plus_constant (x, c);
                    151: }
                    152: 
                    153: /* If X is a sum, return a new sum like X but lacking any constant terms.
                    154:    Add all the removed constant terms into *CONSTPTR.
                    155:    X itself is not altered.  The result != X if and only if
                    156:    it is not isomorphic to X.  */
                    157: 
                    158: rtx
                    159: eliminate_constant_term (x, constptr)
                    160:      rtx x;
                    161:      int *constptr;
                    162: {
                    163:   int c;
                    164:   register rtx x0, x1;
                    165: 
                    166:   if (GET_CODE (x) != PLUS)
                    167:     return x;
                    168: 
                    169:   /* First handle constants appearing at this level explicitly.  */
                    170:   if (GET_CODE (XEXP (x, 0)) == CONST_INT)
                    171:     {
                    172:       *constptr += INTVAL (XEXP (x, 0));
                    173:       return eliminate_constant_term (XEXP (x, 1), constptr);
                    174:     }
                    175: 
                    176:   if (GET_CODE (XEXP (x, 1)) == CONST_INT)
                    177:     {
                    178:       *constptr += INTVAL (XEXP (x, 1));
                    179:       return eliminate_constant_term (XEXP (x, 0), constptr);
                    180:     }
                    181: 
                    182:   c = 0;
                    183:   x0 = eliminate_constant_term (XEXP (x, 0), &c);
                    184:   x1 = eliminate_constant_term (XEXP (x, 1), &c);
                    185:   if (x1 != XEXP (x, 1) || x0 != XEXP (x, 0))
                    186:     {
                    187:       *constptr += c;
                    188:       return gen_rtx (PLUS, GET_MODE (x), x0, x1);
                    189:     }
                    190:   return x;
                    191: }
                    192: 
                    193: /* Returns the insn that next references REG after INSN, or 0
                    194:    if REG is clobbered before next referenced or we cannot find
                    195:    an insn that references REG in a straight-line piece of code.  */
                    196: 
                    197: rtx
                    198: find_next_ref (reg, insn)
                    199:      rtx reg;
                    200:      rtx insn;
                    201: {
                    202:   rtx next;
                    203: 
                    204:   for (insn = NEXT_INSN (insn); insn; insn = next)
                    205:     {
                    206:       next = NEXT_INSN (insn);
                    207:       if (GET_CODE (insn) == NOTE)
                    208:        continue;
                    209:       if (GET_CODE (insn) == CODE_LABEL
                    210:          || GET_CODE (insn) == BARRIER)
                    211:        return 0;
                    212:       if (GET_CODE (insn) == INSN
                    213:          || GET_CODE (insn) == JUMP_INSN
                    214:          || GET_CODE (insn) == CALL_INSN)
                    215:        {
                    216:          if (reg_set_p (reg, insn))
                    217:            return 0;
                    218:          if (reg_mentioned_p (reg, PATTERN (insn)))
                    219:            return insn;
                    220:          if (GET_CODE (insn) == JUMP_INSN)
                    221:            {
                    222:              if (simplejump_p (insn))
                    223:                next = JUMP_LABEL (insn);
                    224:              else
                    225:                return 0;
                    226:            }
                    227:          if (GET_CODE (insn) == CALL_INSN
                    228:              && REGNO (reg) < FIRST_PSEUDO_REGISTER
                    229:              && call_used_regs[REGNO (reg)])
                    230:            return 0;
                    231:        }
                    232:       else
                    233:        abort ();
                    234:     }
                    235:   return 0;
                    236: }
                    237: 
                    238: /* Return an rtx for the size in bytes of the value of EXP.  */
                    239: 
                    240: rtx
                    241: expr_size (exp)
                    242:      tree exp;
                    243: {
                    244:   return expand_expr (size_in_bytes (TREE_TYPE (exp)),
                    245:                      0, TYPE_MODE (sizetype), 0);
                    246: }
                    247: 
                    248: /* Return a copy of X in which all memory references
                    249:    and all constants that involve symbol refs
                    250:    have been replaced with new temporary registers.
                    251:    Also emit code to load the memory locations and constants
                    252:    into those registers.
                    253: 
                    254:    If X contains no such constants or memory references,
                    255:    X itself (not a copy) is returned.
                    256: 
                    257:    If a constant is found in the address that is not a legitimate constant
                    258:    in an insn, it is left alone in the hope that it might be valid in the
                    259:    address.
                    260: 
                    261:    X may contain no arithmetic except addition, subtraction and multiplication.
                    262:    Values returned by expand_expr with 1 for sum_ok fit this constraint.  */
                    263: 
                    264: static rtx
                    265: break_out_memory_refs (x)
                    266:      register rtx x;
                    267: {
                    268:   if (GET_CODE (x) == MEM
                    269:       || (CONSTANT_P (x) && LEGITIMATE_CONSTANT_P (x)
                    270:          && GET_MODE (x) != VOIDmode))
                    271:     {
                    272:       register rtx temp = force_reg (GET_MODE (x), x);
                    273:       mark_reg_pointer (temp);
                    274:       x = temp;
                    275:     }
                    276:   else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
                    277:           || GET_CODE (x) == MULT)
                    278:     {
                    279:       register rtx op0 = break_out_memory_refs (XEXP (x, 0));
                    280:       register rtx op1 = break_out_memory_refs (XEXP (x, 1));
                    281:       if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
                    282:        x = gen_rtx (GET_CODE (x), Pmode, op0, op1);
                    283:     }
                    284:   return x;
                    285: }
                    286: 
                    287: /* Given a memory address or facsimile X, construct a new address,
                    288:    currently equivalent, that is stable: future stores won't change it.
                    289: 
                    290:    X must be composed of constants, register and memory references
                    291:    combined with addition, subtraction and multiplication:
                    292:    in other words, just what you can get from expand_expr if sum_ok is 1.
                    293: 
                    294:    Works by making copies of all regs and memory locations used
                    295:    by X and combining them the same way X does.
                    296:    You could also stabilize the reference to this address
                    297:    by copying the address to a register with copy_to_reg;
                    298:    but then you wouldn't get indexed addressing in the reference.  */
                    299: 
                    300: rtx
                    301: copy_all_regs (x)
                    302:      register rtx x;
                    303: {
                    304:   if (GET_CODE (x) == REG)
                    305:     {
                    306:       if (REGNO (x) != FRAME_POINTER_REGNUM)
                    307:        x = copy_to_reg (x);
                    308:     }
                    309:   else if (GET_CODE (x) == MEM)
                    310:     x = copy_to_reg (x);
                    311:   else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
                    312:           || GET_CODE (x) == MULT)
                    313:     {
                    314:       register rtx op0 = copy_all_regs (XEXP (x, 0));
                    315:       register rtx op1 = copy_all_regs (XEXP (x, 1));
                    316:       if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
                    317:        x = gen_rtx (GET_CODE (x), Pmode, op0, op1);
                    318:     }
                    319:   return x;
                    320: }
                    321: 
                    322: /* Return something equivalent to X but valid as a memory address
                    323:    for something of mode MODE.  When X is not itself valid, this
                    324:    works by copying X or subexpressions of it into registers.  */
                    325: 
                    326: rtx
                    327: memory_address (mode, x)
                    328:      enum machine_mode mode;
                    329:      register rtx x;
                    330: {
                    331:   register rtx oldx;
                    332: 
                    333:   /* By passing constant addresses thru registers
                    334:      we get a chance to cse them.  */
                    335:   if (! cse_not_expected && CONSTANT_P (x) && LEGITIMATE_CONSTANT_P (x))
                    336:     return force_reg (Pmode, x);
                    337: 
                    338:   /* Accept a QUEUED that refers to a REG
                    339:      even though that isn't a valid address.
                    340:      On attempting to put this in an insn we will call protect_from_queue
                    341:      which will turn it into a REG, which is valid.  */
                    342:   if (GET_CODE (x) == QUEUED
                    343:       && GET_CODE (QUEUED_VAR (x)) == REG)
                    344:     return x;
                    345: 
                    346:   /* We get better cse by rejecting indirect addressing at this stage.
                    347:      Let the combiner create indirect addresses where appropriate.
                    348:      For now, generate the code so that the subexpressions useful to share
                    349:      are visible.  But not if cse won't be done!  */
                    350:   oldx = x;
                    351:   if (! cse_not_expected && GET_CODE (x) != REG)
                    352:     x = break_out_memory_refs (x);
                    353: 
                    354:   /* At this point, any valid address is accepted.  */
                    355:   GO_IF_LEGITIMATE_ADDRESS (mode, x, win);
                    356: 
                    357:   /* If it was valid before but breaking out memory refs invalidated it,
                    358:      use it the old way.  */
                    359:   if (memory_address_p (mode, oldx))
                    360:     goto win2;
                    361: 
                    362:   /* Perform machine-dependent transformations on X
                    363:      in certain cases.  This is not necessary since the code
                    364:      below can handle all possible cases, but machine-dependent
                    365:      transformations can make better code.  */
                    366:   LEGITIMIZE_ADDRESS (x, oldx, mode, win);
                    367: 
                    368:   /* PLUS and MULT can appear in special ways
                    369:      as the result of attempts to make an address usable for indexing.
                    370:      Usually they are dealt with by calling force_operand, below.
                    371:      But a sum containing constant terms is special
                    372:      if removing them makes the sum a valid address:
                    373:      then we generate that address in a register
                    374:      and index off of it.  We do this because it often makes
                    375:      shorter code, and because the addresses thus generated
                    376:      in registers often become common subexpressions.  */
                    377:   if (GET_CODE (x) == PLUS)
                    378:     {
                    379:       int constant_term = 0;
                    380:       rtx y = eliminate_constant_term (x, &constant_term);
                    381:       if (constant_term == 0
                    382:          || ! memory_address_p (mode, y))
                    383:        return force_operand (x, 0);
                    384: 
                    385:       y = plus_constant (copy_to_reg (y), constant_term);
                    386:       if (! memory_address_p (mode, y))
                    387:        return force_operand (x, 0);
                    388:       return y;
                    389:     }
                    390:   if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS)
                    391:     return force_operand (x, 0);
                    392: 
                    393:   /* If we have a register that's an invalid address,
                    394:      it must be a hard reg of the wrong class.  Copy it to a pseudo.  */
                    395:   if (GET_CODE (x) == REG)
                    396:     return copy_to_reg (x);
                    397: 
                    398:   /* Last resort: copy the value to a register, since
                    399:      the register is a valid address.  */
                    400:   return force_reg (Pmode, x);
                    401: 
                    402:  win2:
                    403:   x = oldx;
                    404:  win:
                    405:   if (flag_force_addr && ! cse_not_expected && GET_CODE (x) != REG
                    406:       /* Don't copy an addr via a reg if it is one of our stack slots.  */
                    407:       && ! (GET_CODE (x) == PLUS
                    408:            && (XEXP (x, 0) == virtual_stack_vars_rtx
                    409:                || XEXP (x, 0) == virtual_incoming_args_rtx)))
                    410:     {
                    411:       if (general_operand (x, Pmode))
                    412:        return force_reg (Pmode, x);
                    413:       else
                    414:        return force_operand (x, 0);
                    415:     }
                    416:   return x;
                    417: }
                    418: 
                    419: /* Like `memory_address' but pretend `flag_force_addr' is 0.  */
                    420: 
                    421: rtx
                    422: memory_address_noforce (mode, x)
                    423:      enum machine_mode mode;
                    424:      rtx x;
                    425: {
                    426:   int ambient_force_addr = flag_force_addr;
                    427:   rtx val;
                    428: 
                    429:   flag_force_addr = 0;
                    430:   val = memory_address (mode, x);
                    431:   flag_force_addr = ambient_force_addr;
                    432:   return val;
                    433: }
                    434: 
                    435: /* Convert a mem ref into one with a valid memory address.
                    436:    Pass through anything else unchanged.  */
                    437: 
                    438: rtx
                    439: validize_mem (ref)
                    440:      rtx ref;
                    441: {
                    442:   if (GET_CODE (ref) != MEM)
                    443:     return ref;
                    444:   if (memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
                    445:     return ref;
                    446:   /* Don't alter REF itself, since that is probably a stack slot.  */
                    447:   return change_address (ref, GET_MODE (ref), XEXP (ref, 0));
                    448: }
                    449: 
                    450: /* Return a modified copy of X with its memory address copied
                    451:    into a temporary register to protect it from side effects.
                    452:    If X is not a MEM, it is returned unchanged (and not copied).
                    453:    Perhaps even if it is a MEM, if there is no need to change it.  */
                    454: 
                    455: rtx
                    456: stabilize (x)
                    457:      rtx x;
                    458: {
                    459:   register rtx addr;
                    460:   if (GET_CODE (x) != MEM)
                    461:     return x;
                    462:   addr = XEXP (x, 0);
                    463:   if (rtx_unstable_p (addr))
                    464:     {
                    465:       rtx temp = copy_all_regs (addr);
                    466:       rtx mem;
                    467:       if (GET_CODE (temp) != REG)
                    468:        temp = copy_to_reg (temp);
                    469:       mem = gen_rtx (MEM, GET_MODE (x), temp);
                    470:       /* Mark returned memref with in_struct
                    471:         if it's in an array or structure. */
                    472:       if (GET_CODE (addr) == PLUS || MEM_IN_STRUCT_P (x))
                    473:        MEM_IN_STRUCT_P (mem) = 1;
                    474:       return mem;
                    475:     }
                    476:   return x;
                    477: }
                    478: 
                    479: /* Copy the value or contents of X to a new temp reg and return that reg.  */
                    480: 
                    481: rtx
                    482: copy_to_reg (x)
                    483:      rtx x;
                    484: {
                    485:   register rtx temp = gen_reg_rtx (GET_MODE (x));
                    486:  
                    487:   /* If not an operand, must be an address with PLUS and MULT so
                    488:      do the computation.  */ 
                    489:   if (! general_operand (x, VOIDmode))
                    490:     x = force_operand (x, temp);
                    491:   
                    492:   if (x != temp)
                    493:     emit_move_insn (temp, x);
                    494: 
                    495:   return temp;
                    496: }
                    497: 
                    498: /* Like copy_to_reg but always give the new register mode Pmode
                    499:    in case X is a constant.  */
                    500: 
                    501: rtx
                    502: copy_addr_to_reg (x)
                    503:      rtx x;
                    504: {
                    505:   return copy_to_mode_reg (Pmode, x);
                    506: }
                    507: 
                    508: /* Like copy_to_reg but always give the new register mode MODE
                    509:    in case X is a constant.  */
                    510: 
                    511: rtx
                    512: copy_to_mode_reg (mode, x)
                    513:      enum machine_mode mode;
                    514:      rtx x;
                    515: {
                    516:   register rtx temp = gen_reg_rtx (mode);
                    517:   
                    518:   /* If not an operand, must be an address with PLUS and MULT so
                    519:      do the computation.  */ 
                    520:   if (! general_operand (x, VOIDmode))
                    521:     x = force_operand (x, temp);
                    522: 
                    523:   if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)
                    524:     abort ();
                    525:   if (x != temp)
                    526:     emit_move_insn (temp, x);
                    527:   return temp;
                    528: }
                    529: 
                    530: /* Load X into a register if it is not already one.
                    531:    Use mode MODE for the register.
                    532:    X should be valid for mode MODE, but it may be a constant which
                    533:    is valid for all integer modes; that's why caller must specify MODE.
                    534: 
                    535:    The caller must not alter the value in the register we return,
                    536:    since we mark it as a "constant" register.  */
                    537: 
                    538: rtx
                    539: force_reg (mode, x)
                    540:      enum machine_mode mode;
                    541:      rtx x;
                    542: {
                    543:   register rtx temp, insn;
                    544: 
                    545:   if (GET_CODE (x) == REG)
                    546:     return x;
                    547:   temp = gen_reg_rtx (mode);
                    548:   insn = emit_move_insn (temp, x);
                    549:   /* Let optimizers know that TEMP's value never changes
                    550:      and that X can be substituted for it.  */
                    551:   if (CONSTANT_P (x))
                    552:     {
                    553:       rtx note = find_reg_note (insn, REG_EQUAL, 0);
                    554: 
                    555:       if (note)
                    556:        XEXP (note, 0) = x;
                    557:       else
                    558:        REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, x, REG_NOTES (insn));
                    559:     }
                    560:   return temp;
                    561: }
                    562: 
                    563: /* If X is a memory ref, copy its contents to a new temp reg and return
                    564:    that reg.  Otherwise, return X.  */
                    565: 
                    566: rtx
                    567: force_not_mem (x)
                    568:      rtx x;
                    569: {
                    570:   register rtx temp;
                    571:   if (GET_CODE (x) != MEM || GET_MODE (x) == BLKmode)
                    572:     return x;
                    573:   temp = gen_reg_rtx (GET_MODE (x));
                    574:   emit_move_insn (temp, x);
                    575:   return temp;
                    576: }
                    577: 
                    578: /* Copy X to TARGET (if it's nonzero and a reg)
                    579:    or to a new temp reg and return that reg.
                    580: 
                    581:    If we need to make a temp reg, try getting the mode from
                    582:    both X and TARGET.  */
                    583: 
                    584: rtx
                    585: copy_to_suggested_reg (x, target)
                    586:      rtx x, target;
                    587: {
                    588:   register rtx temp;
                    589: 
                    590:   if (target && GET_CODE (target) == REG)
                    591:     temp = target;
                    592:   else
                    593:     {
                    594:       enum machine_mode mode = GET_MODE (x);
                    595: 
                    596:       if (mode == VOIDmode && target != 0)
                    597:        mode = GET_MODE (target);
                    598: 
                    599:       temp = gen_reg_rtx (mode);
                    600:     }
                    601: 
                    602:   emit_move_insn (temp, x);
                    603:   return temp;
                    604: }
                    605: 
                    606: /* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
                    607:    This pops when ADJUST is positive.  ADJUST need not be constant.  */
                    608: 
                    609: void
                    610: adjust_stack (adjust)
                    611:      rtx adjust;
                    612: {
                    613:   rtx temp;
                    614:   adjust = protect_from_queue (adjust, 0);
                    615: 
                    616:   if (adjust == const0_rtx)
                    617:     return;
                    618: 
                    619:   temp = expand_binop (Pmode,
                    620: #ifdef STACK_GROWS_DOWNWARD
                    621:                       add_optab,
                    622: #else
                    623:                       sub_optab,
                    624: #endif
                    625:                       stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
                    626:                       OPTAB_LIB_WIDEN);
                    627: 
                    628:   if (temp != stack_pointer_rtx)
                    629:     emit_move_insn (stack_pointer_rtx, temp);
                    630: }
                    631: 
                    632: /* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes).
                    633:    This pushes when ADJUST is positive.  ADJUST need not be constant.  */
                    634: 
                    635: void
                    636: anti_adjust_stack (adjust)
                    637:      rtx adjust;
                    638: {
                    639:   rtx temp;
                    640:   adjust = protect_from_queue (adjust, 0);
                    641: 
                    642:   if (adjust == const0_rtx)
                    643:     return;
                    644: 
                    645:   temp = expand_binop (Pmode,
                    646: #ifdef STACK_GROWS_DOWNWARD
                    647:                       sub_optab,
                    648: #else
                    649:                       add_optab,
                    650: #endif
                    651:                       stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
                    652:                       OPTAB_LIB_WIDEN);
                    653: 
                    654:   if (temp != stack_pointer_rtx)
                    655:     emit_move_insn (stack_pointer_rtx, temp);
                    656: }
                    657: 
                    658: /* Round the size of a block to be pushed up to the boundary required
                    659:    by this machine.  SIZE is the desired size, which need not be constant.  */
                    660: 
                    661: rtx
                    662: round_push (size)
                    663:      rtx size;
                    664: {
                    665: #ifdef STACK_BOUNDARY
                    666:   int align = STACK_BOUNDARY / BITS_PER_UNIT;
                    667:   if (align == 1)
                    668:     return size;
                    669:   if (GET_CODE (size) == CONST_INT)
                    670:     {
                    671:       int new = (INTVAL (size) + align - 1) / align * align;
                    672:       if (INTVAL (size) != new)
                    673:        size = gen_rtx (CONST_INT, VOIDmode, new);
                    674:     }
                    675:   else
                    676:     {
                    677:       size = expand_divmod (0, CEIL_DIV_EXPR, Pmode, size,
                    678:                            gen_rtx (CONST_INT, VOIDmode, align),
                    679:                            0, 1);
                    680:       size = expand_mult (Pmode, size,
                    681:                          gen_rtx (CONST_INT, VOIDmode, align),
                    682:                          0, 1);
                    683:     }
                    684: #endif /* STACK_BOUNDARY */
                    685:   return size;
                    686: }
                    687: 
                    688: /* Return an rtx representing the address of an area of memory dynamically
                    689:    pushed on the stack.  This region of memory is always aligned to
                    690:    a multiple of BIGGEST_ALIGNMENT.
                    691: 
                    692:    Any required stack pointer alignment is preserved.
                    693: 
                    694:    SIZE is an rtx representing the size of the area.
                    695:    TARGET is a place in which the address can be placed.  */
                    696: 
                    697: rtx
                    698: allocate_dynamic_stack_space (size, target)
                    699:      rtx size;
                    700:      rtx target;
                    701: {
                    702:   /* Ensure the size is in the proper mode.  */
                    703:   if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
                    704:     size = convert_to_mode (Pmode, size, 1);
                    705: 
                    706:   /* We will need to ensure that the address we return is aligned to
                    707:      BIGGEST_ALIGNMENT.  If STACK_DYNAMIC_OFFSET is defined, we don't
                    708:      always know its final value at this point in the compilation (it 
                    709:      might depend on the size of the outgoing parameter lists, for
                    710:      example), so we must align the value to be returned in that case.
                    711:      (Note that STACK_DYNAMIC_OFFSET will have a default non-zero value if
                    712:      STACK_POINTER_OFFSET or ACCUMULATE_OUTGOING_ARGS are defined).
                    713:      We must also do an alignment operation on the returned value if
                    714:      the stack pointer alignment is less strict that BIGGEST_ALIGNMENT.
                    715: 
                    716:      If we have to align, we must leave space in SIZE for the hole
                    717:      that might result from the alignment operation.  */
                    718: 
                    719: #if defined (STACK_DYNAMIC_OFFSET) || defined(STACK_POINTER_OFFSET) || defined (ALLOCATE_OUTGOING_ARGS)
                    720: #define MUST_ALIGN
                    721: #endif
                    722: 
                    723: #if ! defined (MUST_ALIGN) && (!defined(STACK_BOUNDARY) || STACK_BOUNDARY < BIGGEST_ALIGNMENT)
                    724: #define MUST_ALIGN
                    725: #endif
                    726: 
                    727: #ifdef MUST_ALIGN
                    728: 
                    729:   if (GET_CODE (size) == CONST_INT)
                    730:     size = gen_rtx (CONST_INT, VOIDmode,
                    731:                    INTVAL (size) + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1));
                    732:   else
                    733:     size = expand_binop (Pmode, add_optab, size,
                    734:                         gen_rtx (CONST_INT, VOIDmode,
                    735:                                  BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1),
                    736:                         0, 1, OPTAB_LIB_WIDEN);
                    737: #endif
                    738: 
                    739: #ifdef SETJMP_VIA_SAVE_AREA
                    740:   /* If setjmp restores regs from a save area in the stack frame,
                    741:      avoid clobbering the reg save area.  Note that the offset of
                    742:      virtual_incoming_args_rtx includes the preallocated stack args space.
                    743:      It would be no problem to clobber that, but it's on the wrong side
                    744:      of the old save area.  */
                    745:   {
                    746:     rtx dynamic_offset
                    747:       = expand_binop (Pmode, sub_optab, virtual_stack_dynamic_rtx,
                    748:                      stack_pointer_rtx, 0, 1, OPTAB_LIB_WIDEN);
                    749:     size = expand_binop (Pmode, add_optab, size, dynamic_offset,
                    750:                         0, 1, OPTAB_LIB_WIDEN);
                    751:   }
                    752: #endif /* SETJMP_VIA_SAVE_AREA */
                    753: 
                    754:   /* Round the size to a multiple of the required stack alignment.
                    755:      Since the stack if presumed to be rounded before this allocation,
                    756:      this will maintain the required alignment.
                    757: 
                    758:      If the stack grows downward, we could save an insn by subtracting
                    759:      SIZE from the stack pointer and then aligning the stack pointer.
                    760:      The problem with this is that the stack pointer may be unaligned
                    761:      between the execution of the subtraction and alignment insns and
                    762:      some machines do not allow this.  Even on those that do, some
                    763:      signal handlers malfunction if a signal should occur between those
                    764:      insns.  Since this is an extremely rare event, we have no reliable
                    765:      way of knowing which systems have this problem.  So we avoid even
                    766:      momentarily mis-aligning the stack.  */
                    767: 
                    768:   size = round_push (size);
                    769: 
                    770:   do_pending_stack_adjust ();
                    771: 
                    772:   if (target == 0)
                    773:     target = gen_reg_rtx (Pmode);
                    774: 
                    775: #ifndef STACK_GROWS_DOWNWARD
                    776:   emit_move_insn (target, virtual_stack_dynamic_rtx);
                    777: #endif
                    778: 
                    779:   /* Perform the required allocation from the stack.  Some systems do
                    780:      this differently than simply incrementing/decrementing from the
                    781:      stack pointer.  */
                    782: #ifdef HAVE_allocate_stack
                    783:   if (HAVE_allocate_stack)
                    784:     {
                    785:       enum machine_mode mode
                    786:        = insn_operand_mode[(int) CODE_FOR_allocate_stack][0];
                    787: 
                    788:       if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][0]
                    789:          && ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][0])
                    790:                (size, mode)))
                    791:        size = copy_to_mode_reg (mode, size);
                    792: 
                    793:       emit_insn (gen_allocate_stack (size));
                    794:     }
                    795:   else
                    796: #endif
                    797:     anti_adjust_stack (size);
                    798: 
                    799: #ifdef STACK_GROWS_DOWNWARD
                    800:   emit_move_insn (target, virtual_stack_dynamic_rtx);
                    801: #endif
                    802: 
                    803: #ifdef MUST_ALIGN
                    804:   target = expand_divmod (0, CEIL_DIV_EXPR, Pmode, target,
                    805:                          gen_rtx (CONST_INT, VOIDmode,
                    806:                                   BIGGEST_ALIGNMENT / BITS_PER_UNIT),
                    807:                          0, 1);
                    808: 
                    809:   target = expand_mult (Pmode, target,
                    810:                        gen_rtx (CONST_INT, VOIDmode,
                    811:                                 BIGGEST_ALIGNMENT / BITS_PER_UNIT),
                    812:                        0, 1);
                    813: #endif
                    814:   
                    815:   /* Some systems require a particular insn to refer to the stack
                    816:      to make the pages exist.  */
                    817: #ifdef HAVE_probe
                    818:   if (HAVE_probe)
                    819:     emit_insn (gen_probe ());
                    820: #endif
                    821: 
                    822:   return target;
                    823: }
                    824: 
                    825: /* Return an rtx representing the register or memory location
                    826:    in which a scalar value of data type VALTYPE
                    827:    was returned by a function call to function FUNC.
                    828:    FUNC is a FUNCTION_DECL node if the precise function is known,
                    829:    otherwise 0.  */
                    830: 
                    831: rtx
                    832: hard_function_value (valtype, func)
                    833:      tree valtype;
                    834:      tree func;
                    835: {
                    836:   return FUNCTION_VALUE (valtype, func);
                    837: }
                    838: 
                    839: /* Return an rtx representing the register or memory location
                    840:    in which a scalar value of mode MODE was returned by a library call.  */
                    841: 
                    842: rtx
                    843: hard_libcall_value (mode)
                    844:      enum machine_mode mode;
                    845: {
                    846:   return LIBCALL_VALUE (mode);
                    847: }

unix.superglobalmegacorp.com

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