118334Speter/* Subroutines for manipulating rtx's in semantically interesting ways. 290075Sobrien Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998, 3169689Skan 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4169689Skan Free Software Foundation, Inc. 518334Speter 690075SobrienThis file is part of GCC. 718334Speter 890075SobrienGCC is free software; you can redistribute it and/or modify it under 990075Sobrienthe terms of the GNU General Public License as published by the Free 1090075SobrienSoftware Foundation; either version 2, or (at your option) any later 1190075Sobrienversion. 1218334Speter 1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1590075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1690075Sobrienfor more details. 1718334Speter 1818334SpeterYou should have received a copy of the GNU General Public License 1990075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 21169689Skan02110-1301, USA. */ 2218334Speter 2318334Speter 2418334Speter#include "config.h" 2550397Sobrien#include "system.h" 26132718Skan#include "coretypes.h" 27132718Skan#include "tm.h" 2852284Sobrien#include "toplev.h" 2918334Speter#include "rtl.h" 3018334Speter#include "tree.h" 3190075Sobrien#include "tm_p.h" 3218334Speter#include "flags.h" 3390075Sobrien#include "function.h" 3418334Speter#include "expr.h" 3590075Sobrien#include "optabs.h" 3618334Speter#include "hard-reg-set.h" 3718334Speter#include "insn-config.h" 3890075Sobrien#include "ggc.h" 3918334Speter#include "recog.h" 40102780Skan#include "langhooks.h" 41169689Skan#include "target.h" 42169689Skan#include "output.h" 4318334Speter 44132718Skanstatic rtx break_out_memory_refs (rtx); 45132718Skanstatic void emit_stack_probe (rtx); 4652284Sobrien 4790075Sobrien 4890075Sobrien/* Truncate and perhaps sign-extend C as appropriate for MODE. */ 4990075Sobrien 5090075SobrienHOST_WIDE_INT 51132718Skantrunc_int_for_mode (HOST_WIDE_INT c, enum machine_mode mode) 5290075Sobrien{ 5390075Sobrien int width = GET_MODE_BITSIZE (mode); 5490075Sobrien 55117395Skan /* You want to truncate to a _what_? */ 56169689Skan gcc_assert (SCALAR_INT_MODE_P (mode)); 57117395Skan 5890075Sobrien /* Canonicalize BImode to 0 and STORE_FLAG_VALUE. */ 5990075Sobrien if (mode == BImode) 6090075Sobrien return c & 1 ? STORE_FLAG_VALUE : 0; 6190075Sobrien 6290075Sobrien /* Sign-extend for the requested mode. */ 6390075Sobrien 6490075Sobrien if (width < HOST_BITS_PER_WIDE_INT) 6590075Sobrien { 6690075Sobrien HOST_WIDE_INT sign = 1; 6790075Sobrien sign <<= width - 1; 6890075Sobrien c &= (sign << 1) - 1; 6990075Sobrien c ^= sign; 7090075Sobrien c -= sign; 7190075Sobrien } 7290075Sobrien 7390075Sobrien return c; 7490075Sobrien} 7590075Sobrien 76169689Skan/* Return an rtx for the sum of X and the integer C. */ 7718334Speter 7818334Speterrtx 79169689Skanplus_constant (rtx x, HOST_WIDE_INT c) 8018334Speter{ 8190075Sobrien RTX_CODE code; 8290075Sobrien rtx y; 8390075Sobrien enum machine_mode mode; 8490075Sobrien rtx tem; 8518334Speter int all_constant = 0; 8618334Speter 8718334Speter if (c == 0) 8818334Speter return x; 8918334Speter 9018334Speter restart: 9118334Speter 9218334Speter code = GET_CODE (x); 9318334Speter mode = GET_MODE (x); 9490075Sobrien y = x; 9590075Sobrien 9618334Speter switch (code) 9718334Speter { 9818334Speter case CONST_INT: 9918334Speter return GEN_INT (INTVAL (x) + c); 10018334Speter 10118334Speter case CONST_DOUBLE: 10218334Speter { 10390075Sobrien unsigned HOST_WIDE_INT l1 = CONST_DOUBLE_LOW (x); 10418334Speter HOST_WIDE_INT h1 = CONST_DOUBLE_HIGH (x); 10590075Sobrien unsigned HOST_WIDE_INT l2 = c; 10618334Speter HOST_WIDE_INT h2 = c < 0 ? ~0 : 0; 10790075Sobrien unsigned HOST_WIDE_INT lv; 10890075Sobrien HOST_WIDE_INT hv; 10918334Speter 11018334Speter add_double (l1, h1, l2, h2, &lv, &hv); 11118334Speter 11218334Speter return immed_double_const (lv, hv, VOIDmode); 11318334Speter } 11418334Speter 11518334Speter case MEM: 11618334Speter /* If this is a reference to the constant pool, try replacing it with 11718334Speter a reference to a new constant. If the resulting address isn't 11818334Speter valid, don't return it because we have no way to validize it. */ 11918334Speter if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF 12018334Speter && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))) 12118334Speter { 12218334Speter tem 12318334Speter = force_const_mem (GET_MODE (x), 12418334Speter plus_constant (get_pool_constant (XEXP (x, 0)), 12518334Speter c)); 12618334Speter if (memory_address_p (GET_MODE (tem), XEXP (tem, 0))) 12718334Speter return tem; 12818334Speter } 12918334Speter break; 13018334Speter 13118334Speter case CONST: 13218334Speter /* If adding to something entirely constant, set a flag 13318334Speter so that we can add a CONST around the result. */ 13418334Speter x = XEXP (x, 0); 13518334Speter all_constant = 1; 13618334Speter goto restart; 13718334Speter 13818334Speter case SYMBOL_REF: 13918334Speter case LABEL_REF: 14018334Speter all_constant = 1; 14118334Speter break; 14218334Speter 14318334Speter case PLUS: 14418334Speter /* The interesting case is adding the integer to a sum. 14518334Speter Look for constant term in the sum and combine 14618334Speter with C. For an integer constant term, we make a combined 14718334Speter integer. For a constant term that is not an explicit integer, 14896263Sobrien we cannot really combine, but group them together anyway. 14918334Speter 15052284Sobrien Restart or use a recursive call in case the remaining operand is 15152284Sobrien something that we handle specially, such as a SYMBOL_REF. 15218334Speter 15352284Sobrien We may not immediately return from the recursive call here, lest 15452284Sobrien all_constant gets lost. */ 15552284Sobrien 15618334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT) 15752284Sobrien { 15852284Sobrien c += INTVAL (XEXP (x, 1)); 15990075Sobrien 16090075Sobrien if (GET_MODE (x) != VOIDmode) 16190075Sobrien c = trunc_int_for_mode (c, GET_MODE (x)); 16290075Sobrien 16352284Sobrien x = XEXP (x, 0); 16452284Sobrien goto restart; 16552284Sobrien } 16690075Sobrien else if (CONSTANT_P (XEXP (x, 1))) 16752284Sobrien { 16890075Sobrien x = gen_rtx_PLUS (mode, XEXP (x, 0), plus_constant (XEXP (x, 1), c)); 16952284Sobrien c = 0; 17052284Sobrien } 17190075Sobrien else if (find_constant_term_loc (&y)) 17252284Sobrien { 17390075Sobrien /* We need to be careful since X may be shared and we can't 17490075Sobrien modify it in place. */ 17590075Sobrien rtx copy = copy_rtx (x); 17690075Sobrien rtx *const_loc = find_constant_term_loc (©); 17790075Sobrien 17890075Sobrien *const_loc = plus_constant (*const_loc, c); 17990075Sobrien x = copy; 18052284Sobrien c = 0; 18152284Sobrien } 18250397Sobrien break; 18390075Sobrien 18450397Sobrien default: 18550397Sobrien break; 18618334Speter } 18718334Speter 18818334Speter if (c != 0) 18950397Sobrien x = gen_rtx_PLUS (mode, x, GEN_INT (c)); 19018334Speter 19118334Speter if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) 19218334Speter return x; 19318334Speter else if (all_constant) 19450397Sobrien return gen_rtx_CONST (mode, x); 19518334Speter else 19618334Speter return x; 19718334Speter} 19818334Speter 19918334Speter/* If X is a sum, return a new sum like X but lacking any constant terms. 20018334Speter Add all the removed constant terms into *CONSTPTR. 20118334Speter X itself is not altered. The result != X if and only if 20218334Speter it is not isomorphic to X. */ 20318334Speter 20418334Speterrtx 205132718Skaneliminate_constant_term (rtx x, rtx *constptr) 20618334Speter{ 20790075Sobrien rtx x0, x1; 20818334Speter rtx tem; 20918334Speter 21018334Speter if (GET_CODE (x) != PLUS) 21118334Speter return x; 21218334Speter 21318334Speter /* First handle constants appearing at this level explicitly. */ 21418334Speter if (GET_CODE (XEXP (x, 1)) == CONST_INT 21518334Speter && 0 != (tem = simplify_binary_operation (PLUS, GET_MODE (x), *constptr, 21618334Speter XEXP (x, 1))) 21718334Speter && GET_CODE (tem) == CONST_INT) 21818334Speter { 21918334Speter *constptr = tem; 22018334Speter return eliminate_constant_term (XEXP (x, 0), constptr); 22118334Speter } 22218334Speter 22318334Speter tem = const0_rtx; 22418334Speter x0 = eliminate_constant_term (XEXP (x, 0), &tem); 22518334Speter x1 = eliminate_constant_term (XEXP (x, 1), &tem); 22618334Speter if ((x1 != XEXP (x, 1) || x0 != XEXP (x, 0)) 22718334Speter && 0 != (tem = simplify_binary_operation (PLUS, GET_MODE (x), 22818334Speter *constptr, tem)) 22918334Speter && GET_CODE (tem) == CONST_INT) 23018334Speter { 23118334Speter *constptr = tem; 23250397Sobrien return gen_rtx_PLUS (GET_MODE (x), x0, x1); 23318334Speter } 23418334Speter 23518334Speter return x; 23618334Speter} 23718334Speter 23818334Speter/* Return an rtx for the size in bytes of the value of EXP. */ 23918334Speter 24018334Speterrtx 241132718Skanexpr_size (tree exp) 24218334Speter{ 243169689Skan tree size; 24418334Speter 245169689Skan if (TREE_CODE (exp) == WITH_SIZE_EXPR) 246169689Skan size = TREE_OPERAND (exp, 1); 247169689Skan else 248169689Skan size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lang_hooks.expr_size (exp), exp); 24918334Speter 25090075Sobrien return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0); 251102780Skan} 25290075Sobrien 253102780Skan/* Return a wide integer for the size in bytes of the value of EXP, or -1 254102780Skan if the size can vary or is larger than an integer. */ 255102780Skan 256102780SkanHOST_WIDE_INT 257132718Skanint_expr_size (tree exp) 258102780Skan{ 259169689Skan tree size; 260102780Skan 261169689Skan if (TREE_CODE (exp) == WITH_SIZE_EXPR) 262169689Skan size = TREE_OPERAND (exp, 1); 263169689Skan else 264169689Skan size = lang_hooks.expr_size (exp); 265169689Skan 266169689Skan if (size == 0 || !host_integerp (size, 0)) 267102780Skan return -1; 268102780Skan 269169689Skan return tree_low_cst (size, 0); 27018334Speter} 27118334Speter 27218334Speter/* Return a copy of X in which all memory references 27318334Speter and all constants that involve symbol refs 27418334Speter have been replaced with new temporary registers. 27518334Speter Also emit code to load the memory locations and constants 27618334Speter into those registers. 27718334Speter 27818334Speter If X contains no such constants or memory references, 27918334Speter X itself (not a copy) is returned. 28018334Speter 28118334Speter If a constant is found in the address that is not a legitimate constant 28218334Speter in an insn, it is left alone in the hope that it might be valid in the 28318334Speter address. 28418334Speter 28518334Speter X may contain no arithmetic except addition, subtraction and multiplication. 28618334Speter Values returned by expand_expr with 1 for sum_ok fit this constraint. */ 28718334Speter 28818334Speterstatic rtx 289132718Skanbreak_out_memory_refs (rtx x) 29018334Speter{ 291169689Skan if (MEM_P (x) 29218334Speter || (CONSTANT_P (x) && CONSTANT_ADDRESS_P (x) 29318334Speter && GET_MODE (x) != VOIDmode)) 29418334Speter x = force_reg (GET_MODE (x), x); 29518334Speter else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS 29618334Speter || GET_CODE (x) == MULT) 29718334Speter { 29890075Sobrien rtx op0 = break_out_memory_refs (XEXP (x, 0)); 29990075Sobrien rtx op1 = break_out_memory_refs (XEXP (x, 1)); 30018334Speter 30118334Speter if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1)) 30250397Sobrien x = gen_rtx_fmt_ee (GET_CODE (x), Pmode, op0, op1); 30318334Speter } 30418334Speter 30518334Speter return x; 30618334Speter} 30718334Speter 30818334Speter/* Given X, a memory address in ptr_mode, convert it to an address 30918334Speter in Pmode, or vice versa (TO_MODE says which way). We take advantage of 31018334Speter the fact that pointers are not allowed to overflow by commuting arithmetic 31118334Speter operations over conversions so that address arithmetic insns can be 31218334Speter used. */ 31318334Speter 31418334Speterrtx 315132718Skanconvert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED, 316132718Skan rtx x) 31718334Speter{ 318132718Skan#ifndef POINTERS_EXTEND_UNSIGNED 319169689Skan gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode); 320132718Skan return x; 321132718Skan#else /* defined(POINTERS_EXTEND_UNSIGNED) */ 322132718Skan enum machine_mode from_mode; 32318334Speter rtx temp; 324117395Skan enum rtx_code code; 32518334Speter 326132718Skan /* If X already has the right mode, just return it. */ 327132718Skan if (GET_MODE (x) == to_mode) 328132718Skan return x; 329132718Skan 330132718Skan from_mode = to_mode == ptr_mode ? Pmode : ptr_mode; 331132718Skan 33250397Sobrien /* Here we handle some special cases. If none of them apply, fall through 33350397Sobrien to the default case. */ 33418334Speter switch (GET_CODE (x)) 33518334Speter { 33618334Speter case CONST_INT: 33718334Speter case CONST_DOUBLE: 338117395Skan if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)) 339117395Skan code = TRUNCATE; 340117395Skan else if (POINTERS_EXTEND_UNSIGNED < 0) 341117395Skan break; 342117395Skan else if (POINTERS_EXTEND_UNSIGNED > 0) 343117395Skan code = ZERO_EXTEND; 344117395Skan else 345117395Skan code = SIGN_EXTEND; 346117395Skan temp = simplify_unary_operation (code, to_mode, x, from_mode); 347117395Skan if (temp) 348117395Skan return temp; 349117395Skan break; 35018334Speter 35190075Sobrien case SUBREG: 352117395Skan if ((SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x))) 35390075Sobrien && GET_MODE (SUBREG_REG (x)) == to_mode) 35490075Sobrien return SUBREG_REG (x); 35590075Sobrien break; 35690075Sobrien 35718334Speter case LABEL_REF: 358117395Skan temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0)); 359117395Skan LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x); 360117395Skan return temp; 36190075Sobrien break; 36218334Speter 36318334Speter case SYMBOL_REF: 364117395Skan temp = shallow_copy_rtx (x); 365117395Skan PUT_MODE (temp, to_mode); 366117395Skan return temp; 36790075Sobrien break; 36818334Speter 36950397Sobrien case CONST: 370117395Skan return gen_rtx_CONST (to_mode, 371117395Skan convert_memory_address (to_mode, XEXP (x, 0))); 37290075Sobrien break; 37350397Sobrien 37418334Speter case PLUS: 37518334Speter case MULT: 376117395Skan /* For addition we can safely permute the conversion and addition 377117395Skan operation if one operand is a constant and converting the constant 378117395Skan does not change it. We can always safely permute them if we are 379117395Skan making the address narrower. */ 380117395Skan if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode) 381117395Skan || (GET_CODE (x) == PLUS 382117395Skan && GET_CODE (XEXP (x, 1)) == CONST_INT 383117395Skan && XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1)))) 38496263Sobrien return gen_rtx_fmt_ee (GET_CODE (x), to_mode, 38550397Sobrien convert_memory_address (to_mode, XEXP (x, 0)), 386117395Skan XEXP (x, 1)); 38750397Sobrien break; 38896263Sobrien 38918334Speter default: 39050397Sobrien break; 39118334Speter } 39250397Sobrien 39350397Sobrien return convert_modes (to_mode, from_mode, 39450397Sobrien x, POINTERS_EXTEND_UNSIGNED); 395132718Skan#endif /* defined(POINTERS_EXTEND_UNSIGNED) */ 39618334Speter} 39718334Speter 39818334Speter/* Return something equivalent to X but valid as a memory address 39918334Speter for something of mode MODE. When X is not itself valid, this 40018334Speter works by copying X or subexpressions of it into registers. */ 40118334Speter 40218334Speterrtx 403132718Skanmemory_address (enum machine_mode mode, rtx x) 40418334Speter{ 40590075Sobrien rtx oldx = x; 40618334Speter 407132718Skan x = convert_memory_address (Pmode, x); 40818334Speter 409132718Skan /* By passing constant addresses through registers 41018334Speter we get a chance to cse them. */ 41118334Speter if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)) 41218334Speter x = force_reg (Pmode, x); 41318334Speter 41418334Speter /* We get better cse by rejecting indirect addressing at this stage. 41518334Speter Let the combiner create indirect addresses where appropriate. 41618334Speter For now, generate the code so that the subexpressions useful to share 41718334Speter are visible. But not if cse won't be done! */ 41818334Speter else 41918334Speter { 420169689Skan if (! cse_not_expected && !REG_P (x)) 42118334Speter x = break_out_memory_refs (x); 42218334Speter 42318334Speter /* At this point, any valid address is accepted. */ 424169689Skan if (memory_address_p (mode, x)) 425169689Skan goto win; 42618334Speter 42718334Speter /* If it was valid before but breaking out memory refs invalidated it, 42818334Speter use it the old way. */ 42918334Speter if (memory_address_p (mode, oldx)) 43018334Speter goto win2; 43118334Speter 43218334Speter /* Perform machine-dependent transformations on X 43318334Speter in certain cases. This is not necessary since the code 43418334Speter below can handle all possible cases, but machine-dependent 43518334Speter transformations can make better code. */ 43618334Speter LEGITIMIZE_ADDRESS (x, oldx, mode, win); 43718334Speter 43818334Speter /* PLUS and MULT can appear in special ways 43918334Speter as the result of attempts to make an address usable for indexing. 44018334Speter Usually they are dealt with by calling force_operand, below. 44118334Speter But a sum containing constant terms is special 44218334Speter if removing them makes the sum a valid address: 44318334Speter then we generate that address in a register 44418334Speter and index off of it. We do this because it often makes 44518334Speter shorter code, and because the addresses thus generated 44618334Speter in registers often become common subexpressions. */ 44718334Speter if (GET_CODE (x) == PLUS) 44818334Speter { 44918334Speter rtx constant_term = const0_rtx; 45018334Speter rtx y = eliminate_constant_term (x, &constant_term); 45118334Speter if (constant_term == const0_rtx 45218334Speter || ! memory_address_p (mode, y)) 45318334Speter x = force_operand (x, NULL_RTX); 45418334Speter else 45518334Speter { 45650397Sobrien y = gen_rtx_PLUS (GET_MODE (x), copy_to_reg (y), constant_term); 45718334Speter if (! memory_address_p (mode, y)) 45818334Speter x = force_operand (x, NULL_RTX); 45918334Speter else 46018334Speter x = y; 46118334Speter } 46218334Speter } 46318334Speter 46418334Speter else if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS) 46518334Speter x = force_operand (x, NULL_RTX); 46618334Speter 46718334Speter /* If we have a register that's an invalid address, 46818334Speter it must be a hard reg of the wrong class. Copy it to a pseudo. */ 469169689Skan else if (REG_P (x)) 47018334Speter x = copy_to_reg (x); 47118334Speter 47218334Speter /* Last resort: copy the value to a register, since 47318334Speter the register is a valid address. */ 47418334Speter else 47518334Speter x = force_reg (Pmode, x); 47618334Speter 47718334Speter goto done; 47818334Speter 47918334Speter win2: 48018334Speter x = oldx; 48118334Speter win: 482169689Skan if (flag_force_addr && ! cse_not_expected && !REG_P (x)) 48318334Speter { 484169689Skan x = force_operand (x, NULL_RTX); 485169689Skan x = force_reg (Pmode, x); 48618334Speter } 48718334Speter } 48818334Speter 48918334Speter done: 49018334Speter 49118334Speter /* If we didn't change the address, we are done. Otherwise, mark 49218334Speter a reg as a pointer if we have REG or REG + CONST_INT. */ 49318334Speter if (oldx == x) 49418334Speter return x; 495169689Skan else if (REG_P (x)) 49690075Sobrien mark_reg_pointer (x, BITS_PER_UNIT); 49718334Speter else if (GET_CODE (x) == PLUS 498169689Skan && REG_P (XEXP (x, 0)) 49918334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT) 50090075Sobrien mark_reg_pointer (XEXP (x, 0), BITS_PER_UNIT); 50118334Speter 50218334Speter /* OLDX may have been the address on a temporary. Update the address 50318334Speter to indicate that X is now used. */ 50418334Speter update_temp_slot_address (oldx, x); 50518334Speter 50618334Speter return x; 50718334Speter} 50818334Speter 50918334Speter/* Like `memory_address' but pretend `flag_force_addr' is 0. */ 51018334Speter 51118334Speterrtx 512132718Skanmemory_address_noforce (enum machine_mode mode, rtx x) 51318334Speter{ 51418334Speter int ambient_force_addr = flag_force_addr; 51518334Speter rtx val; 51618334Speter 51718334Speter flag_force_addr = 0; 51818334Speter val = memory_address (mode, x); 51918334Speter flag_force_addr = ambient_force_addr; 52018334Speter return val; 52118334Speter} 52218334Speter 52318334Speter/* Convert a mem ref into one with a valid memory address. 52418334Speter Pass through anything else unchanged. */ 52518334Speter 52618334Speterrtx 527132718Skanvalidize_mem (rtx ref) 52818334Speter{ 529169689Skan if (!MEM_P (ref)) 53018334Speter return ref; 531169689Skan ref = use_anchored_address (ref); 53290075Sobrien if (! (flag_force_addr && CONSTANT_ADDRESS_P (XEXP (ref, 0))) 53390075Sobrien && memory_address_p (GET_MODE (ref), XEXP (ref, 0))) 53418334Speter return ref; 53590075Sobrien 53618334Speter /* Don't alter REF itself, since that is probably a stack slot. */ 53790075Sobrien return replace_equiv_address (ref, XEXP (ref, 0)); 53818334Speter} 53990075Sobrien 540169689Skan/* If X is a memory reference to a member of an object block, try rewriting 541169689Skan it to use an anchor instead. Return the new memory reference on success 542169689Skan and the old one on failure. */ 543117395Skan 54418334Speterrtx 545169689Skanuse_anchored_address (rtx x) 54618334Speter{ 547169689Skan rtx base; 548169689Skan HOST_WIDE_INT offset; 549169689Skan 550169689Skan if (!flag_section_anchors) 55118334Speter return x; 55218334Speter 553169689Skan if (!MEM_P (x)) 554169689Skan return x; 555169689Skan 556169689Skan /* Split the address into a base and offset. */ 557169689Skan base = XEXP (x, 0); 558169689Skan offset = 0; 559169689Skan if (GET_CODE (base) == CONST 560169689Skan && GET_CODE (XEXP (base, 0)) == PLUS 561169689Skan && GET_CODE (XEXP (XEXP (base, 0), 1)) == CONST_INT) 562169689Skan { 563169689Skan offset += INTVAL (XEXP (XEXP (base, 0), 1)); 564169689Skan base = XEXP (XEXP (base, 0), 0); 565169689Skan } 566169689Skan 567169689Skan /* Check whether BASE is suitable for anchors. */ 568169689Skan if (GET_CODE (base) != SYMBOL_REF 569169689Skan || !SYMBOL_REF_HAS_BLOCK_INFO_P (base) 570169689Skan || SYMBOL_REF_ANCHOR_P (base) 571169689Skan || SYMBOL_REF_BLOCK (base) == NULL 572169689Skan || !targetm.use_anchors_for_symbol_p (base)) 573169689Skan return x; 574169689Skan 575169689Skan /* Decide where BASE is going to be. */ 576169689Skan place_block_symbol (base); 577169689Skan 578169689Skan /* Get the anchor we need to use. */ 579169689Skan offset += SYMBOL_REF_BLOCK_OFFSET (base); 580169689Skan base = get_section_anchor (SYMBOL_REF_BLOCK (base), offset, 581169689Skan SYMBOL_REF_TLS_MODEL (base)); 582169689Skan 583169689Skan /* Work out the offset from the anchor. */ 584169689Skan offset -= SYMBOL_REF_BLOCK_OFFSET (base); 585169689Skan 586169689Skan /* If we're going to run a CSE pass, force the anchor into a register. 587169689Skan We will then be able to reuse registers for several accesses, if the 588169689Skan target costs say that that's worthwhile. */ 589169689Skan if (!cse_not_expected) 590169689Skan base = force_reg (GET_MODE (base), base); 591169689Skan 592169689Skan return replace_equiv_address (x, plus_constant (base, offset)); 59318334Speter} 59418334Speter 59518334Speter/* Copy the value or contents of X to a new temp reg and return that reg. */ 59618334Speter 59718334Speterrtx 598132718Skancopy_to_reg (rtx x) 59918334Speter{ 60090075Sobrien rtx temp = gen_reg_rtx (GET_MODE (x)); 60196263Sobrien 60218334Speter /* If not an operand, must be an address with PLUS and MULT so 60396263Sobrien do the computation. */ 60418334Speter if (! general_operand (x, VOIDmode)) 60518334Speter x = force_operand (x, temp); 60696263Sobrien 60718334Speter if (x != temp) 60818334Speter emit_move_insn (temp, x); 60918334Speter 61018334Speter return temp; 61118334Speter} 61218334Speter 61318334Speter/* Like copy_to_reg but always give the new register mode Pmode 61418334Speter in case X is a constant. */ 61518334Speter 61618334Speterrtx 617132718Skancopy_addr_to_reg (rtx x) 61818334Speter{ 61918334Speter return copy_to_mode_reg (Pmode, x); 62018334Speter} 62118334Speter 62218334Speter/* Like copy_to_reg but always give the new register mode MODE 62318334Speter in case X is a constant. */ 62418334Speter 62518334Speterrtx 626132718Skancopy_to_mode_reg (enum machine_mode mode, rtx x) 62718334Speter{ 62890075Sobrien rtx temp = gen_reg_rtx (mode); 62996263Sobrien 63018334Speter /* If not an operand, must be an address with PLUS and MULT so 63196263Sobrien do the computation. */ 63218334Speter if (! general_operand (x, VOIDmode)) 63318334Speter x = force_operand (x, temp); 63418334Speter 635169689Skan gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode); 63618334Speter if (x != temp) 63718334Speter emit_move_insn (temp, x); 63818334Speter return temp; 63918334Speter} 64018334Speter 64118334Speter/* Load X into a register if it is not already one. 64218334Speter Use mode MODE for the register. 64318334Speter X should be valid for mode MODE, but it may be a constant which 64418334Speter is valid for all integer modes; that's why caller must specify MODE. 64518334Speter 64618334Speter The caller must not alter the value in the register we return, 64718334Speter since we mark it as a "constant" register. */ 64818334Speter 64918334Speterrtx 650132718Skanforce_reg (enum machine_mode mode, rtx x) 65118334Speter{ 65290075Sobrien rtx temp, insn, set; 65318334Speter 654169689Skan if (REG_P (x)) 65518334Speter return x; 65618334Speter 65796263Sobrien if (general_operand (x, mode)) 65896263Sobrien { 65996263Sobrien temp = gen_reg_rtx (mode); 66096263Sobrien insn = emit_move_insn (temp, x); 66196263Sobrien } 66296263Sobrien else 66396263Sobrien { 66496263Sobrien temp = force_operand (x, NULL_RTX); 665169689Skan if (REG_P (temp)) 66696263Sobrien insn = get_last_insn (); 66796263Sobrien else 66896263Sobrien { 66996263Sobrien rtx temp2 = gen_reg_rtx (mode); 67096263Sobrien insn = emit_move_insn (temp2, temp); 67196263Sobrien temp = temp2; 67296263Sobrien } 67396263Sobrien } 67496263Sobrien 67518334Speter /* Let optimizers know that TEMP's value never changes 67618334Speter and that X can be substituted for it. Don't get confused 67718334Speter if INSN set something else (such as a SUBREG of TEMP). */ 67818334Speter if (CONSTANT_P (x) 67918334Speter && (set = single_set (insn)) != 0 680132718Skan && SET_DEST (set) == temp 681132718Skan && ! rtx_equal_p (x, SET_SRC (set))) 68290075Sobrien set_unique_reg_note (insn, REG_EQUAL, x); 68396263Sobrien 684169689Skan /* Let optimizers know that TEMP is a pointer, and if so, the 685169689Skan known alignment of that pointer. */ 686169689Skan { 687169689Skan unsigned align = 0; 688169689Skan if (GET_CODE (x) == SYMBOL_REF) 689169689Skan { 690169689Skan align = BITS_PER_UNIT; 691169689Skan if (SYMBOL_REF_DECL (x) && DECL_P (SYMBOL_REF_DECL (x))) 692169689Skan align = DECL_ALIGN (SYMBOL_REF_DECL (x)); 693169689Skan } 694169689Skan else if (GET_CODE (x) == LABEL_REF) 695169689Skan align = BITS_PER_UNIT; 696169689Skan else if (GET_CODE (x) == CONST 697169689Skan && GET_CODE (XEXP (x, 0)) == PLUS 698169689Skan && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF 699169689Skan && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) 700169689Skan { 701169689Skan rtx s = XEXP (XEXP (x, 0), 0); 702169689Skan rtx c = XEXP (XEXP (x, 0), 1); 703169689Skan unsigned sa, ca; 704169689Skan 705169689Skan sa = BITS_PER_UNIT; 706169689Skan if (SYMBOL_REF_DECL (s) && DECL_P (SYMBOL_REF_DECL (s))) 707169689Skan sa = DECL_ALIGN (SYMBOL_REF_DECL (s)); 708169689Skan 709169689Skan ca = exact_log2 (INTVAL (c) & -INTVAL (c)) * BITS_PER_UNIT; 710169689Skan 711169689Skan align = MIN (sa, ca); 712169689Skan } 713169689Skan else if (MEM_P (x) && MEM_POINTER (x)) 714169689Skan align = MEM_ALIGN (x); 715169689Skan 716169689Skan if (align) 717169689Skan mark_reg_pointer (temp, align); 718169689Skan } 719169689Skan 72018334Speter return temp; 72118334Speter} 72218334Speter 72318334Speter/* If X is a memory ref, copy its contents to a new temp reg and return 72418334Speter that reg. Otherwise, return X. */ 72518334Speter 72618334Speterrtx 727132718Skanforce_not_mem (rtx x) 72818334Speter{ 72990075Sobrien rtx temp; 73090075Sobrien 731169689Skan if (!MEM_P (x) || GET_MODE (x) == BLKmode) 73218334Speter return x; 73390075Sobrien 73418334Speter temp = gen_reg_rtx (GET_MODE (x)); 735169689Skan 736169689Skan if (MEM_POINTER (x)) 737169689Skan REG_POINTER (temp) = 1; 738169689Skan 73918334Speter emit_move_insn (temp, x); 74018334Speter return temp; 74118334Speter} 74218334Speter 74318334Speter/* Copy X to TARGET (if it's nonzero and a reg) 74418334Speter or to a new temp reg and return that reg. 74518334Speter MODE is the mode to use for X in case it is a constant. */ 74618334Speter 74718334Speterrtx 748132718Skancopy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode) 74918334Speter{ 75090075Sobrien rtx temp; 75118334Speter 752169689Skan if (target && REG_P (target)) 75318334Speter temp = target; 75418334Speter else 75518334Speter temp = gen_reg_rtx (mode); 75618334Speter 75718334Speter emit_move_insn (temp, x); 75818334Speter return temp; 75918334Speter} 76018334Speter 76118334Speter/* Return the mode to use to store a scalar of TYPE and MODE. 76218334Speter PUNSIGNEDP points to the signedness of the type and may be adjusted 76318334Speter to show what signedness to use on extension operations. 76418334Speter 765117395Skan FOR_CALL is nonzero if this call is promoting args for a call. */ 76618334Speter 767169689Skan#if defined(PROMOTE_MODE) && !defined(PROMOTE_FUNCTION_MODE) 768169689Skan#define PROMOTE_FUNCTION_MODE PROMOTE_MODE 769169689Skan#endif 770169689Skan 77118334Speterenum machine_mode 772132718Skanpromote_mode (tree type, enum machine_mode mode, int *punsignedp, 773132718Skan int for_call ATTRIBUTE_UNUSED) 77418334Speter{ 77518334Speter enum tree_code code = TREE_CODE (type); 77618334Speter int unsignedp = *punsignedp; 77718334Speter 778169689Skan#ifndef PROMOTE_MODE 77918334Speter if (! for_call) 78018334Speter return mode; 78118334Speter#endif 78218334Speter 78318334Speter switch (code) 78418334Speter { 785169689Skan#ifdef PROMOTE_FUNCTION_MODE 786169689Skan case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: 787169689Skan case REAL_TYPE: case OFFSET_TYPE: 78818334Speter#ifdef PROMOTE_MODE 789169689Skan if (for_call) 790169689Skan { 791169689Skan#endif 792169689Skan PROMOTE_FUNCTION_MODE (mode, unsignedp, type); 793169689Skan#ifdef PROMOTE_MODE 794169689Skan } 795169689Skan else 796169689Skan { 797169689Skan PROMOTE_MODE (mode, unsignedp, type); 798169689Skan } 799169689Skan#endif 80018334Speter break; 80118334Speter#endif 80218334Speter 80318334Speter#ifdef POINTERS_EXTEND_UNSIGNED 80450397Sobrien case REFERENCE_TYPE: 80518334Speter case POINTER_TYPE: 80618334Speter mode = Pmode; 80718334Speter unsignedp = POINTERS_EXTEND_UNSIGNED; 80818334Speter break; 80918334Speter#endif 81096263Sobrien 81150397Sobrien default: 81250397Sobrien break; 81318334Speter } 81418334Speter 81518334Speter *punsignedp = unsignedp; 81618334Speter return mode; 81718334Speter} 81818334Speter 81918334Speter/* Adjust the stack pointer by ADJUST (an rtx for a number of bytes). 82018334Speter This pops when ADJUST is positive. ADJUST need not be constant. */ 82118334Speter 82218334Spetervoid 823132718Skanadjust_stack (rtx adjust) 82418334Speter{ 82518334Speter rtx temp; 82618334Speter 82718334Speter if (adjust == const0_rtx) 82818334Speter return; 82918334Speter 83090075Sobrien /* We expect all variable sized adjustments to be multiple of 83190075Sobrien PREFERRED_STACK_BOUNDARY. */ 83290075Sobrien if (GET_CODE (adjust) == CONST_INT) 83390075Sobrien stack_pointer_delta -= INTVAL (adjust); 83490075Sobrien 83518334Speter temp = expand_binop (Pmode, 83618334Speter#ifdef STACK_GROWS_DOWNWARD 83718334Speter add_optab, 83818334Speter#else 83918334Speter sub_optab, 84018334Speter#endif 84118334Speter stack_pointer_rtx, adjust, stack_pointer_rtx, 0, 84218334Speter OPTAB_LIB_WIDEN); 84318334Speter 84418334Speter if (temp != stack_pointer_rtx) 84518334Speter emit_move_insn (stack_pointer_rtx, temp); 84618334Speter} 84718334Speter 84818334Speter/* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes). 84918334Speter This pushes when ADJUST is positive. ADJUST need not be constant. */ 85018334Speter 85118334Spetervoid 852132718Skananti_adjust_stack (rtx adjust) 85318334Speter{ 85418334Speter rtx temp; 85518334Speter 85618334Speter if (adjust == const0_rtx) 85718334Speter return; 85818334Speter 85990075Sobrien /* We expect all variable sized adjustments to be multiple of 86090075Sobrien PREFERRED_STACK_BOUNDARY. */ 86190075Sobrien if (GET_CODE (adjust) == CONST_INT) 86290075Sobrien stack_pointer_delta += INTVAL (adjust); 86390075Sobrien 86418334Speter temp = expand_binop (Pmode, 86518334Speter#ifdef STACK_GROWS_DOWNWARD 86618334Speter sub_optab, 86718334Speter#else 86818334Speter add_optab, 86918334Speter#endif 87018334Speter stack_pointer_rtx, adjust, stack_pointer_rtx, 0, 87118334Speter OPTAB_LIB_WIDEN); 87218334Speter 87318334Speter if (temp != stack_pointer_rtx) 87418334Speter emit_move_insn (stack_pointer_rtx, temp); 87518334Speter} 87618334Speter 87718334Speter/* Round the size of a block to be pushed up to the boundary required 87818334Speter by this machine. SIZE is the desired size, which need not be constant. */ 87918334Speter 880169689Skanstatic rtx 881132718Skanround_push (rtx size) 88218334Speter{ 88352284Sobrien int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; 884132718Skan 88518334Speter if (align == 1) 88618334Speter return size; 887132718Skan 88818334Speter if (GET_CODE (size) == CONST_INT) 88918334Speter { 890132718Skan HOST_WIDE_INT new = (INTVAL (size) + align - 1) / align * align; 891132718Skan 89218334Speter if (INTVAL (size) != new) 89318334Speter size = GEN_INT (new); 89418334Speter } 89518334Speter else 89618334Speter { 89718334Speter /* CEIL_DIV_EXPR needs to worry about the addition overflowing, 89850397Sobrien but we know it can't. So add ourselves and then do 89950397Sobrien TRUNC_DIV_EXPR. */ 90018334Speter size = expand_binop (Pmode, add_optab, size, GEN_INT (align - 1), 90118334Speter NULL_RTX, 1, OPTAB_LIB_WIDEN); 90218334Speter size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, GEN_INT (align), 90318334Speter NULL_RTX, 1); 90418334Speter size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1); 90518334Speter } 906132718Skan 90718334Speter return size; 90818334Speter} 90918334Speter 91018334Speter/* Save the stack pointer for the purpose in SAVE_LEVEL. PSAVE is a pointer 91118334Speter to a previously-created save area. If no save area has been allocated, 91218334Speter this function will allocate one. If a save area is specified, it 91318334Speter must be of the proper mode. 91418334Speter 91518334Speter The insns are emitted after insn AFTER, if nonzero, otherwise the insns 91618334Speter are emitted at the current position. */ 91718334Speter 91818334Spetervoid 919132718Skanemit_stack_save (enum save_level save_level, rtx *psave, rtx after) 92018334Speter{ 92118334Speter rtx sa = *psave; 92218334Speter /* The default is that we use a move insn and save in a Pmode object. */ 923132718Skan rtx (*fcn) (rtx, rtx) = gen_move_insn; 92450397Sobrien enum machine_mode mode = STACK_SAVEAREA_MODE (save_level); 92518334Speter 92618334Speter /* See if this machine has anything special to do for this kind of save. */ 92718334Speter switch (save_level) 92818334Speter { 92918334Speter#ifdef HAVE_save_stack_block 93018334Speter case SAVE_BLOCK: 93118334Speter if (HAVE_save_stack_block) 93250397Sobrien fcn = gen_save_stack_block; 93318334Speter break; 93418334Speter#endif 93518334Speter#ifdef HAVE_save_stack_function 93618334Speter case SAVE_FUNCTION: 93718334Speter if (HAVE_save_stack_function) 93850397Sobrien fcn = gen_save_stack_function; 93918334Speter break; 94018334Speter#endif 94118334Speter#ifdef HAVE_save_stack_nonlocal 94218334Speter case SAVE_NONLOCAL: 94318334Speter if (HAVE_save_stack_nonlocal) 94450397Sobrien fcn = gen_save_stack_nonlocal; 94518334Speter break; 94618334Speter#endif 94750397Sobrien default: 94850397Sobrien break; 94918334Speter } 95018334Speter 95118334Speter /* If there is no save area and we have to allocate one, do so. Otherwise 95218334Speter verify the save area is the proper mode. */ 95318334Speter 95418334Speter if (sa == 0) 95518334Speter { 95618334Speter if (mode != VOIDmode) 95718334Speter { 95818334Speter if (save_level == SAVE_NONLOCAL) 95918334Speter *psave = sa = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); 96018334Speter else 96118334Speter *psave = sa = gen_reg_rtx (mode); 96218334Speter } 96318334Speter } 96418334Speter 96518334Speter if (after) 96618334Speter { 96718334Speter rtx seq; 96818334Speter 96918334Speter start_sequence (); 970146895Skan do_pending_stack_adjust (); 97118334Speter /* We must validize inside the sequence, to ensure that any instructions 97218334Speter created by the validize call also get moved to the right place. */ 97318334Speter if (sa != 0) 97418334Speter sa = validize_mem (sa); 97518334Speter emit_insn (fcn (sa, stack_pointer_rtx)); 976117395Skan seq = get_insns (); 97718334Speter end_sequence (); 97818334Speter emit_insn_after (seq, after); 97918334Speter } 98018334Speter else 98118334Speter { 982146895Skan do_pending_stack_adjust (); 98318334Speter if (sa != 0) 98418334Speter sa = validize_mem (sa); 98518334Speter emit_insn (fcn (sa, stack_pointer_rtx)); 98618334Speter } 98718334Speter} 98818334Speter 98918334Speter/* Restore the stack pointer for the purpose in SAVE_LEVEL. SA is the save 99096263Sobrien area made by emit_stack_save. If it is zero, we have nothing to do. 99118334Speter 99296263Sobrien Put any emitted insns after insn AFTER, if nonzero, otherwise at 99318334Speter current position. */ 99418334Speter 99518334Spetervoid 996132718Skanemit_stack_restore (enum save_level save_level, rtx sa, rtx after) 99718334Speter{ 99818334Speter /* The default is that we use a move insn. */ 999132718Skan rtx (*fcn) (rtx, rtx) = gen_move_insn; 100018334Speter 100118334Speter /* See if this machine has anything special to do for this kind of save. */ 100218334Speter switch (save_level) 100318334Speter { 100418334Speter#ifdef HAVE_restore_stack_block 100518334Speter case SAVE_BLOCK: 100618334Speter if (HAVE_restore_stack_block) 100718334Speter fcn = gen_restore_stack_block; 100818334Speter break; 100918334Speter#endif 101018334Speter#ifdef HAVE_restore_stack_function 101118334Speter case SAVE_FUNCTION: 101218334Speter if (HAVE_restore_stack_function) 101318334Speter fcn = gen_restore_stack_function; 101418334Speter break; 101518334Speter#endif 101618334Speter#ifdef HAVE_restore_stack_nonlocal 101718334Speter case SAVE_NONLOCAL: 101818334Speter if (HAVE_restore_stack_nonlocal) 101918334Speter fcn = gen_restore_stack_nonlocal; 102018334Speter break; 102118334Speter#endif 102250397Sobrien default: 102350397Sobrien break; 102418334Speter } 102518334Speter 102618334Speter if (sa != 0) 1027117395Skan { 1028117395Skan sa = validize_mem (sa); 1029117395Skan /* These clobbers prevent the scheduler from moving 1030117395Skan references to variable arrays below the code 1031117395Skan that deletes (pops) the arrays. */ 1032117395Skan emit_insn (gen_rtx_CLOBBER (VOIDmode, 1033132718Skan gen_rtx_MEM (BLKmode, 1034117395Skan gen_rtx_SCRATCH (VOIDmode)))); 1035117395Skan emit_insn (gen_rtx_CLOBBER (VOIDmode, 1036117395Skan gen_rtx_MEM (BLKmode, stack_pointer_rtx))); 1037117395Skan } 103818334Speter 1039146895Skan discard_pending_stack_adjust (); 1040146895Skan 104118334Speter if (after) 104218334Speter { 104318334Speter rtx seq; 104418334Speter 104518334Speter start_sequence (); 104618334Speter emit_insn (fcn (stack_pointer_rtx, sa)); 1047117395Skan seq = get_insns (); 104818334Speter end_sequence (); 104918334Speter emit_insn_after (seq, after); 105018334Speter } 105118334Speter else 105218334Speter emit_insn (fcn (stack_pointer_rtx, sa)); 105318334Speter} 105450397Sobrien 1055169689Skan/* Invoke emit_stack_save on the nonlocal_goto_save_area for the current 1056169689Skan function. This function should be called whenever we allocate or 1057169689Skan deallocate dynamic stack space. */ 1058169689Skan 105950397Sobrienvoid 1060169689Skanupdate_nonlocal_goto_save_area (void) 106150397Sobrien{ 1062169689Skan tree t_save; 1063169689Skan rtx r_save; 106450397Sobrien 1065169689Skan /* The nonlocal_goto_save_area object is an array of N pointers. The 1066169689Skan first one is used for the frame pointer save; the rest are sized by 1067169689Skan STACK_SAVEAREA_MODE. Create a reference to array index 1, the first 1068169689Skan of the stack save area slots. */ 1069169689Skan t_save = build4 (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area, 1070169689Skan integer_one_node, NULL_TREE, NULL_TREE); 1071169689Skan r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE); 107250397Sobrien 1073169689Skan emit_stack_save (SAVE_NONLOCAL, &r_save, NULL_RTX); 107450397Sobrien} 1075169689Skan 107618334Speter/* Return an rtx representing the address of an area of memory dynamically 107718334Speter pushed on the stack. This region of memory is always aligned to 107818334Speter a multiple of BIGGEST_ALIGNMENT. 107918334Speter 108018334Speter Any required stack pointer alignment is preserved. 108118334Speter 108218334Speter SIZE is an rtx representing the size of the area. 108318334Speter TARGET is a place in which the address can be placed. 108418334Speter 108518334Speter KNOWN_ALIGN is the alignment (in bits) that we know SIZE has. */ 108618334Speter 108718334Speterrtx 1088132718Skanallocate_dynamic_stack_space (rtx size, rtx target, int known_align) 108918334Speter{ 109018334Speter /* If we're asking for zero bytes, it doesn't matter what we point 109118334Speter to since we can't dereference it. But return a reasonable 109218334Speter address anyway. */ 109318334Speter if (size == const0_rtx) 109418334Speter return virtual_stack_dynamic_rtx; 109518334Speter 109618334Speter /* Otherwise, show we're calling alloca or equivalent. */ 109718334Speter current_function_calls_alloca = 1; 109818334Speter 109918334Speter /* Ensure the size is in the proper mode. */ 110018334Speter if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode) 110118334Speter size = convert_to_mode (Pmode, size, 1); 110218334Speter 110390075Sobrien /* We can't attempt to minimize alignment necessary, because we don't 110490075Sobrien know the final value of preferred_stack_boundary yet while executing 110590075Sobrien this code. */ 110690075Sobrien cfun->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY; 110790075Sobrien 110818334Speter /* We will need to ensure that the address we return is aligned to 110918334Speter BIGGEST_ALIGNMENT. If STACK_DYNAMIC_OFFSET is defined, we don't 111096263Sobrien always know its final value at this point in the compilation (it 111118334Speter might depend on the size of the outgoing parameter lists, for 111218334Speter example), so we must align the value to be returned in that case. 1113117395Skan (Note that STACK_DYNAMIC_OFFSET will have a default nonzero value if 111418334Speter STACK_POINTER_OFFSET or ACCUMULATE_OUTGOING_ARGS are defined). 111518334Speter We must also do an alignment operation on the returned value if 111618334Speter the stack pointer alignment is less strict that BIGGEST_ALIGNMENT. 111718334Speter 111818334Speter If we have to align, we must leave space in SIZE for the hole 111918334Speter that might result from the alignment operation. */ 112018334Speter 112190075Sobrien#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET) 112218334Speter#define MUST_ALIGN 1 112318334Speter#else 112452284Sobrien#define MUST_ALIGN (PREFERRED_STACK_BOUNDARY < BIGGEST_ALIGNMENT) 112518334Speter#endif 112618334Speter 112718334Speter if (MUST_ALIGN) 112890075Sobrien size 112996263Sobrien = force_operand (plus_constant (size, 113090075Sobrien BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1), 113190075Sobrien NULL_RTX); 113218334Speter 113318334Speter#ifdef SETJMP_VIA_SAVE_AREA 113418334Speter /* If setjmp restores regs from a save area in the stack frame, 113518334Speter avoid clobbering the reg save area. Note that the offset of 113618334Speter virtual_incoming_args_rtx includes the preallocated stack args space. 113718334Speter It would be no problem to clobber that, but it's on the wrong side 1138169689Skan of the old save area. 113950397Sobrien 1140169689Skan What used to happen is that, since we did not know for sure 1141169689Skan whether setjmp() was invoked until after RTL generation, we 1142169689Skan would use reg notes to store the "optimized" size and fix things 1143169689Skan up later. These days we know this information before we ever 1144169689Skan start building RTL so the reg notes are unnecessary. */ 1145169689Skan if (!current_function_calls_setjmp) 1146169689Skan { 1147169689Skan int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; 114850397Sobrien 1149169689Skan /* ??? Code below assumes that the save area needs maximal 1150169689Skan alignment. This constraint may be too strong. */ 1151169689Skan gcc_assert (PREFERRED_STACK_BOUNDARY == BIGGEST_ALIGNMENT); 115250397Sobrien 1153169689Skan if (GET_CODE (size) == CONST_INT) 1154169689Skan { 1155169689Skan HOST_WIDE_INT new = INTVAL (size) / align * align; 115650397Sobrien 1157169689Skan if (INTVAL (size) != new) 1158169689Skan size = GEN_INT (new); 1159169689Skan } 1160169689Skan else 1161169689Skan { 1162169689Skan /* Since we know overflow is not possible, we avoid using 1163169689Skan CEIL_DIV_EXPR and use TRUNC_DIV_EXPR instead. */ 1164169689Skan size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, 1165169689Skan GEN_INT (align), NULL_RTX, 1); 1166169689Skan size = expand_mult (Pmode, size, 1167169689Skan GEN_INT (align), NULL_RTX, 1); 1168169689Skan } 1169169689Skan } 1170169689Skan else 1171169689Skan { 1172169689Skan rtx dynamic_offset 1173169689Skan = expand_binop (Pmode, sub_optab, virtual_stack_dynamic_rtx, 1174169689Skan stack_pointer_rtx, NULL_RTX, 1, OPTAB_LIB_WIDEN); 117550397Sobrien 1176169689Skan size = expand_binop (Pmode, add_optab, size, dynamic_offset, 1177169689Skan NULL_RTX, 1, OPTAB_LIB_WIDEN); 1178169689Skan } 117918334Speter#endif /* SETJMP_VIA_SAVE_AREA */ 118018334Speter 118118334Speter /* Round the size to a multiple of the required stack alignment. 118218334Speter Since the stack if presumed to be rounded before this allocation, 118318334Speter this will maintain the required alignment. 118418334Speter 118518334Speter If the stack grows downward, we could save an insn by subtracting 118618334Speter SIZE from the stack pointer and then aligning the stack pointer. 118718334Speter The problem with this is that the stack pointer may be unaligned 118818334Speter between the execution of the subtraction and alignment insns and 118918334Speter some machines do not allow this. Even on those that do, some 119018334Speter signal handlers malfunction if a signal should occur between those 119118334Speter insns. Since this is an extremely rare event, we have no reliable 119218334Speter way of knowing which systems have this problem. So we avoid even 119318334Speter momentarily mis-aligning the stack. */ 119418334Speter 119518334Speter /* If we added a variable amount to SIZE, 119618334Speter we can no longer assume it is aligned. */ 119718334Speter#if !defined (SETJMP_VIA_SAVE_AREA) 119852284Sobrien if (MUST_ALIGN || known_align % PREFERRED_STACK_BOUNDARY != 0) 119918334Speter#endif 120018334Speter size = round_push (size); 120118334Speter 120218334Speter do_pending_stack_adjust (); 120318334Speter 120490075Sobrien /* We ought to be called always on the toplevel and stack ought to be aligned 120590075Sobrien properly. */ 1206169689Skan gcc_assert (!(stack_pointer_delta 1207169689Skan % (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT))); 120890075Sobrien 120950397Sobrien /* If needed, check that we have the required amount of stack. Take into 121050397Sobrien account what has already been checked. */ 121150397Sobrien if (flag_stack_check && ! STACK_CHECK_BUILTIN) 121250397Sobrien probe_stack_range (STACK_CHECK_MAX_FRAME_SIZE + STACK_CHECK_PROTECT, size); 121350397Sobrien 121490075Sobrien /* Don't use a TARGET that isn't a pseudo or is the wrong mode. */ 1215169689Skan if (target == 0 || !REG_P (target) 121690075Sobrien || REGNO (target) < FIRST_PSEUDO_REGISTER 121790075Sobrien || GET_MODE (target) != Pmode) 121818334Speter target = gen_reg_rtx (Pmode); 121918334Speter 122090075Sobrien mark_reg_pointer (target, known_align); 122118334Speter 122218334Speter /* Perform the required allocation from the stack. Some systems do 122318334Speter this differently than simply incrementing/decrementing from the 122450397Sobrien stack pointer, such as acquiring the space by calling malloc(). */ 122518334Speter#ifdef HAVE_allocate_stack 122618334Speter if (HAVE_allocate_stack) 122718334Speter { 122850397Sobrien enum machine_mode mode = STACK_SIZE_MODE; 122990075Sobrien insn_operand_predicate_fn pred; 123018334Speter 123190075Sobrien /* We don't have to check against the predicate for operand 0 since 123290075Sobrien TARGET is known to be a pseudo of the proper mode, which must 123390075Sobrien be valid for the operand. For operand 1, convert to the 123490075Sobrien proper mode and validate. */ 123590075Sobrien if (mode == VOIDmode) 123690075Sobrien mode = insn_data[(int) CODE_FOR_allocate_stack].operand[1].mode; 123790075Sobrien 123890075Sobrien pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate; 123990075Sobrien if (pred && ! ((*pred) (size, mode))) 1240132718Skan size = copy_to_mode_reg (mode, convert_to_mode (mode, size, 1)); 124118334Speter 124250397Sobrien emit_insn (gen_allocate_stack (target, size)); 124318334Speter } 124418334Speter else 124518334Speter#endif 124618334Speter { 124750397Sobrien#ifndef STACK_GROWS_DOWNWARD 124850397Sobrien emit_move_insn (target, virtual_stack_dynamic_rtx); 124950397Sobrien#endif 125090075Sobrien 125190075Sobrien /* Check stack bounds if necessary. */ 125290075Sobrien if (current_function_limit_stack) 125390075Sobrien { 125490075Sobrien rtx available; 125590075Sobrien rtx space_available = gen_label_rtx (); 125690075Sobrien#ifdef STACK_GROWS_DOWNWARD 125796263Sobrien available = expand_binop (Pmode, sub_optab, 125890075Sobrien stack_pointer_rtx, stack_limit_rtx, 125990075Sobrien NULL_RTX, 1, OPTAB_WIDEN); 126090075Sobrien#else 126196263Sobrien available = expand_binop (Pmode, sub_optab, 126290075Sobrien stack_limit_rtx, stack_pointer_rtx, 126390075Sobrien NULL_RTX, 1, OPTAB_WIDEN); 126490075Sobrien#endif 126590075Sobrien emit_cmp_and_jump_insns (available, size, GEU, NULL_RTX, Pmode, 1, 126690075Sobrien space_available); 126790075Sobrien#ifdef HAVE_trap 126890075Sobrien if (HAVE_trap) 126990075Sobrien emit_insn (gen_trap ()); 127090075Sobrien else 127190075Sobrien#endif 127290075Sobrien error ("stack limits not supported on this target"); 127390075Sobrien emit_barrier (); 127490075Sobrien emit_label (space_available); 127590075Sobrien } 127690075Sobrien 127718334Speter anti_adjust_stack (size); 127818334Speter 127918334Speter#ifdef STACK_GROWS_DOWNWARD 128096263Sobrien emit_move_insn (target, virtual_stack_dynamic_rtx); 128118334Speter#endif 128250397Sobrien } 128318334Speter 128418334Speter if (MUST_ALIGN) 128518334Speter { 128618334Speter /* CEIL_DIV_EXPR needs to worry about the addition overflowing, 128750397Sobrien but we know it can't. So add ourselves and then do 128850397Sobrien TRUNC_DIV_EXPR. */ 128918334Speter target = expand_binop (Pmode, add_optab, target, 129018334Speter GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1), 129118334Speter NULL_RTX, 1, OPTAB_LIB_WIDEN); 129218334Speter target = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, target, 129318334Speter GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT), 129418334Speter NULL_RTX, 1); 129518334Speter target = expand_mult (Pmode, target, 129618334Speter GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT), 129718334Speter NULL_RTX, 1); 129818334Speter } 129996263Sobrien 130018334Speter /* Record the new stack level for nonlocal gotos. */ 1301169689Skan if (cfun->nonlocal_goto_save_area != 0) 1302169689Skan update_nonlocal_goto_save_area (); 130318334Speter 130418334Speter return target; 130518334Speter} 130618334Speter 130796263Sobrien/* A front end may want to override GCC's stack checking by providing a 130890075Sobrien run-time routine to call to check the stack, so provide a mechanism for 130990075Sobrien calling that routine. */ 131090075Sobrien 1311117395Skanstatic GTY(()) rtx stack_check_libfunc; 131290075Sobrien 131390075Sobrienvoid 1314132718Skanset_stack_check_libfunc (rtx libfunc) 131590075Sobrien{ 131690075Sobrien stack_check_libfunc = libfunc; 131790075Sobrien} 131890075Sobrien 131950397Sobrien/* Emit one stack probe at ADDRESS, an address within the stack. */ 132050397Sobrien 132150397Sobrienstatic void 1322132718Skanemit_stack_probe (rtx address) 132350397Sobrien{ 132450397Sobrien rtx memref = gen_rtx_MEM (word_mode, address); 132550397Sobrien 132650397Sobrien MEM_VOLATILE_P (memref) = 1; 132750397Sobrien 132850397Sobrien if (STACK_CHECK_PROBE_LOAD) 132950397Sobrien emit_move_insn (gen_reg_rtx (word_mode), memref); 133050397Sobrien else 133150397Sobrien emit_move_insn (memref, const0_rtx); 133250397Sobrien} 133350397Sobrien 133496263Sobrien/* Probe a range of stack addresses from FIRST to FIRST+SIZE, inclusive. 133550397Sobrien FIRST is a constant and size is a Pmode RTX. These are offsets from the 133650397Sobrien current stack pointer. STACK_GROWS_DOWNWARD says whether to add or 133750397Sobrien subtract from the stack. If SIZE is constant, this is done 133850397Sobrien with a fixed number of probes. Otherwise, we must make a loop. */ 133950397Sobrien 134050397Sobrien#ifdef STACK_GROWS_DOWNWARD 134150397Sobrien#define STACK_GROW_OP MINUS 134250397Sobrien#else 134350397Sobrien#define STACK_GROW_OP PLUS 134450397Sobrien#endif 134550397Sobrien 134650397Sobrienvoid 1347132718Skanprobe_stack_range (HOST_WIDE_INT first, rtx size) 134850397Sobrien{ 134990075Sobrien /* First ensure SIZE is Pmode. */ 135090075Sobrien if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode) 135190075Sobrien size = convert_to_mode (Pmode, size, 1); 135290075Sobrien 135390075Sobrien /* Next see if the front end has set up a function for us to call to 135490075Sobrien check the stack. */ 135590075Sobrien if (stack_check_libfunc != 0) 135690075Sobrien { 135790075Sobrien rtx addr = memory_address (QImode, 1358117395Skan gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, 1359117395Skan stack_pointer_rtx, 1360117395Skan plus_constant (size, first))); 136190075Sobrien 1362132718Skan addr = convert_memory_address (ptr_mode, addr); 136390075Sobrien emit_library_call (stack_check_libfunc, LCT_NORMAL, VOIDmode, 1, addr, 136490075Sobrien ptr_mode); 136590075Sobrien } 136690075Sobrien 136790075Sobrien /* Next see if we have an insn to check the stack. Use it if so. */ 136850397Sobrien#ifdef HAVE_check_stack 136990075Sobrien else if (HAVE_check_stack) 137050397Sobrien { 137190075Sobrien insn_operand_predicate_fn pred; 137250397Sobrien rtx last_addr 1373117395Skan = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, 1374117395Skan stack_pointer_rtx, 1375117395Skan plus_constant (size, first)), 137650397Sobrien NULL_RTX); 137750397Sobrien 137890075Sobrien pred = insn_data[(int) CODE_FOR_check_stack].operand[0].predicate; 137990075Sobrien if (pred && ! ((*pred) (last_addr, Pmode))) 138090075Sobrien last_addr = copy_to_mode_reg (Pmode, last_addr); 138150397Sobrien 138290075Sobrien emit_insn (gen_check_stack (last_addr)); 138350397Sobrien } 138450397Sobrien#endif 138550397Sobrien 138650397Sobrien /* If we have to generate explicit probes, see if we have a constant 138750397Sobrien small number of them to generate. If so, that's the easy case. */ 138890075Sobrien else if (GET_CODE (size) == CONST_INT 138990075Sobrien && INTVAL (size) < 10 * STACK_CHECK_PROBE_INTERVAL) 139050397Sobrien { 139150397Sobrien HOST_WIDE_INT offset; 139250397Sobrien 139350397Sobrien /* Start probing at FIRST + N * STACK_CHECK_PROBE_INTERVAL 139450397Sobrien for values of N from 1 until it exceeds LAST. If only one 139550397Sobrien probe is needed, this will not generate any code. Then probe 139650397Sobrien at LAST. */ 139750397Sobrien for (offset = first + STACK_CHECK_PROBE_INTERVAL; 139850397Sobrien offset < INTVAL (size); 139950397Sobrien offset = offset + STACK_CHECK_PROBE_INTERVAL) 140050397Sobrien emit_stack_probe (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, 140150397Sobrien stack_pointer_rtx, 140250397Sobrien GEN_INT (offset))); 140350397Sobrien 140450397Sobrien emit_stack_probe (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, 140550397Sobrien stack_pointer_rtx, 140650397Sobrien plus_constant (size, first))); 140750397Sobrien } 140850397Sobrien 140950397Sobrien /* In the variable case, do the same as above, but in a loop. We emit loop 141050397Sobrien notes so that loop optimization can be done. */ 141150397Sobrien else 141250397Sobrien { 141350397Sobrien rtx test_addr 141450397Sobrien = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, 141550397Sobrien stack_pointer_rtx, 141650397Sobrien GEN_INT (first + STACK_CHECK_PROBE_INTERVAL)), 141750397Sobrien NULL_RTX); 141850397Sobrien rtx last_addr 141950397Sobrien = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, 142050397Sobrien stack_pointer_rtx, 142150397Sobrien plus_constant (size, first)), 142250397Sobrien NULL_RTX); 142350397Sobrien rtx incr = GEN_INT (STACK_CHECK_PROBE_INTERVAL); 142450397Sobrien rtx loop_lab = gen_label_rtx (); 142550397Sobrien rtx test_lab = gen_label_rtx (); 142650397Sobrien rtx end_lab = gen_label_rtx (); 142750397Sobrien rtx temp; 142850397Sobrien 1429169689Skan if (!REG_P (test_addr) 143050397Sobrien || REGNO (test_addr) < FIRST_PSEUDO_REGISTER) 143150397Sobrien test_addr = force_reg (Pmode, test_addr); 143250397Sobrien 143350397Sobrien emit_jump (test_lab); 143450397Sobrien 143550397Sobrien emit_label (loop_lab); 143650397Sobrien emit_stack_probe (test_addr); 143750397Sobrien 143850397Sobrien#ifdef STACK_GROWS_DOWNWARD 143950397Sobrien#define CMP_OPCODE GTU 144050397Sobrien temp = expand_binop (Pmode, sub_optab, test_addr, incr, test_addr, 144150397Sobrien 1, OPTAB_WIDEN); 144250397Sobrien#else 144350397Sobrien#define CMP_OPCODE LTU 144450397Sobrien temp = expand_binop (Pmode, add_optab, test_addr, incr, test_addr, 144550397Sobrien 1, OPTAB_WIDEN); 144650397Sobrien#endif 144750397Sobrien 1448169689Skan gcc_assert (temp == test_addr); 144950397Sobrien 145050397Sobrien emit_label (test_lab); 145152284Sobrien emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE, 145290075Sobrien NULL_RTX, Pmode, 1, loop_lab); 145350397Sobrien emit_jump (end_lab); 145450397Sobrien emit_label (end_lab); 145550397Sobrien 145650397Sobrien emit_stack_probe (last_addr); 145750397Sobrien } 145850397Sobrien} 145950397Sobrien 146018334Speter/* Return an rtx representing the register or memory location 146118334Speter in which a scalar value of data type VALTYPE 146218334Speter was returned by a function call to function FUNC. 1463169689Skan FUNC is a FUNCTION_DECL, FNTYPE a FUNCTION_TYPE node if the precise 1464169689Skan function is known, otherwise 0. 146590075Sobrien OUTGOING is 1 if on a machine with register windows this function 146690075Sobrien should return the register in which the function will put its result 146790075Sobrien and 0 otherwise. */ 146818334Speter 146918334Speterrtx 1470169689Skanhard_function_value (tree valtype, tree func, tree fntype, 1471132718Skan int outgoing ATTRIBUTE_UNUSED) 147218334Speter{ 147390075Sobrien rtx val; 147490075Sobrien 1475169689Skan val = targetm.calls.function_value (valtype, func ? func : fntype, outgoing); 147690075Sobrien 1477169689Skan if (REG_P (val) 147818334Speter && GET_MODE (val) == BLKmode) 147918334Speter { 148090075Sobrien unsigned HOST_WIDE_INT bytes = int_size_in_bytes (valtype); 148118334Speter enum machine_mode tmpmode; 148290075Sobrien 148396263Sobrien /* int_size_in_bytes can return -1. We don't need a check here 1484169689Skan since the value of bytes will then be large enough that no 1485169689Skan mode will match anyway. */ 148696263Sobrien 148718334Speter for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT); 1488117395Skan tmpmode != VOIDmode; 1489117395Skan tmpmode = GET_MODE_WIDER_MODE (tmpmode)) 1490117395Skan { 1491117395Skan /* Have we found a large enough mode? */ 1492117395Skan if (GET_MODE_SIZE (tmpmode) >= bytes) 1493117395Skan break; 1494117395Skan } 149518334Speter 149618334Speter /* No suitable mode found. */ 1497169689Skan gcc_assert (tmpmode != VOIDmode); 149818334Speter 149918334Speter PUT_MODE (val, tmpmode); 150096263Sobrien } 150118334Speter return val; 150218334Speter} 150318334Speter 150418334Speter/* Return an rtx representing the register or memory location 150518334Speter in which a scalar value of mode MODE was returned by a library call. */ 150618334Speter 150718334Speterrtx 1508132718Skanhard_libcall_value (enum machine_mode mode) 150918334Speter{ 151018334Speter return LIBCALL_VALUE (mode); 151118334Speter} 151218334Speter 151318334Speter/* Look up the tree code for a given rtx code 151418334Speter to provide the arithmetic operation for REAL_ARITHMETIC. 151518334Speter The function returns an int because the caller may not know 151618334Speter what `enum tree_code' means. */ 151718334Speter 151818334Speterint 1519132718Skanrtx_to_tree_code (enum rtx_code code) 152018334Speter{ 152118334Speter enum tree_code tcode; 152218334Speter 152318334Speter switch (code) 152418334Speter { 152518334Speter case PLUS: 152618334Speter tcode = PLUS_EXPR; 152718334Speter break; 152818334Speter case MINUS: 152918334Speter tcode = MINUS_EXPR; 153018334Speter break; 153118334Speter case MULT: 153218334Speter tcode = MULT_EXPR; 153318334Speter break; 153418334Speter case DIV: 153518334Speter tcode = RDIV_EXPR; 153618334Speter break; 153718334Speter case SMIN: 153818334Speter tcode = MIN_EXPR; 153918334Speter break; 154018334Speter case SMAX: 154118334Speter tcode = MAX_EXPR; 154218334Speter break; 154318334Speter default: 154418334Speter tcode = LAST_AND_UNUSED_TREE_CODE; 154518334Speter break; 154618334Speter } 154718334Speter return ((int) tcode); 154818334Speter} 1549117395Skan 1550117395Skan#include "gt-explow.h" 1551