|
|
1.1 ! root 1: /* Emit RTL for the GNU C-Compiler expander. ! 2: Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: /* Middle-to-low level generation of rtx code and insns. ! 22: ! 23: This file contains the functions `gen_rtx', `gen_reg_rtx' ! 24: and `gen_label_rtx' that are the usual ways of creating rtl ! 25: expressions for most purposes. ! 26: ! 27: It also has the functions for creating insns and linking ! 28: them in the doubly-linked chain. ! 29: ! 30: The patterns of the insns are created by machine-dependent ! 31: routines in insn-emit.c, which is generated automatically from ! 32: the machine description. These routines use `gen_rtx' to make ! 33: the individual rtx's of the pattern; what is machine dependent ! 34: is the kind of rtx's they make and what arguments they use. */ ! 35: ! 36: #include "config.h" ! 37: #include "gvarargs.h" ! 38: #include "rtl.h" ! 39: #include "tree.h" ! 40: #include "flags.h" ! 41: #include "function.h" ! 42: #include "expr.h" ! 43: #include "regs.h" ! 44: #include "insn-config.h" ! 45: #include "real.h" ! 46: #include "obstack.h" ! 47: ! 48: #include "bytecode.h" ! 49: #include "machmode.h" ! 50: #include "bc-opcode.h" ! 51: #include "bc-typecd.h" ! 52: #include "bc-optab.h" ! 53: #include "bc-emit.h" ! 54: ! 55: #include <stdio.h> ! 56: ! 57: ! 58: /* Opcode names */ ! 59: #ifdef BCDEBUG_PRINT_CODE ! 60: char *opcode_name[] = ! 61: { ! 62: #include "bc-opname.h" ! 63: ! 64: "***END***" ! 65: }; ! 66: #endif ! 67: ! 68: ! 69: /* Commonly used modes. */ ! 70: ! 71: enum machine_mode byte_mode; /* Mode whose width is BITS_PER_UNIT */ ! 72: enum machine_mode word_mode; /* Mode whose width is BITS_PER_WORD */ ! 73: ! 74: /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function. ! 75: After rtl generation, it is 1 plus the largest register number used. */ ! 76: ! 77: int reg_rtx_no = LAST_VIRTUAL_REGISTER + 1; ! 78: ! 79: /* This is *not* reset after each function. It gives each CODE_LABEL ! 80: in the entire compilation a unique label number. */ ! 81: ! 82: static int label_num = 1; ! 83: ! 84: /* Lowest label number in current function. */ ! 85: ! 86: static int first_label_num; ! 87: ! 88: /* Highest label number in current function. ! 89: Zero means use the value of label_num instead. ! 90: This is nonzero only when belatedly compiling an inline function. */ ! 91: ! 92: static int last_label_num; ! 93: ! 94: /* Value label_num had when set_new_first_and_last_label_number was called. ! 95: If label_num has not changed since then, last_label_num is valid. */ ! 96: ! 97: static int base_label_num; ! 98: ! 99: /* Nonzero means do not generate NOTEs for source line numbers. */ ! 100: ! 101: static int no_line_numbers; ! 102: ! 103: /* Commonly used rtx's, so that we only need space for one copy. ! 104: These are initialized once for the entire compilation. ! 105: All of these except perhaps the floating-point CONST_DOUBLEs ! 106: are unique; no other rtx-object will be equal to any of these. */ ! 107: ! 108: rtx pc_rtx; /* (PC) */ ! 109: rtx cc0_rtx; /* (CC0) */ ! 110: rtx cc1_rtx; /* (CC1) (not actually used nowadays) */ ! 111: rtx const0_rtx; /* (CONST_INT 0) */ ! 112: rtx const1_rtx; /* (CONST_INT 1) */ ! 113: rtx const2_rtx; /* (CONST_INT 2) */ ! 114: rtx constm1_rtx; /* (CONST_INT -1) */ ! 115: rtx const_true_rtx; /* (CONST_INT STORE_FLAG_VALUE) */ ! 116: ! 117: /* We record floating-point CONST_DOUBLEs in each floating-point mode for ! 118: the values of 0, 1, and 2. For the integer entries and VOIDmode, we ! 119: record a copy of const[012]_rtx. */ ! 120: ! 121: rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE]; ! 122: ! 123: REAL_VALUE_TYPE dconst0; ! 124: REAL_VALUE_TYPE dconst1; ! 125: REAL_VALUE_TYPE dconst2; ! 126: REAL_VALUE_TYPE dconstm1; ! 127: ! 128: /* All references to the following fixed hard registers go through ! 129: these unique rtl objects. On machines where the frame-pointer and ! 130: arg-pointer are the same register, they use the same unique object. ! 131: ! 132: After register allocation, other rtl objects which used to be pseudo-regs ! 133: may be clobbered to refer to the frame-pointer register. ! 134: But references that were originally to the frame-pointer can be ! 135: distinguished from the others because they contain frame_pointer_rtx. ! 136: ! 137: When to use frame_pointer_rtx and hard_frame_pointer_rtx is a little ! 138: tricky: until register elimination has taken place hard_frame_pointer_rtx ! 139: should be used if it is being set, and frame_pointer_rtx otherwise. After ! 140: register elimination hard_frame_pointer_rtx should always be used. ! 141: On machines where the two registers are same (most) then these are the ! 142: same. ! 143: ! 144: In an inline procedure, the stack and frame pointer rtxs may not be ! 145: used for anything else. */ ! 146: rtx stack_pointer_rtx; /* (REG:Pmode STACK_POINTER_REGNUM) */ ! 147: rtx frame_pointer_rtx; /* (REG:Pmode FRAME_POINTER_REGNUM) */ ! 148: rtx hard_frame_pointer_rtx; /* (REG:Pmode HARD_FRAME_POINTER_REGNUM) */ ! 149: rtx arg_pointer_rtx; /* (REG:Pmode ARG_POINTER_REGNUM) */ ! 150: rtx struct_value_rtx; /* (REG:Pmode STRUCT_VALUE_REGNUM) */ ! 151: rtx struct_value_incoming_rtx; /* (REG:Pmode STRUCT_VALUE_INCOMING_REGNUM) */ ! 152: rtx static_chain_rtx; /* (REG:Pmode STATIC_CHAIN_REGNUM) */ ! 153: rtx static_chain_incoming_rtx; /* (REG:Pmode STATIC_CHAIN_INCOMING_REGNUM) */ ! 154: rtx pic_offset_table_rtx; /* (REG:Pmode PIC_OFFSET_TABLE_REGNUM) */ ! 155: ! 156: rtx virtual_incoming_args_rtx; /* (REG:Pmode VIRTUAL_INCOMING_ARGS_REGNUM) */ ! 157: rtx virtual_stack_vars_rtx; /* (REG:Pmode VIRTUAL_STACK_VARS_REGNUM) */ ! 158: rtx virtual_stack_dynamic_rtx; /* (REG:Pmode VIRTUAL_STACK_DYNAMIC_REGNUM) */ ! 159: rtx virtual_outgoing_args_rtx; /* (REG:Pmode VIRTUAL_OUTGOING_ARGS_REGNUM) */ ! 160: ! 161: /* We make one copy of (const_int C) where C is in ! 162: [- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT] ! 163: to save space during the compilation and simplify comparisons of ! 164: integers. */ ! 165: ! 166: #define MAX_SAVED_CONST_INT 64 ! 167: ! 168: static rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1]; ! 169: ! 170: /* The ends of the doubly-linked chain of rtl for the current function. ! 171: Both are reset to null at the start of rtl generation for the function. ! 172: ! 173: start_sequence saves both of these on `sequence_stack' along with ! 174: `sequence_rtl_expr' and then starts a new, nested sequence of insns. */ ! 175: ! 176: static rtx first_insn = NULL; ! 177: static rtx last_insn = NULL; ! 178: ! 179: /* RTL_EXPR within which the current sequence will be placed. Use to ! 180: prevent reuse of any temporaries within the sequence until after the ! 181: RTL_EXPR is emitted. */ ! 182: ! 183: tree sequence_rtl_expr = NULL; ! 184: ! 185: /* INSN_UID for next insn emitted. ! 186: Reset to 1 for each function compiled. */ ! 187: ! 188: static int cur_insn_uid = 1; ! 189: ! 190: /* Line number and source file of the last line-number NOTE emitted. ! 191: This is used to avoid generating duplicates. */ ! 192: ! 193: static int last_linenum = 0; ! 194: static char *last_filename = 0; ! 195: ! 196: /* A vector indexed by pseudo reg number. The allocated length ! 197: of this vector is regno_pointer_flag_length. Since this ! 198: vector is needed during the expansion phase when the total ! 199: number of registers in the function is not yet known, ! 200: it is copied and made bigger when necessary. */ ! 201: ! 202: char *regno_pointer_flag; ! 203: int regno_pointer_flag_length; ! 204: ! 205: /* Indexed by pseudo register number, gives the rtx for that pseudo. ! 206: Allocated in parallel with regno_pointer_flag. */ ! 207: ! 208: rtx *regno_reg_rtx; ! 209: ! 210: /* Stack of pending (incomplete) sequences saved by `start_sequence'. ! 211: Each element describes one pending sequence. ! 212: The main insn-chain is saved in the last element of the chain, ! 213: unless the chain is empty. */ ! 214: ! 215: struct sequence_stack *sequence_stack; ! 216: ! 217: /* start_sequence and gen_sequence can make a lot of rtx expressions which are ! 218: shortly thrown away. We use two mechanisms to prevent this waste: ! 219: ! 220: First, we keep a list of the expressions used to represent the sequence ! 221: stack in sequence_element_free_list. ! 222: ! 223: Second, for sizes up to 5 elements, we keep a SEQUENCE and its associated ! 224: rtvec for use by gen_sequence. One entry for each size is sufficient ! 225: because most cases are calls to gen_sequence followed by immediately ! 226: emitting the SEQUENCE. Reuse is safe since emitting a sequence is ! 227: destructive on the insn in it anyway and hence can't be redone. ! 228: ! 229: We do not bother to save this cached data over nested function calls. ! 230: Instead, we just reinitialize them. */ ! 231: ! 232: #define SEQUENCE_RESULT_SIZE 5 ! 233: ! 234: static struct sequence_stack *sequence_element_free_list; ! 235: static rtx sequence_result[SEQUENCE_RESULT_SIZE]; ! 236: ! 237: extern int rtx_equal_function_value_matters; ! 238: ! 239: /* Filename and line number of last line-number note, ! 240: whether we actually emitted it or not. */ ! 241: extern char *emit_filename; ! 242: extern int emit_lineno; ! 243: ! 244: rtx change_address (); ! 245: void init_emit (); ! 246: ! 247: extern struct obstack *rtl_obstack; ! 248: ! 249: extern int stack_depth; ! 250: extern int max_stack_depth; ! 251: ! 252: /* rtx gen_rtx (code, mode, [element1, ..., elementn]) ! 253: ** ! 254: ** This routine generates an RTX of the size specified by ! 255: ** <code>, which is an RTX code. The RTX structure is initialized ! 256: ** from the arguments <element1> through <elementn>, which are ! 257: ** interpreted according to the specific RTX type's format. The ! 258: ** special machine mode associated with the rtx (if any) is specified ! 259: ** in <mode>. ! 260: ** ! 261: ** gen_rtx can be invoked in a way which resembles the lisp-like ! 262: ** rtx it will generate. For example, the following rtx structure: ! 263: ** ! 264: ** (plus:QI (mem:QI (reg:SI 1)) ! 265: ** (mem:QI (plusw:SI (reg:SI 2) (reg:SI 3)))) ! 266: ** ! 267: ** ...would be generated by the following C code: ! 268: ** ! 269: ** gen_rtx (PLUS, QImode, ! 270: ** gen_rtx (MEM, QImode, ! 271: ** gen_rtx (REG, SImode, 1)), ! 272: ** gen_rtx (MEM, QImode, ! 273: ** gen_rtx (PLUS, SImode, ! 274: ** gen_rtx (REG, SImode, 2), ! 275: ** gen_rtx (REG, SImode, 3)))), ! 276: */ ! 277: ! 278: /*VARARGS2*/ ! 279: rtx ! 280: gen_rtx (va_alist) ! 281: va_dcl ! 282: { ! 283: va_list p; ! 284: enum rtx_code code; ! 285: enum machine_mode mode; ! 286: register int i; /* Array indices... */ ! 287: register char *fmt; /* Current rtx's format... */ ! 288: register rtx rt_val; /* RTX to return to caller... */ ! 289: ! 290: va_start (p); ! 291: code = va_arg (p, enum rtx_code); ! 292: mode = va_arg (p, enum machine_mode); ! 293: ! 294: if (code == CONST_INT) ! 295: { ! 296: HOST_WIDE_INT arg = va_arg (p, HOST_WIDE_INT); ! 297: ! 298: if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT) ! 299: return const_int_rtx[arg + MAX_SAVED_CONST_INT]; ! 300: ! 301: if (const_true_rtx && arg == STORE_FLAG_VALUE) ! 302: return const_true_rtx; ! 303: ! 304: rt_val = rtx_alloc (code); ! 305: INTVAL (rt_val) = arg; ! 306: } ! 307: else if (code == REG) ! 308: { ! 309: int regno = va_arg (p, int); ! 310: ! 311: /* In case the MD file explicitly references the frame pointer, have ! 312: all such references point to the same frame pointer. This is used ! 313: during frame pointer elimination to distinguish the explicit ! 314: references to these registers from pseudos that happened to be ! 315: assigned to them. ! 316: ! 317: If we have eliminated the frame pointer or arg pointer, we will ! 318: be using it as a normal register, for example as a spill register. ! 319: In such cases, we might be accessing it in a mode that is not ! 320: Pmode and therefore cannot use the pre-allocated rtx. ! 321: ! 322: Also don't do this when we are making new REGs in reload, ! 323: since we don't want to get confused with the real pointers. */ ! 324: ! 325: if (frame_pointer_rtx && regno == FRAME_POINTER_REGNUM && mode == Pmode ! 326: && ! reload_in_progress) ! 327: return frame_pointer_rtx; ! 328: #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM ! 329: if (hard_frame_pointer_rtx && regno == HARD_FRAME_POINTER_REGNUM ! 330: && mode == Pmode && ! reload_in_progress) ! 331: return hard_frame_pointer_rtx; ! 332: #endif ! 333: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM ! 334: if (arg_pointer_rtx && regno == ARG_POINTER_REGNUM && mode == Pmode ! 335: && ! reload_in_progress) ! 336: return arg_pointer_rtx; ! 337: #endif ! 338: if (stack_pointer_rtx && regno == STACK_POINTER_REGNUM && mode == Pmode ! 339: && ! reload_in_progress) ! 340: return stack_pointer_rtx; ! 341: else ! 342: { ! 343: rt_val = rtx_alloc (code); ! 344: rt_val->mode = mode; ! 345: REGNO (rt_val) = regno; ! 346: return rt_val; ! 347: } ! 348: } ! 349: else ! 350: { ! 351: rt_val = rtx_alloc (code); /* Allocate the storage space. */ ! 352: rt_val->mode = mode; /* Store the machine mode... */ ! 353: ! 354: fmt = GET_RTX_FORMAT (code); /* Find the right format... */ ! 355: for (i = 0; i < GET_RTX_LENGTH (code); i++) ! 356: { ! 357: switch (*fmt++) ! 358: { ! 359: case '0': /* Unused field. */ ! 360: break; ! 361: ! 362: case 'i': /* An integer? */ ! 363: XINT (rt_val, i) = va_arg (p, int); ! 364: break; ! 365: ! 366: case 'w': /* A wide integer? */ ! 367: XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT); ! 368: break; ! 369: ! 370: case 's': /* A string? */ ! 371: XSTR (rt_val, i) = va_arg (p, char *); ! 372: break; ! 373: ! 374: case 'e': /* An expression? */ ! 375: case 'u': /* An insn? Same except when printing. */ ! 376: XEXP (rt_val, i) = va_arg (p, rtx); ! 377: break; ! 378: ! 379: case 'E': /* An RTX vector? */ ! 380: XVEC (rt_val, i) = va_arg (p, rtvec); ! 381: break; ! 382: ! 383: default: ! 384: abort (); ! 385: } ! 386: } ! 387: } ! 388: va_end (p); ! 389: return rt_val; /* Return the new RTX... */ ! 390: } ! 391: ! 392: /* gen_rtvec (n, [rt1, ..., rtn]) ! 393: ** ! 394: ** This routine creates an rtvec and stores within it the ! 395: ** pointers to rtx's which are its arguments. ! 396: */ ! 397: ! 398: /*VARARGS1*/ ! 399: rtvec ! 400: gen_rtvec (va_alist) ! 401: va_dcl ! 402: { ! 403: int n, i; ! 404: va_list p; ! 405: rtx *vector; ! 406: ! 407: va_start (p); ! 408: n = va_arg (p, int); ! 409: ! 410: if (n == 0) ! 411: return NULL_RTVEC; /* Don't allocate an empty rtvec... */ ! 412: ! 413: vector = (rtx *) alloca (n * sizeof (rtx)); ! 414: for (i = 0; i < n; i++) ! 415: vector[i] = va_arg (p, rtx); ! 416: va_end (p); ! 417: ! 418: return gen_rtvec_v (n, vector); ! 419: } ! 420: ! 421: rtvec ! 422: gen_rtvec_v (n, argp) ! 423: int n; ! 424: rtx *argp; ! 425: { ! 426: register int i; ! 427: register rtvec rt_val; ! 428: ! 429: if (n == 0) ! 430: return NULL_RTVEC; /* Don't allocate an empty rtvec... */ ! 431: ! 432: rt_val = rtvec_alloc (n); /* Allocate an rtvec... */ ! 433: ! 434: for (i = 0; i < n; i++) ! 435: rt_val->elem[i].rtx = *argp++; ! 436: ! 437: return rt_val; ! 438: } ! 439: ! 440: /* Generate a REG rtx for a new pseudo register of mode MODE. ! 441: This pseudo is assigned the next sequential register number. */ ! 442: ! 443: rtx ! 444: gen_reg_rtx (mode) ! 445: enum machine_mode mode; ! 446: { ! 447: register rtx val; ! 448: ! 449: /* Don't let anything called by or after reload create new registers ! 450: (actually, registers can't be created after flow, but this is a good ! 451: approximation). */ ! 452: ! 453: if (reload_in_progress || reload_completed) ! 454: abort (); ! 455: ! 456: if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ! 457: || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) ! 458: { ! 459: /* For complex modes, don't make a single pseudo. ! 460: Instead, make a CONCAT of two pseudos. ! 461: This allows noncontiguous allocation of the real and imaginary parts, ! 462: which makes much better code. Besides, allocating DCmode ! 463: pseudos overstrains reload on some machines like the 386. */ ! 464: rtx realpart, imagpart; ! 465: int size = GET_MODE_UNIT_SIZE (mode); ! 466: enum machine_mode partmode ! 467: = mode_for_size (size * BITS_PER_UNIT, ! 468: (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ! 469: ? MODE_FLOAT : MODE_INT), ! 470: 0); ! 471: ! 472: realpart = gen_reg_rtx (partmode); ! 473: imagpart = gen_reg_rtx (partmode); ! 474: return gen_rtx (CONCAT, mode, realpart, imagpart); ! 475: } ! 476: ! 477: /* Make sure regno_pointer_flag and regno_reg_rtx are large ! 478: enough to have an element for this pseudo reg number. */ ! 479: ! 480: if (reg_rtx_no == regno_pointer_flag_length) ! 481: { ! 482: rtx *new1; ! 483: char *new = ! 484: (char *) oballoc (regno_pointer_flag_length * 2); ! 485: bzero (new, regno_pointer_flag_length * 2); ! 486: bcopy (regno_pointer_flag, new, regno_pointer_flag_length); ! 487: regno_pointer_flag = new; ! 488: ! 489: new1 = (rtx *) oballoc (regno_pointer_flag_length * 2 * sizeof (rtx)); ! 490: bzero (new1, regno_pointer_flag_length * 2 * sizeof (rtx)); ! 491: bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx)); ! 492: regno_reg_rtx = new1; ! 493: ! 494: regno_pointer_flag_length *= 2; ! 495: } ! 496: ! 497: val = gen_rtx (REG, mode, reg_rtx_no); ! 498: regno_reg_rtx[reg_rtx_no++] = val; ! 499: return val; ! 500: } ! 501: ! 502: /* Identify REG as a probable pointer register. */ ! 503: ! 504: void ! 505: mark_reg_pointer (reg) ! 506: rtx reg; ! 507: { ! 508: REGNO_POINTER_FLAG (REGNO (reg)) = 1; ! 509: } ! 510: ! 511: /* Return 1 plus largest pseudo reg number used in the current function. */ ! 512: ! 513: int ! 514: max_reg_num () ! 515: { ! 516: return reg_rtx_no; ! 517: } ! 518: ! 519: /* Return 1 + the largest label number used so far in the current function. */ ! 520: ! 521: int ! 522: max_label_num () ! 523: { ! 524: if (last_label_num && label_num == base_label_num) ! 525: return last_label_num; ! 526: return label_num; ! 527: } ! 528: ! 529: /* Return first label number used in this function (if any were used). */ ! 530: ! 531: int ! 532: get_first_label_num () ! 533: { ! 534: return first_label_num; ! 535: } ! 536: ! 537: /* Return a value representing some low-order bits of X, where the number ! 538: of low-order bits is given by MODE. Note that no conversion is done ! 539: between floating-point and fixed-point values, rather, the bit ! 540: representation is returned. ! 541: ! 542: This function handles the cases in common between gen_lowpart, below, ! 543: and two variants in cse.c and combine.c. These are the cases that can ! 544: be safely handled at all points in the compilation. ! 545: ! 546: If this is not a case we can handle, return 0. */ ! 547: ! 548: rtx ! 549: gen_lowpart_common (mode, x) ! 550: enum machine_mode mode; ! 551: register rtx x; ! 552: { ! 553: int word = 0; ! 554: ! 555: if (GET_MODE (x) == mode) ! 556: return x; ! 557: ! 558: /* MODE must occupy no more words than the mode of X. */ ! 559: if (GET_MODE (x) != VOIDmode ! 560: && ((GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD ! 561: > ((GET_MODE_SIZE (GET_MODE (x)) + (UNITS_PER_WORD - 1)) ! 562: / UNITS_PER_WORD))) ! 563: return 0; ! 564: ! 565: if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ! 566: word = ((GET_MODE_SIZE (GET_MODE (x)) ! 567: - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)) ! 568: / UNITS_PER_WORD); ! 569: ! 570: if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND) ! 571: && (GET_MODE_CLASS (mode) == MODE_INT ! 572: || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)) ! 573: { ! 574: /* If we are getting the low-order part of something that has been ! 575: sign- or zero-extended, we can either just use the object being ! 576: extended or make a narrower extension. If we want an even smaller ! 577: piece than the size of the object being extended, call ourselves ! 578: recursively. ! 579: ! 580: This case is used mostly by combine and cse. */ ! 581: ! 582: if (GET_MODE (XEXP (x, 0)) == mode) ! 583: return XEXP (x, 0); ! 584: else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))) ! 585: return gen_lowpart_common (mode, XEXP (x, 0)); ! 586: else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))) ! 587: return gen_rtx (GET_CODE (x), mode, XEXP (x, 0)); ! 588: } ! 589: else if (GET_CODE (x) == SUBREG ! 590: && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD ! 591: || GET_MODE_SIZE (mode) == GET_MODE_UNIT_SIZE (GET_MODE (x)))) ! 592: return (GET_MODE (SUBREG_REG (x)) == mode && SUBREG_WORD (x) == 0 ! 593: ? SUBREG_REG (x) ! 594: : gen_rtx (SUBREG, mode, SUBREG_REG (x), SUBREG_WORD (x))); ! 595: else if (GET_CODE (x) == REG) ! 596: { ! 597: /* If the register is not valid for MODE, return 0. If we don't ! 598: do this, there is no way to fix up the resulting REG later. ! 599: But we do do this if the current REG is not valid for its ! 600: mode. This latter is a kludge, but is required due to the ! 601: way that parameters are passed on some machines, most ! 602: notably Sparc. */ ! 603: if (REGNO (x) < FIRST_PSEUDO_REGISTER ! 604: && ! HARD_REGNO_MODE_OK (REGNO (x) + word, mode) ! 605: && HARD_REGNO_MODE_OK (REGNO (x), GET_MODE (x))) ! 606: return 0; ! 607: else if (REGNO (x) < FIRST_PSEUDO_REGISTER ! 608: /* integrate.c can't handle parts of a return value register. */ ! 609: && (! REG_FUNCTION_VALUE_P (x) ! 610: || ! rtx_equal_function_value_matters) ! 611: /* We want to keep the stack, frame, and arg pointers ! 612: special. */ ! 613: && REGNO (x) != FRAME_POINTER_REGNUM ! 614: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM ! 615: && REGNO (x) != ARG_POINTER_REGNUM ! 616: #endif ! 617: && REGNO (x) != STACK_POINTER_REGNUM) ! 618: return gen_rtx (REG, mode, REGNO (x) + word); ! 619: else ! 620: return gen_rtx (SUBREG, mode, x, word); ! 621: } ! 622: else if (GET_CODE (x) == CONCAT) ! 623: { ! 624: if (GET_MODE (XEXP (x, 0)) != mode) ! 625: abort (); ! 626: return XEXP (x, 0); ! 627: } ! 628: /* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits ! 629: from the low-order part of the constant. */ ! 630: else if ((GET_MODE_CLASS (mode) == MODE_INT ! 631: || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT) ! 632: && GET_MODE (x) == VOIDmode ! 633: && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)) ! 634: { ! 635: /* If MODE is twice the host word size, X is already the desired ! 636: representation. Otherwise, if MODE is wider than a word, we can't ! 637: do this. If MODE is exactly a word, return just one CONST_INT. ! 638: If MODE is smaller than a word, clear the bits that don't belong ! 639: in our mode, unless they and our sign bit are all one. So we get ! 640: either a reasonable negative value or a reasonable unsigned value ! 641: for this mode. */ ! 642: ! 643: if (GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT) ! 644: return x; ! 645: else if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT) ! 646: return 0; ! 647: else if (GET_MODE_BITSIZE (mode) == HOST_BITS_PER_WIDE_INT) ! 648: return (GET_CODE (x) == CONST_INT ? x ! 649: : GEN_INT (CONST_DOUBLE_LOW (x))); ! 650: else ! 651: { ! 652: /* MODE must be narrower than HOST_BITS_PER_INT. */ ! 653: int width = GET_MODE_BITSIZE (mode); ! 654: HOST_WIDE_INT val = (GET_CODE (x) == CONST_INT ? INTVAL (x) ! 655: : CONST_DOUBLE_LOW (x)); ! 656: ! 657: if (((val & ((HOST_WIDE_INT) (-1) << (width - 1))) ! 658: != ((HOST_WIDE_INT) (-1) << (width - 1)))) ! 659: val &= ((HOST_WIDE_INT) 1 << width) - 1; ! 660: ! 661: return (GET_CODE (x) == CONST_INT && INTVAL (x) == val ? x ! 662: : GEN_INT (val)); ! 663: } ! 664: } ! 665: ! 666: /* If X is an integral constant but we want it in floating-point, it ! 667: must be the case that we have a union of an integer and a floating-point ! 668: value. If the machine-parameters allow it, simulate that union here ! 669: and return the result. The two-word and single-word cases are ! 670: different. */ ! 671: ! 672: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT ! 673: && HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 674: || flag_pretend_float) ! 675: && GET_MODE_CLASS (mode) == MODE_FLOAT ! 676: && GET_MODE_SIZE (mode) == UNITS_PER_WORD ! 677: && GET_CODE (x) == CONST_INT ! 678: && sizeof (float) * HOST_BITS_PER_CHAR == HOST_BITS_PER_WIDE_INT) ! 679: #ifdef REAL_ARITHMETIC ! 680: { ! 681: REAL_VALUE_TYPE r; ! 682: HOST_WIDE_INT i; ! 683: ! 684: i = INTVAL (x); ! 685: r = REAL_VALUE_FROM_TARGET_SINGLE (i); ! 686: return immed_real_const_1 (r, mode); ! 687: } ! 688: #else ! 689: { ! 690: union {HOST_WIDE_INT i; float d; } u; ! 691: ! 692: u.i = INTVAL (x); ! 693: return immed_real_const_1 (u.d, mode); ! 694: } ! 695: #endif ! 696: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT ! 697: && HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 698: || flag_pretend_float) ! 699: && GET_MODE_CLASS (mode) == MODE_FLOAT ! 700: && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD ! 701: && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE) ! 702: && GET_MODE (x) == VOIDmode ! 703: && (sizeof (double) * HOST_BITS_PER_CHAR ! 704: == 2 * HOST_BITS_PER_WIDE_INT)) ! 705: #ifdef REAL_ARITHMETIC ! 706: { ! 707: REAL_VALUE_TYPE r; ! 708: HOST_WIDE_INT i[2]; ! 709: HOST_WIDE_INT low, high; ! 710: ! 711: if (GET_CODE (x) == CONST_INT) ! 712: low = INTVAL (x), high = low >> (HOST_BITS_PER_WIDE_INT -1); ! 713: else ! 714: low = CONST_DOUBLE_LOW (x), high = CONST_DOUBLE_HIGH (x); ! 715: ! 716: /* TARGET_DOUBLE takes the addressing order of the target machine. */ ! 717: #ifdef WORDS_BIG_ENDIAN ! 718: i[0] = high, i[1] = low; ! 719: #else ! 720: i[0] = low, i[1] = high; ! 721: #endif ! 722: ! 723: r = REAL_VALUE_FROM_TARGET_DOUBLE (i); ! 724: return immed_real_const_1 (r, mode); ! 725: } ! 726: #else ! 727: { ! 728: union {HOST_WIDE_INT i[2]; double d; } u; ! 729: HOST_WIDE_INT low, high; ! 730: ! 731: if (GET_CODE (x) == CONST_INT) ! 732: low = INTVAL (x), high = low >> (HOST_BITS_PER_WIDE_INT -1); ! 733: else ! 734: low = CONST_DOUBLE_LOW (x), high = CONST_DOUBLE_HIGH (x); ! 735: ! 736: #ifdef HOST_WORDS_BIG_ENDIAN ! 737: u.i[0] = high, u.i[1] = low; ! 738: #else ! 739: u.i[0] = low, u.i[1] = high; ! 740: #endif ! 741: ! 742: return immed_real_const_1 (u.d, mode); ! 743: } ! 744: #endif ! 745: /* Similarly, if this is converting a floating-point value into a ! 746: single-word integer. Only do this is the host and target parameters are ! 747: compatible. */ ! 748: ! 749: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT ! 750: && HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 751: || flag_pretend_float) ! 752: && (GET_MODE_CLASS (mode) == MODE_INT ! 753: || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT) ! 754: && GET_CODE (x) == CONST_DOUBLE ! 755: && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT ! 756: && GET_MODE_BITSIZE (mode) == BITS_PER_WORD) ! 757: return operand_subword (x, 0, 0, GET_MODE (x)); ! 758: ! 759: /* Similarly, if this is converting a floating-point value into a ! 760: two-word integer, we can do this one word at a time and make an ! 761: integer. Only do this is the host and target parameters are ! 762: compatible. */ ! 763: ! 764: else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT ! 765: && HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 766: || flag_pretend_float) ! 767: && (GET_MODE_CLASS (mode) == MODE_INT ! 768: || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT) ! 769: && GET_CODE (x) == CONST_DOUBLE ! 770: && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT ! 771: && GET_MODE_BITSIZE (mode) == 2 * BITS_PER_WORD) ! 772: { ! 773: rtx lowpart = operand_subword (x, WORDS_BIG_ENDIAN, 0, GET_MODE (x)); ! 774: rtx highpart = operand_subword (x, ! WORDS_BIG_ENDIAN, 0, GET_MODE (x)); ! 775: ! 776: if (lowpart && GET_CODE (lowpart) == CONST_INT ! 777: && highpart && GET_CODE (highpart) == CONST_INT) ! 778: return immed_double_const (INTVAL (lowpart), INTVAL (highpart), mode); ! 779: } ! 780: ! 781: /* Otherwise, we can't do this. */ ! 782: return 0; ! 783: } ! 784: ! 785: /* Return the real part (which has mode MODE) of a complex value X. ! 786: This always comes at the low address in memory. */ ! 787: ! 788: rtx ! 789: gen_realpart (mode, x) ! 790: enum machine_mode mode; ! 791: register rtx x; ! 792: { ! 793: if (WORDS_BIG_ENDIAN) ! 794: return gen_highpart (mode, x); ! 795: else ! 796: return gen_lowpart (mode, x); ! 797: } ! 798: ! 799: /* Return the imaginary part (which has mode MODE) of a complex value X. ! 800: This always comes at the high address in memory. */ ! 801: ! 802: rtx ! 803: gen_imagpart (mode, x) ! 804: enum machine_mode mode; ! 805: register rtx x; ! 806: { ! 807: if (WORDS_BIG_ENDIAN) ! 808: return gen_lowpart (mode, x); ! 809: else ! 810: return gen_highpart (mode, x); ! 811: } ! 812: ! 813: /* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value, ! 814: return an rtx (MEM, SUBREG, or CONST_INT) that refers to the ! 815: least-significant part of X. ! 816: MODE specifies how big a part of X to return; ! 817: it usually should not be larger than a word. ! 818: If X is a MEM whose address is a QUEUED, the value may be so also. */ ! 819: ! 820: rtx ! 821: gen_lowpart (mode, x) ! 822: enum machine_mode mode; ! 823: register rtx x; ! 824: { ! 825: rtx result = gen_lowpart_common (mode, x); ! 826: ! 827: if (result) ! 828: return result; ! 829: else if (GET_CODE (x) == MEM) ! 830: { ! 831: /* The only additional case we can do is MEM. */ ! 832: register int offset = 0; ! 833: if (WORDS_BIG_ENDIAN) ! 834: offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) ! 835: - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); ! 836: ! 837: if (BYTES_BIG_ENDIAN) ! 838: /* Adjust the address so that the address-after-the-data ! 839: is unchanged. */ ! 840: offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) ! 841: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); ! 842: ! 843: return change_address (x, mode, plus_constant (XEXP (x, 0), offset)); ! 844: } ! 845: else ! 846: abort (); ! 847: } ! 848: ! 849: /* Like `gen_lowpart', but refer to the most significant part. ! 850: This is used to access the imaginary part of a complex number. */ ! 851: ! 852: rtx ! 853: gen_highpart (mode, x) ! 854: enum machine_mode mode; ! 855: register rtx x; ! 856: { ! 857: /* This case loses if X is a subreg. To catch bugs early, ! 858: complain if an invalid MODE is used even in other cases. */ ! 859: if (GET_MODE_SIZE (mode) > UNITS_PER_WORD ! 860: && GET_MODE_SIZE (mode) != GET_MODE_UNIT_SIZE (GET_MODE (x))) ! 861: abort (); ! 862: if (GET_CODE (x) == CONST_DOUBLE ! 863: #if !(TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT || defined (REAL_IS_NOT_DOUBLE)) ! 864: && GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT ! 865: #endif ! 866: ) ! 867: return gen_rtx (CONST_INT, VOIDmode, ! 868: CONST_DOUBLE_HIGH (x) & GET_MODE_MASK (mode)); ! 869: else if (GET_CODE (x) == CONST_INT) ! 870: return const0_rtx; ! 871: else if (GET_CODE (x) == MEM) ! 872: { ! 873: register int offset = 0; ! 874: #if !WORDS_BIG_ENDIAN ! 875: offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) ! 876: - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); ! 877: #endif ! 878: #if !BYTES_BIG_ENDIAN ! 879: if (GET_MODE_SIZE (mode) < UNITS_PER_WORD) ! 880: offset -= (GET_MODE_SIZE (mode) ! 881: - MIN (UNITS_PER_WORD, ! 882: GET_MODE_SIZE (GET_MODE (x)))); ! 883: #endif ! 884: return change_address (x, mode, plus_constant (XEXP (x, 0), offset)); ! 885: } ! 886: else if (GET_CODE (x) == SUBREG) ! 887: { ! 888: /* The only time this should occur is when we are looking at a ! 889: multi-word item with a SUBREG whose mode is the same as that of the ! 890: item. It isn't clear what we would do if it wasn't. */ ! 891: if (SUBREG_WORD (x) != 0) ! 892: abort (); ! 893: return gen_highpart (mode, SUBREG_REG (x)); ! 894: } ! 895: else if (GET_CODE (x) == REG) ! 896: { ! 897: int word = 0; ! 898: ! 899: #if !WORDS_BIG_ENDIAN ! 900: if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) ! 901: word = ((GET_MODE_SIZE (GET_MODE (x)) ! 902: - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)) ! 903: / UNITS_PER_WORD); ! 904: #endif ! 905: if (REGNO (x) < FIRST_PSEUDO_REGISTER ! 906: /* integrate.c can't handle parts of a return value register. */ ! 907: && (! REG_FUNCTION_VALUE_P (x) ! 908: || ! rtx_equal_function_value_matters) ! 909: /* We want to keep the stack, frame, and arg pointers special. */ ! 910: && REGNO (x) != FRAME_POINTER_REGNUM ! 911: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM ! 912: && REGNO (x) != ARG_POINTER_REGNUM ! 913: #endif ! 914: && REGNO (x) != STACK_POINTER_REGNUM) ! 915: return gen_rtx (REG, mode, REGNO (x) + word); ! 916: else ! 917: return gen_rtx (SUBREG, mode, x, word); ! 918: } ! 919: else if (GET_CODE (x) == CONCAT) ! 920: { ! 921: if (GET_MODE (XEXP (x, 1)) != mode) ! 922: abort (); ! 923: return XEXP (x, 1); ! 924: } ! 925: else ! 926: abort (); ! 927: } ! 928: ! 929: /* Return 1 iff X, assumed to be a SUBREG, ! 930: refers to the least significant part of its containing reg. ! 931: If X is not a SUBREG, always return 1 (it is its own low part!). */ ! 932: ! 933: int ! 934: subreg_lowpart_p (x) ! 935: rtx x; ! 936: { ! 937: if (GET_CODE (x) != SUBREG) ! 938: return 1; ! 939: ! 940: if (WORDS_BIG_ENDIAN ! 941: && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) > UNITS_PER_WORD) ! 942: return (SUBREG_WORD (x) ! 943: == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) ! 944: - MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)) ! 945: / UNITS_PER_WORD)); ! 946: ! 947: return SUBREG_WORD (x) == 0; ! 948: } ! 949: ! 950: /* Return subword I of operand OP. ! 951: The word number, I, is interpreted as the word number starting at the ! 952: low-order address. Word 0 is the low-order word if not WORDS_BIG_ENDIAN, ! 953: otherwise it is the high-order word. ! 954: ! 955: If we cannot extract the required word, we return zero. Otherwise, an ! 956: rtx corresponding to the requested word will be returned. ! 957: ! 958: VALIDATE_ADDRESS is nonzero if the address should be validated. Before ! 959: reload has completed, a valid address will always be returned. After ! 960: reload, if a valid address cannot be returned, we return zero. ! 961: ! 962: If VALIDATE_ADDRESS is zero, we simply form the required address; validating ! 963: it is the responsibility of the caller. ! 964: ! 965: MODE is the mode of OP in case it is a CONST_INT. */ ! 966: ! 967: rtx ! 968: operand_subword (op, i, validate_address, mode) ! 969: rtx op; ! 970: int i; ! 971: int validate_address; ! 972: enum machine_mode mode; ! 973: { ! 974: HOST_WIDE_INT val; ! 975: int size_ratio = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD; ! 976: ! 977: if (mode == VOIDmode) ! 978: mode = GET_MODE (op); ! 979: ! 980: if (mode == VOIDmode) ! 981: abort (); ! 982: ! 983: /* If OP is narrower than a word or if we want a word outside OP, fail. */ ! 984: if (mode != BLKmode ! 985: && (GET_MODE_SIZE (mode) < UNITS_PER_WORD ! 986: || (i + 1) * UNITS_PER_WORD > GET_MODE_SIZE (mode))) ! 987: return 0; ! 988: ! 989: /* If OP is already an integer word, return it. */ ! 990: if (GET_MODE_CLASS (mode) == MODE_INT ! 991: && GET_MODE_SIZE (mode) == UNITS_PER_WORD) ! 992: return op; ! 993: ! 994: /* If OP is a REG or SUBREG, we can handle it very simply. */ ! 995: if (GET_CODE (op) == REG) ! 996: { ! 997: /* If the register is not valid for MODE, return 0. If we don't ! 998: do this, there is no way to fix up the resulting REG later. */ ! 999: if (REGNO (op) < FIRST_PSEUDO_REGISTER ! 1000: && ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode)) ! 1001: return 0; ! 1002: else if (REGNO (op) >= FIRST_PSEUDO_REGISTER ! 1003: || (REG_FUNCTION_VALUE_P (op) ! 1004: && rtx_equal_function_value_matters) ! 1005: /* We want to keep the stack, frame, and arg pointers ! 1006: special. */ ! 1007: || REGNO (op) == FRAME_POINTER_REGNUM ! 1008: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM ! 1009: || REGNO (op) == ARG_POINTER_REGNUM ! 1010: #endif ! 1011: || REGNO (op) == STACK_POINTER_REGNUM) ! 1012: return gen_rtx (SUBREG, word_mode, op, i); ! 1013: else ! 1014: return gen_rtx (REG, word_mode, REGNO (op) + i); ! 1015: } ! 1016: else if (GET_CODE (op) == SUBREG) ! 1017: return gen_rtx (SUBREG, word_mode, SUBREG_REG (op), i + SUBREG_WORD (op)); ! 1018: else if (GET_CODE (op) == CONCAT) ! 1019: { ! 1020: int partwords = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD; ! 1021: if (i < partwords) ! 1022: return operand_subword (XEXP (op, 0), i, validate_address, mode); ! 1023: return operand_subword (XEXP (op, 1), i - partwords, ! 1024: validate_address, mode); ! 1025: } ! 1026: ! 1027: /* Form a new MEM at the requested address. */ ! 1028: if (GET_CODE (op) == MEM) ! 1029: { ! 1030: rtx addr = plus_constant (XEXP (op, 0), i * UNITS_PER_WORD); ! 1031: rtx new; ! 1032: ! 1033: if (validate_address) ! 1034: { ! 1035: if (reload_completed) ! 1036: { ! 1037: if (! strict_memory_address_p (word_mode, addr)) ! 1038: return 0; ! 1039: } ! 1040: else ! 1041: addr = memory_address (word_mode, addr); ! 1042: } ! 1043: ! 1044: new = gen_rtx (MEM, word_mode, addr); ! 1045: ! 1046: MEM_VOLATILE_P (new) = MEM_VOLATILE_P (op); ! 1047: MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (op); ! 1048: RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op); ! 1049: ! 1050: return new; ! 1051: } ! 1052: ! 1053: /* The only remaining cases are when OP is a constant. If the host and ! 1054: target floating formats are the same, handling two-word floating ! 1055: constants are easy. Note that REAL_VALUE_TO_TARGET_{SINGLE,DOUBLE} ! 1056: are defined as returning 32 bit and 64-bit values, respectively, ! 1057: and not values of BITS_PER_WORD and 2 * BITS_PER_WORD bits. */ ! 1058: #ifdef REAL_ARITHMETIC ! 1059: if ((HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 1060: && GET_MODE_CLASS (mode) == MODE_FLOAT ! 1061: && GET_MODE_BITSIZE (mode) == 64 ! 1062: && GET_CODE (op) == CONST_DOUBLE) ! 1063: { ! 1064: HOST_WIDE_INT k[2]; ! 1065: REAL_VALUE_TYPE rv; ! 1066: ! 1067: REAL_VALUE_FROM_CONST_DOUBLE (rv, op); ! 1068: REAL_VALUE_TO_TARGET_DOUBLE (rv, k); ! 1069: ! 1070: /* We handle 32-bit and 64-bit host words here. Note that the order in ! 1071: which the words are written depends on the word endianness. ! 1072: ! 1073: ??? This is a potential portability problem and should ! 1074: be fixed at some point. */ ! 1075: if (HOST_BITS_PER_WIDE_INT == 32) ! 1076: return GEN_INT (k[i]); ! 1077: else if (HOST_BITS_PER_WIDE_INT == 64 && i == 0) ! 1078: return GEN_INT ((k[! WORDS_BIG_ENDIAN] << (HOST_BITS_PER_WIDE_INT / 2)) ! 1079: | k[WORDS_BIG_ENDIAN]); ! 1080: else ! 1081: abort (); ! 1082: } ! 1083: #else /* no REAL_ARITHMETIC */ ! 1084: if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT ! 1085: && HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 1086: || flag_pretend_float) ! 1087: && GET_MODE_CLASS (mode) == MODE_FLOAT ! 1088: && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD ! 1089: && GET_CODE (op) == CONST_DOUBLE) ! 1090: { ! 1091: /* The constant is stored in the host's word-ordering, ! 1092: but we want to access it in the target's word-ordering. Some ! 1093: compilers don't like a conditional inside macro args, so we have two ! 1094: copies of the return. */ ! 1095: #ifdef HOST_WORDS_BIG_ENDIAN ! 1096: return GEN_INT (i == WORDS_BIG_ENDIAN ! 1097: ? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op)); ! 1098: #else ! 1099: return GEN_INT (i != WORDS_BIG_ENDIAN ! 1100: ? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op)); ! 1101: #endif ! 1102: } ! 1103: #endif /* no REAL_ARITHMETIC */ ! 1104: ! 1105: /* Single word float is a little harder, since single- and double-word ! 1106: values often do not have the same high-order bits. We have already ! 1107: verified that we want the only defined word of the single-word value. */ ! 1108: #ifdef REAL_ARITHMETIC ! 1109: if ((HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 1110: && GET_MODE_CLASS (mode) == MODE_FLOAT ! 1111: && GET_MODE_BITSIZE (mode) == 32 ! 1112: && GET_CODE (op) == CONST_DOUBLE) ! 1113: { ! 1114: HOST_WIDE_INT l; ! 1115: REAL_VALUE_TYPE rv; ! 1116: ! 1117: REAL_VALUE_FROM_CONST_DOUBLE (rv, op); ! 1118: REAL_VALUE_TO_TARGET_SINGLE (rv, l); ! 1119: return GEN_INT (l); ! 1120: } ! 1121: #else ! 1122: if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT ! 1123: && HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) ! 1124: || flag_pretend_float) ! 1125: && GET_MODE_CLASS (mode) == MODE_FLOAT ! 1126: && GET_MODE_SIZE (mode) == UNITS_PER_WORD ! 1127: && GET_CODE (op) == CONST_DOUBLE) ! 1128: { ! 1129: double d; ! 1130: union {float f; HOST_WIDE_INT i; } u; ! 1131: ! 1132: REAL_VALUE_FROM_CONST_DOUBLE (d, op); ! 1133: ! 1134: u.f = d; ! 1135: return GEN_INT (u.i); ! 1136: } ! 1137: #endif /* no REAL_ARITHMETIC */ ! 1138: ! 1139: /* The only remaining cases that we can handle are integers. ! 1140: Convert to proper endianness now since these cases need it. ! 1141: At this point, i == 0 means the low-order word. ! 1142: ! 1143: We do not want to handle the case when BITS_PER_WORD <= HOST_BITS_PER_INT ! 1144: in general. However, if OP is (const_int 0), we can just return ! 1145: it for any word. */ ! 1146: ! 1147: if (op == const0_rtx) ! 1148: return op; ! 1149: ! 1150: if (GET_MODE_CLASS (mode) != MODE_INT ! 1151: || (GET_CODE (op) != CONST_INT && GET_CODE (op) != CONST_DOUBLE) ! 1152: || BITS_PER_WORD > HOST_BITS_PER_INT) ! 1153: return 0; ! 1154: ! 1155: if (WORDS_BIG_ENDIAN) ! 1156: i = GET_MODE_SIZE (mode) / UNITS_PER_WORD - 1 - i; ! 1157: ! 1158: /* Find out which word on the host machine this value is in and get ! 1159: it from the constant. */ ! 1160: val = (i / size_ratio == 0 ! 1161: ? (GET_CODE (op) == CONST_INT ? INTVAL (op) : CONST_DOUBLE_LOW (op)) ! 1162: : (GET_CODE (op) == CONST_INT ! 1163: ? (INTVAL (op) < 0 ? ~0 : 0) : CONST_DOUBLE_HIGH (op))); ! 1164: ! 1165: /* If BITS_PER_WORD is smaller than an int, get the appropriate bits. */ ! 1166: if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT) ! 1167: val = ((val >> ((i % size_ratio) * BITS_PER_WORD)) ! 1168: & (((HOST_WIDE_INT) 1 ! 1169: << (BITS_PER_WORD % HOST_BITS_PER_WIDE_INT)) - 1)); ! 1170: ! 1171: return GEN_INT (val); ! 1172: } ! 1173: ! 1174: /* Similar to `operand_subword', but never return 0. If we can't extract ! 1175: the required subword, put OP into a register and try again. If that fails, ! 1176: abort. We always validate the address in this case. It is not valid ! 1177: to call this function after reload; it is mostly meant for RTL ! 1178: generation. ! 1179: ! 1180: MODE is the mode of OP, in case it is CONST_INT. */ ! 1181: ! 1182: rtx ! 1183: operand_subword_force (op, i, mode) ! 1184: rtx op; ! 1185: int i; ! 1186: enum machine_mode mode; ! 1187: { ! 1188: rtx result = operand_subword (op, i, 1, mode); ! 1189: ! 1190: if (result) ! 1191: return result; ! 1192: ! 1193: if (mode != BLKmode && mode != VOIDmode) ! 1194: op = force_reg (mode, op); ! 1195: ! 1196: result = operand_subword (op, i, 1, mode); ! 1197: if (result == 0) ! 1198: abort (); ! 1199: ! 1200: return result; ! 1201: } ! 1202: ! 1203: /* Given a compare instruction, swap the operands. ! 1204: A test instruction is changed into a compare of 0 against the operand. */ ! 1205: ! 1206: void ! 1207: reverse_comparison (insn) ! 1208: rtx insn; ! 1209: { ! 1210: rtx body = PATTERN (insn); ! 1211: rtx comp; ! 1212: ! 1213: if (GET_CODE (body) == SET) ! 1214: comp = SET_SRC (body); ! 1215: else ! 1216: comp = SET_SRC (XVECEXP (body, 0, 0)); ! 1217: ! 1218: if (GET_CODE (comp) == COMPARE) ! 1219: { ! 1220: rtx op0 = XEXP (comp, 0); ! 1221: rtx op1 = XEXP (comp, 1); ! 1222: XEXP (comp, 0) = op1; ! 1223: XEXP (comp, 1) = op0; ! 1224: } ! 1225: else ! 1226: { ! 1227: rtx new = gen_rtx (COMPARE, VOIDmode, ! 1228: CONST0_RTX (GET_MODE (comp)), comp); ! 1229: if (GET_CODE (body) == SET) ! 1230: SET_SRC (body) = new; ! 1231: else ! 1232: SET_SRC (XVECEXP (body, 0, 0)) = new; ! 1233: } ! 1234: } ! 1235: ! 1236: /* Return a memory reference like MEMREF, but with its mode changed ! 1237: to MODE and its address changed to ADDR. ! 1238: (VOIDmode means don't change the mode. ! 1239: NULL for ADDR means don't change the address.) */ ! 1240: ! 1241: rtx ! 1242: change_address (memref, mode, addr) ! 1243: rtx memref; ! 1244: enum machine_mode mode; ! 1245: rtx addr; ! 1246: { ! 1247: rtx new; ! 1248: ! 1249: if (GET_CODE (memref) != MEM) ! 1250: abort (); ! 1251: if (mode == VOIDmode) ! 1252: mode = GET_MODE (memref); ! 1253: if (addr == 0) ! 1254: addr = XEXP (memref, 0); ! 1255: ! 1256: /* If reload is in progress or has completed, ADDR must be valid. ! 1257: Otherwise, we can call memory_address to make it valid. */ ! 1258: if (reload_completed || reload_in_progress) ! 1259: { ! 1260: if (! memory_address_p (mode, addr)) ! 1261: abort (); ! 1262: } ! 1263: else ! 1264: addr = memory_address (mode, addr); ! 1265: ! 1266: new = gen_rtx (MEM, mode, addr); ! 1267: MEM_VOLATILE_P (new) = MEM_VOLATILE_P (memref); ! 1268: RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (memref); ! 1269: MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (memref); ! 1270: return new; ! 1271: } ! 1272: ! 1273: /* Return a newly created CODE_LABEL rtx with a unique label number. */ ! 1274: ! 1275: rtx ! 1276: gen_label_rtx () ! 1277: { ! 1278: register rtx label; ! 1279: ! 1280: label = (output_bytecode ! 1281: ? gen_rtx (CODE_LABEL, VOIDmode, NULL, bc_get_bytecode_label ()) ! 1282: : gen_rtx (CODE_LABEL, VOIDmode, 0, 0, 0, label_num++, NULL_PTR)); ! 1283: ! 1284: LABEL_NUSES (label) = 0; ! 1285: return label; ! 1286: } ! 1287: ! 1288: /* For procedure integration. */ ! 1289: ! 1290: /* Return a newly created INLINE_HEADER rtx. Should allocate this ! 1291: from a permanent obstack when the opportunity arises. */ ! 1292: ! 1293: rtx ! 1294: gen_inline_header_rtx (first_insn, first_parm_insn, first_labelno, ! 1295: last_labelno, max_parm_regnum, max_regnum, args_size, ! 1296: pops_args, stack_slots, function_flags, ! 1297: outgoing_args_size, original_arg_vector, ! 1298: original_decl_initial) ! 1299: rtx first_insn, first_parm_insn; ! 1300: int first_labelno, last_labelno, max_parm_regnum, max_regnum, args_size; ! 1301: int pops_args; ! 1302: rtx stack_slots; ! 1303: int function_flags; ! 1304: int outgoing_args_size; ! 1305: rtvec original_arg_vector; ! 1306: rtx original_decl_initial; ! 1307: { ! 1308: rtx header = gen_rtx (INLINE_HEADER, VOIDmode, ! 1309: cur_insn_uid++, NULL_RTX, ! 1310: first_insn, first_parm_insn, ! 1311: first_labelno, last_labelno, ! 1312: max_parm_regnum, max_regnum, args_size, pops_args, ! 1313: stack_slots, function_flags, outgoing_args_size, ! 1314: original_arg_vector, original_decl_initial); ! 1315: return header; ! 1316: } ! 1317: ! 1318: /* Install new pointers to the first and last insns in the chain. ! 1319: Used for an inline-procedure after copying the insn chain. */ ! 1320: ! 1321: void ! 1322: set_new_first_and_last_insn (first, last) ! 1323: rtx first, last; ! 1324: { ! 1325: first_insn = first; ! 1326: last_insn = last; ! 1327: } ! 1328: ! 1329: /* Set the range of label numbers found in the current function. ! 1330: This is used when belatedly compiling an inline function. */ ! 1331: ! 1332: void ! 1333: set_new_first_and_last_label_num (first, last) ! 1334: int first, last; ! 1335: { ! 1336: base_label_num = label_num; ! 1337: first_label_num = first; ! 1338: last_label_num = last; ! 1339: } ! 1340: ! 1341: /* Save all variables describing the current status into the structure *P. ! 1342: This is used before starting a nested function. */ ! 1343: ! 1344: void ! 1345: save_emit_status (p) ! 1346: struct function *p; ! 1347: { ! 1348: p->reg_rtx_no = reg_rtx_no; ! 1349: p->first_label_num = first_label_num; ! 1350: p->first_insn = first_insn; ! 1351: p->last_insn = last_insn; ! 1352: p->sequence_rtl_expr = sequence_rtl_expr; ! 1353: p->sequence_stack = sequence_stack; ! 1354: p->cur_insn_uid = cur_insn_uid; ! 1355: p->last_linenum = last_linenum; ! 1356: p->last_filename = last_filename; ! 1357: p->regno_pointer_flag = regno_pointer_flag; ! 1358: p->regno_pointer_flag_length = regno_pointer_flag_length; ! 1359: p->regno_reg_rtx = regno_reg_rtx; ! 1360: } ! 1361: ! 1362: /* Restore all variables describing the current status from the structure *P. ! 1363: This is used after a nested function. */ ! 1364: ! 1365: void ! 1366: restore_emit_status (p) ! 1367: struct function *p; ! 1368: { ! 1369: int i; ! 1370: ! 1371: reg_rtx_no = p->reg_rtx_no; ! 1372: first_label_num = p->first_label_num; ! 1373: last_label_num = 0; ! 1374: first_insn = p->first_insn; ! 1375: last_insn = p->last_insn; ! 1376: sequence_rtl_expr = p->sequence_rtl_expr; ! 1377: sequence_stack = p->sequence_stack; ! 1378: cur_insn_uid = p->cur_insn_uid; ! 1379: last_linenum = p->last_linenum; ! 1380: last_filename = p->last_filename; ! 1381: regno_pointer_flag = p->regno_pointer_flag; ! 1382: regno_pointer_flag_length = p->regno_pointer_flag_length; ! 1383: regno_reg_rtx = p->regno_reg_rtx; ! 1384: ! 1385: /* Clear our cache of rtx expressions for start_sequence and gen_sequence. */ ! 1386: sequence_element_free_list = 0; ! 1387: for (i = 0; i < SEQUENCE_RESULT_SIZE; i++) ! 1388: sequence_result[i] = 0; ! 1389: } ! 1390: ! 1391: /* Go through all the RTL insn bodies and copy any invalid shared structure. ! 1392: It does not work to do this twice, because the mark bits set here ! 1393: are not cleared afterwards. */ ! 1394: ! 1395: void ! 1396: unshare_all_rtl (insn) ! 1397: register rtx insn; ! 1398: { ! 1399: for (; insn; insn = NEXT_INSN (insn)) ! 1400: if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN ! 1401: || GET_CODE (insn) == CALL_INSN) ! 1402: { ! 1403: PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn)); ! 1404: REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn)); ! 1405: LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn)); ! 1406: } ! 1407: ! 1408: /* Make sure the addresses of stack slots found outside the insn chain ! 1409: (such as, in DECL_RTL of a variable) are not shared ! 1410: with the insn chain. ! 1411: ! 1412: This special care is necessary when the stack slot MEM does not ! 1413: actually appear in the insn chain. If it does appear, its address ! 1414: is unshared from all else at that point. */ ! 1415: ! 1416: copy_rtx_if_shared (stack_slot_list); ! 1417: } ! 1418: ! 1419: /* Mark ORIG as in use, and return a copy of it if it was already in use. ! 1420: Recursively does the same for subexpressions. */ ! 1421: ! 1422: rtx ! 1423: copy_rtx_if_shared (orig) ! 1424: rtx orig; ! 1425: { ! 1426: register rtx x = orig; ! 1427: register int i; ! 1428: register enum rtx_code code; ! 1429: register char *format_ptr; ! 1430: int copied = 0; ! 1431: ! 1432: if (x == 0) ! 1433: return 0; ! 1434: ! 1435: code = GET_CODE (x); ! 1436: ! 1437: /* These types may be freely shared. */ ! 1438: ! 1439: switch (code) ! 1440: { ! 1441: case REG: ! 1442: case QUEUED: ! 1443: case CONST_INT: ! 1444: case CONST_DOUBLE: ! 1445: case SYMBOL_REF: ! 1446: case CODE_LABEL: ! 1447: case PC: ! 1448: case CC0: ! 1449: case SCRATCH: ! 1450: /* SCRATCH must be shared because they represent distinct values. */ ! 1451: return x; ! 1452: ! 1453: case CONST: ! 1454: /* CONST can be shared if it contains a SYMBOL_REF. If it contains ! 1455: a LABEL_REF, it isn't sharable. */ ! 1456: if (GET_CODE (XEXP (x, 0)) == PLUS ! 1457: && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF ! 1458: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) ! 1459: return x; ! 1460: break; ! 1461: ! 1462: case INSN: ! 1463: case JUMP_INSN: ! 1464: case CALL_INSN: ! 1465: case NOTE: ! 1466: case LABEL_REF: ! 1467: case BARRIER: ! 1468: /* The chain of insns is not being copied. */ ! 1469: return x; ! 1470: ! 1471: case MEM: ! 1472: /* A MEM is allowed to be shared if its address is constant ! 1473: or is a constant plus one of the special registers. */ ! 1474: if (CONSTANT_ADDRESS_P (XEXP (x, 0)) ! 1475: || XEXP (x, 0) == virtual_stack_vars_rtx ! 1476: || XEXP (x, 0) == virtual_incoming_args_rtx) ! 1477: return x; ! 1478: ! 1479: if (GET_CODE (XEXP (x, 0)) == PLUS ! 1480: && (XEXP (XEXP (x, 0), 0) == virtual_stack_vars_rtx ! 1481: || XEXP (XEXP (x, 0), 0) == virtual_incoming_args_rtx) ! 1482: && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1))) ! 1483: { ! 1484: /* This MEM can appear in more than one place, ! 1485: but its address better not be shared with anything else. */ ! 1486: if (! x->used) ! 1487: XEXP (x, 0) = copy_rtx_if_shared (XEXP (x, 0)); ! 1488: x->used = 1; ! 1489: return x; ! 1490: } ! 1491: } ! 1492: ! 1493: /* This rtx may not be shared. If it has already been seen, ! 1494: replace it with a copy of itself. */ ! 1495: ! 1496: if (x->used) ! 1497: { ! 1498: register rtx copy; ! 1499: ! 1500: copy = rtx_alloc (code); ! 1501: bcopy (x, copy, (sizeof (*copy) - sizeof (copy->fld) ! 1502: + sizeof (copy->fld[0]) * GET_RTX_LENGTH (code))); ! 1503: x = copy; ! 1504: copied = 1; ! 1505: } ! 1506: x->used = 1; ! 1507: ! 1508: /* Now scan the subexpressions recursively. ! 1509: We can store any replaced subexpressions directly into X ! 1510: since we know X is not shared! Any vectors in X ! 1511: must be copied if X was copied. */ ! 1512: ! 1513: format_ptr = GET_RTX_FORMAT (code); ! 1514: ! 1515: for (i = 0; i < GET_RTX_LENGTH (code); i++) ! 1516: { ! 1517: switch (*format_ptr++) ! 1518: { ! 1519: case 'e': ! 1520: XEXP (x, i) = copy_rtx_if_shared (XEXP (x, i)); ! 1521: break; ! 1522: ! 1523: case 'E': ! 1524: if (XVEC (x, i) != NULL) ! 1525: { ! 1526: register int j; ! 1527: int len = XVECLEN (x, i); ! 1528: ! 1529: if (copied && len > 0) ! 1530: XVEC (x, i) = gen_rtvec_v (len, &XVECEXP (x, i, 0)); ! 1531: for (j = 0; j < len; j++) ! 1532: XVECEXP (x, i, j) = copy_rtx_if_shared (XVECEXP (x, i, j)); ! 1533: } ! 1534: break; ! 1535: } ! 1536: } ! 1537: return x; ! 1538: } ! 1539: ! 1540: /* Clear all the USED bits in X to allow copy_rtx_if_shared to be used ! 1541: to look for shared sub-parts. */ ! 1542: ! 1543: void ! 1544: reset_used_flags (x) ! 1545: rtx x; ! 1546: { ! 1547: register int i, j; ! 1548: register enum rtx_code code; ! 1549: register char *format_ptr; ! 1550: int copied = 0; ! 1551: ! 1552: if (x == 0) ! 1553: return; ! 1554: ! 1555: code = GET_CODE (x); ! 1556: ! 1557: /* These types may be freely shared so we needn't do any reseting ! 1558: for them. */ ! 1559: ! 1560: switch (code) ! 1561: { ! 1562: case REG: ! 1563: case QUEUED: ! 1564: case CONST_INT: ! 1565: case CONST_DOUBLE: ! 1566: case SYMBOL_REF: ! 1567: case CODE_LABEL: ! 1568: case PC: ! 1569: case CC0: ! 1570: return; ! 1571: ! 1572: case INSN: ! 1573: case JUMP_INSN: ! 1574: case CALL_INSN: ! 1575: case NOTE: ! 1576: case LABEL_REF: ! 1577: case BARRIER: ! 1578: /* The chain of insns is not being copied. */ ! 1579: return; ! 1580: } ! 1581: ! 1582: x->used = 0; ! 1583: ! 1584: format_ptr = GET_RTX_FORMAT (code); ! 1585: for (i = 0; i < GET_RTX_LENGTH (code); i++) ! 1586: { ! 1587: switch (*format_ptr++) ! 1588: { ! 1589: case 'e': ! 1590: reset_used_flags (XEXP (x, i)); ! 1591: break; ! 1592: ! 1593: case 'E': ! 1594: for (j = 0; j < XVECLEN (x, i); j++) ! 1595: reset_used_flags (XVECEXP (x, i, j)); ! 1596: break; ! 1597: } ! 1598: } ! 1599: } ! 1600: ! 1601: /* Copy X if necessary so that it won't be altered by changes in OTHER. ! 1602: Return X or the rtx for the pseudo reg the value of X was copied into. ! 1603: OTHER must be valid as a SET_DEST. */ ! 1604: ! 1605: rtx ! 1606: make_safe_from (x, other) ! 1607: rtx x, other; ! 1608: { ! 1609: while (1) ! 1610: switch (GET_CODE (other)) ! 1611: { ! 1612: case SUBREG: ! 1613: other = SUBREG_REG (other); ! 1614: break; ! 1615: case STRICT_LOW_PART: ! 1616: case SIGN_EXTEND: ! 1617: case ZERO_EXTEND: ! 1618: other = XEXP (other, 0); ! 1619: break; ! 1620: default: ! 1621: goto done; ! 1622: } ! 1623: done: ! 1624: if ((GET_CODE (other) == MEM ! 1625: && ! CONSTANT_P (x) ! 1626: && GET_CODE (x) != REG ! 1627: && GET_CODE (x) != SUBREG) ! 1628: || (GET_CODE (other) == REG ! 1629: && (REGNO (other) < FIRST_PSEUDO_REGISTER ! 1630: || reg_mentioned_p (other, x)))) ! 1631: { ! 1632: rtx temp = gen_reg_rtx (GET_MODE (x)); ! 1633: emit_move_insn (temp, x); ! 1634: return temp; ! 1635: } ! 1636: return x; ! 1637: } ! 1638: ! 1639: /* Emission of insns (adding them to the doubly-linked list). */ ! 1640: ! 1641: /* Return the first insn of the current sequence or current function. */ ! 1642: ! 1643: rtx ! 1644: get_insns () ! 1645: { ! 1646: return first_insn; ! 1647: } ! 1648: ! 1649: /* Return the last insn emitted in current sequence or current function. */ ! 1650: ! 1651: rtx ! 1652: get_last_insn () ! 1653: { ! 1654: return last_insn; ! 1655: } ! 1656: ! 1657: /* Specify a new insn as the last in the chain. */ ! 1658: ! 1659: void ! 1660: set_last_insn (insn) ! 1661: rtx insn; ! 1662: { ! 1663: if (NEXT_INSN (insn) != 0) ! 1664: abort (); ! 1665: last_insn = insn; ! 1666: } ! 1667: ! 1668: /* Return the last insn emitted, even if it is in a sequence now pushed. */ ! 1669: ! 1670: rtx ! 1671: get_last_insn_anywhere () ! 1672: { ! 1673: struct sequence_stack *stack; ! 1674: if (last_insn) ! 1675: return last_insn; ! 1676: for (stack = sequence_stack; stack; stack = stack->next) ! 1677: if (stack->last != 0) ! 1678: return stack->last; ! 1679: return 0; ! 1680: } ! 1681: ! 1682: /* Return a number larger than any instruction's uid in this function. */ ! 1683: ! 1684: int ! 1685: get_max_uid () ! 1686: { ! 1687: return cur_insn_uid; ! 1688: } ! 1689: ! 1690: /* Return the next insn. If it is a SEQUENCE, return the first insn ! 1691: of the sequence. */ ! 1692: ! 1693: rtx ! 1694: next_insn (insn) ! 1695: rtx insn; ! 1696: { ! 1697: if (insn) ! 1698: { ! 1699: insn = NEXT_INSN (insn); ! 1700: if (insn && GET_CODE (insn) == INSN ! 1701: && GET_CODE (PATTERN (insn)) == SEQUENCE) ! 1702: insn = XVECEXP (PATTERN (insn), 0, 0); ! 1703: } ! 1704: ! 1705: return insn; ! 1706: } ! 1707: ! 1708: /* Return the previous insn. If it is a SEQUENCE, return the last insn ! 1709: of the sequence. */ ! 1710: ! 1711: rtx ! 1712: previous_insn (insn) ! 1713: rtx insn; ! 1714: { ! 1715: if (insn) ! 1716: { ! 1717: insn = PREV_INSN (insn); ! 1718: if (insn && GET_CODE (insn) == INSN ! 1719: && GET_CODE (PATTERN (insn)) == SEQUENCE) ! 1720: insn = XVECEXP (PATTERN (insn), 0, XVECLEN (PATTERN (insn), 0) - 1); ! 1721: } ! 1722: ! 1723: return insn; ! 1724: } ! 1725: ! 1726: /* Return the next insn after INSN that is not a NOTE. This routine does not ! 1727: look inside SEQUENCEs. */ ! 1728: ! 1729: rtx ! 1730: next_nonnote_insn (insn) ! 1731: rtx insn; ! 1732: { ! 1733: while (insn) ! 1734: { ! 1735: insn = NEXT_INSN (insn); ! 1736: if (insn == 0 || GET_CODE (insn) != NOTE) ! 1737: break; ! 1738: } ! 1739: ! 1740: return insn; ! 1741: } ! 1742: ! 1743: /* Return the previous insn before INSN that is not a NOTE. This routine does ! 1744: not look inside SEQUENCEs. */ ! 1745: ! 1746: rtx ! 1747: prev_nonnote_insn (insn) ! 1748: rtx insn; ! 1749: { ! 1750: while (insn) ! 1751: { ! 1752: insn = PREV_INSN (insn); ! 1753: if (insn == 0 || GET_CODE (insn) != NOTE) ! 1754: break; ! 1755: } ! 1756: ! 1757: return insn; ! 1758: } ! 1759: ! 1760: /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN; ! 1761: or 0, if there is none. This routine does not look inside ! 1762: SEQUENCEs. */ ! 1763: ! 1764: rtx ! 1765: next_real_insn (insn) ! 1766: rtx insn; ! 1767: { ! 1768: while (insn) ! 1769: { ! 1770: insn = NEXT_INSN (insn); ! 1771: if (insn == 0 || GET_CODE (insn) == INSN ! 1772: || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN) ! 1773: break; ! 1774: } ! 1775: ! 1776: return insn; ! 1777: } ! 1778: ! 1779: /* Return the last INSN, CALL_INSN or JUMP_INSN before INSN; ! 1780: or 0, if there is none. This routine does not look inside ! 1781: SEQUENCEs. */ ! 1782: ! 1783: rtx ! 1784: prev_real_insn (insn) ! 1785: rtx insn; ! 1786: { ! 1787: while (insn) ! 1788: { ! 1789: insn = PREV_INSN (insn); ! 1790: if (insn == 0 || GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN ! 1791: || GET_CODE (insn) == JUMP_INSN) ! 1792: break; ! 1793: } ! 1794: ! 1795: return insn; ! 1796: } ! 1797: ! 1798: /* Find the next insn after INSN that really does something. This routine ! 1799: does not look inside SEQUENCEs. Until reload has completed, this is the ! 1800: same as next_real_insn. */ ! 1801: ! 1802: rtx ! 1803: next_active_insn (insn) ! 1804: rtx insn; ! 1805: { ! 1806: while (insn) ! 1807: { ! 1808: insn = NEXT_INSN (insn); ! 1809: if (insn == 0 ! 1810: || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN ! 1811: || (GET_CODE (insn) == INSN ! 1812: && (! reload_completed ! 1813: || (GET_CODE (PATTERN (insn)) != USE ! 1814: && GET_CODE (PATTERN (insn)) != CLOBBER)))) ! 1815: break; ! 1816: } ! 1817: ! 1818: return insn; ! 1819: } ! 1820: ! 1821: /* Find the last insn before INSN that really does something. This routine ! 1822: does not look inside SEQUENCEs. Until reload has completed, this is the ! 1823: same as prev_real_insn. */ ! 1824: ! 1825: rtx ! 1826: prev_active_insn (insn) ! 1827: rtx insn; ! 1828: { ! 1829: while (insn) ! 1830: { ! 1831: insn = PREV_INSN (insn); ! 1832: if (insn == 0 ! 1833: || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN ! 1834: || (GET_CODE (insn) == INSN ! 1835: && (! reload_completed ! 1836: || (GET_CODE (PATTERN (insn)) != USE ! 1837: && GET_CODE (PATTERN (insn)) != CLOBBER)))) ! 1838: break; ! 1839: } ! 1840: ! 1841: return insn; ! 1842: } ! 1843: ! 1844: /* Return the next CODE_LABEL after the insn INSN, or 0 if there is none. */ ! 1845: ! 1846: rtx ! 1847: next_label (insn) ! 1848: rtx insn; ! 1849: { ! 1850: while (insn) ! 1851: { ! 1852: insn = NEXT_INSN (insn); ! 1853: if (insn == 0 || GET_CODE (insn) == CODE_LABEL) ! 1854: break; ! 1855: } ! 1856: ! 1857: return insn; ! 1858: } ! 1859: ! 1860: /* Return the last CODE_LABEL before the insn INSN, or 0 if there is none. */ ! 1861: ! 1862: rtx ! 1863: prev_label (insn) ! 1864: rtx insn; ! 1865: { ! 1866: while (insn) ! 1867: { ! 1868: insn = PREV_INSN (insn); ! 1869: if (insn == 0 || GET_CODE (insn) == CODE_LABEL) ! 1870: break; ! 1871: } ! 1872: ! 1873: return insn; ! 1874: } ! 1875: ! 1876: #ifdef HAVE_cc0 ! 1877: /* INSN uses CC0 and is being moved into a delay slot. Set up REG_CC_SETTER ! 1878: and REG_CC_USER notes so we can find it. */ ! 1879: ! 1880: void ! 1881: link_cc0_insns (insn) ! 1882: rtx insn; ! 1883: { ! 1884: rtx user = next_nonnote_insn (insn); ! 1885: ! 1886: if (GET_CODE (user) == INSN && GET_CODE (PATTERN (user)) == SEQUENCE) ! 1887: user = XVECEXP (PATTERN (user), 0, 0); ! 1888: ! 1889: REG_NOTES (user) = gen_rtx (INSN_LIST, REG_CC_SETTER, insn, ! 1890: REG_NOTES (user)); ! 1891: REG_NOTES (insn) = gen_rtx (INSN_LIST, REG_CC_USER, user, REG_NOTES (insn)); ! 1892: } ! 1893: ! 1894: /* Return the next insn that uses CC0 after INSN, which is assumed to ! 1895: set it. This is the inverse of prev_cc0_setter (i.e., prev_cc0_setter ! 1896: applied to the result of this function should yield INSN). ! 1897: ! 1898: Normally, this is simply the next insn. However, if a REG_CC_USER note ! 1899: is present, it contains the insn that uses CC0. ! 1900: ! 1901: Return 0 if we can't find the insn. */ ! 1902: ! 1903: rtx ! 1904: next_cc0_user (insn) ! 1905: rtx insn; ! 1906: { ! 1907: rtx note = find_reg_note (insn, REG_CC_USER, NULL_RTX); ! 1908: ! 1909: if (note) ! 1910: return XEXP (note, 0); ! 1911: ! 1912: insn = next_nonnote_insn (insn); ! 1913: ! 1914: if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) ! 1915: insn = XVECEXP (PATTERN (insn), 0, 0); ! 1916: ! 1917: if (insn && GET_RTX_CLASS (GET_CODE (insn)) == 'i' ! 1918: && reg_mentioned_p (cc0_rtx, PATTERN (insn))) ! 1919: return insn; ! 1920: ! 1921: return 0; ! 1922: } ! 1923: ! 1924: /* Find the insn that set CC0 for INSN. Unless INSN has a REG_CC_SETTER ! 1925: note, it is the previous insn. */ ! 1926: ! 1927: rtx ! 1928: prev_cc0_setter (insn) ! 1929: rtx insn; ! 1930: { ! 1931: rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX); ! 1932: rtx link; ! 1933: ! 1934: if (note) ! 1935: return XEXP (note, 0); ! 1936: ! 1937: insn = prev_nonnote_insn (insn); ! 1938: if (! sets_cc0_p (PATTERN (insn))) ! 1939: abort (); ! 1940: ! 1941: return insn; ! 1942: } ! 1943: #endif ! 1944: ! 1945: /* Try splitting insns that can be split for better scheduling. ! 1946: PAT is the pattern which might split. ! 1947: TRIAL is the insn providing PAT. ! 1948: BACKWARDS is non-zero if we are scanning insns from last to first. ! 1949: ! 1950: If this routine succeeds in splitting, it returns the first or last ! 1951: replacement insn depending on the value of BACKWARDS. Otherwise, it ! 1952: returns TRIAL. If the insn to be returned can be split, it will be. */ ! 1953: ! 1954: rtx ! 1955: try_split (pat, trial, backwards) ! 1956: rtx pat, trial; ! 1957: int backwards; ! 1958: { ! 1959: rtx before = PREV_INSN (trial); ! 1960: rtx after = NEXT_INSN (trial); ! 1961: rtx seq = split_insns (pat, trial); ! 1962: int has_barrier = 0; ! 1963: rtx tem; ! 1964: ! 1965: /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER. ! 1966: We may need to handle this specially. */ ! 1967: if (after && GET_CODE (after) == BARRIER) ! 1968: { ! 1969: has_barrier = 1; ! 1970: after = NEXT_INSN (after); ! 1971: } ! 1972: ! 1973: if (seq) ! 1974: { ! 1975: /* SEQ can either be a SEQUENCE or the pattern of a single insn. ! 1976: The latter case will normally arise only when being done so that ! 1977: it, in turn, will be split (SFmode on the 29k is an example). */ ! 1978: if (GET_CODE (seq) == SEQUENCE) ! 1979: { ! 1980: /* If we are splitting a JUMP_INSN, look for the JUMP_INSN in ! 1981: SEQ and copy our JUMP_LABEL to it. If JUMP_LABEL is non-zero, ! 1982: increment the usage count so we don't delete the label. */ ! 1983: int i; ! 1984: ! 1985: if (GET_CODE (trial) == JUMP_INSN) ! 1986: for (i = XVECLEN (seq, 0) - 1; i >= 0; i--) ! 1987: if (GET_CODE (XVECEXP (seq, 0, i)) == JUMP_INSN) ! 1988: { ! 1989: JUMP_LABEL (XVECEXP (seq, 0, i)) = JUMP_LABEL (trial); ! 1990: ! 1991: if (JUMP_LABEL (trial)) ! 1992: LABEL_NUSES (JUMP_LABEL (trial))++; ! 1993: } ! 1994: ! 1995: tem = emit_insn_after (seq, before); ! 1996: ! 1997: delete_insn (trial); ! 1998: if (has_barrier) ! 1999: emit_barrier_after (tem); ! 2000: } ! 2001: /* Avoid infinite loop if the result matches the original pattern. */ ! 2002: else if (rtx_equal_p (seq, pat)) ! 2003: return trial; ! 2004: else ! 2005: { ! 2006: PATTERN (trial) = seq; ! 2007: INSN_CODE (trial) = -1; ! 2008: } ! 2009: ! 2010: /* Set TEM to the insn we should return. */ ! 2011: tem = backwards ? prev_active_insn (after) : next_active_insn (before); ! 2012: return try_split (PATTERN (tem), tem, backwards); ! 2013: } ! 2014: ! 2015: return trial; ! 2016: } ! 2017: ! 2018: /* Make and return an INSN rtx, initializing all its slots. ! 2019: Store PATTERN in the pattern slots. */ ! 2020: ! 2021: rtx ! 2022: make_insn_raw (pattern) ! 2023: rtx pattern; ! 2024: { ! 2025: register rtx insn; ! 2026: ! 2027: insn = rtx_alloc (INSN); ! 2028: INSN_UID (insn) = cur_insn_uid++; ! 2029: ! 2030: PATTERN (insn) = pattern; ! 2031: INSN_CODE (insn) = -1; ! 2032: LOG_LINKS (insn) = NULL; ! 2033: REG_NOTES (insn) = NULL; ! 2034: ! 2035: return insn; ! 2036: } ! 2037: ! 2038: /* Like `make_insn' but make a JUMP_INSN instead of an insn. */ ! 2039: ! 2040: static rtx ! 2041: make_jump_insn_raw (pattern) ! 2042: rtx pattern; ! 2043: { ! 2044: register rtx insn; ! 2045: ! 2046: insn = rtx_alloc (JUMP_INSN); ! 2047: INSN_UID (insn) = cur_insn_uid++; ! 2048: ! 2049: PATTERN (insn) = pattern; ! 2050: INSN_CODE (insn) = -1; ! 2051: LOG_LINKS (insn) = NULL; ! 2052: REG_NOTES (insn) = NULL; ! 2053: JUMP_LABEL (insn) = NULL; ! 2054: ! 2055: return insn; ! 2056: } ! 2057: ! 2058: /* Add INSN to the end of the doubly-linked list. ! 2059: INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE. */ ! 2060: ! 2061: void ! 2062: add_insn (insn) ! 2063: register rtx insn; ! 2064: { ! 2065: PREV_INSN (insn) = last_insn; ! 2066: NEXT_INSN (insn) = 0; ! 2067: ! 2068: if (NULL != last_insn) ! 2069: NEXT_INSN (last_insn) = insn; ! 2070: ! 2071: if (NULL == first_insn) ! 2072: first_insn = insn; ! 2073: ! 2074: last_insn = insn; ! 2075: } ! 2076: ! 2077: /* Add INSN into the doubly-linked list after insn AFTER. This should be the ! 2078: only function called to insert an insn once delay slots have been filled ! 2079: since only it knows how to update a SEQUENCE. */ ! 2080: ! 2081: void ! 2082: add_insn_after (insn, after) ! 2083: rtx insn, after; ! 2084: { ! 2085: rtx next = NEXT_INSN (after); ! 2086: ! 2087: NEXT_INSN (insn) = next; ! 2088: PREV_INSN (insn) = after; ! 2089: ! 2090: if (next) ! 2091: { ! 2092: PREV_INSN (next) = insn; ! 2093: if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE) ! 2094: PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn; ! 2095: } ! 2096: else if (last_insn == after) ! 2097: last_insn = insn; ! 2098: else ! 2099: { ! 2100: struct sequence_stack *stack = sequence_stack; ! 2101: /* Scan all pending sequences too. */ ! 2102: for (; stack; stack = stack->next) ! 2103: if (after == stack->last) ! 2104: stack->last = insn; ! 2105: } ! 2106: ! 2107: NEXT_INSN (after) = insn; ! 2108: if (GET_CODE (after) == INSN && GET_CODE (PATTERN (after)) == SEQUENCE) ! 2109: { ! 2110: rtx sequence = PATTERN (after); ! 2111: NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn; ! 2112: } ! 2113: } ! 2114: ! 2115: /* Delete all insns made since FROM. ! 2116: FROM becomes the new last instruction. */ ! 2117: ! 2118: void ! 2119: delete_insns_since (from) ! 2120: rtx from; ! 2121: { ! 2122: if (from == 0) ! 2123: first_insn = 0; ! 2124: else ! 2125: NEXT_INSN (from) = 0; ! 2126: last_insn = from; ! 2127: } ! 2128: ! 2129: /* Move a consecutive bunch of insns to a different place in the chain. ! 2130: The insns to be moved are those between FROM and TO. ! 2131: They are moved to a new position after the insn AFTER. ! 2132: AFTER must not be FROM or TO or any insn in between. ! 2133: ! 2134: This function does not know about SEQUENCEs and hence should not be ! 2135: called after delay-slot filling has been done. */ ! 2136: ! 2137: void ! 2138: reorder_insns (from, to, after) ! 2139: rtx from, to, after; ! 2140: { ! 2141: /* Splice this bunch out of where it is now. */ ! 2142: if (PREV_INSN (from)) ! 2143: NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to); ! 2144: if (NEXT_INSN (to)) ! 2145: PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from); ! 2146: if (last_insn == to) ! 2147: last_insn = PREV_INSN (from); ! 2148: if (first_insn == from) ! 2149: first_insn = NEXT_INSN (to); ! 2150: ! 2151: /* Make the new neighbors point to it and it to them. */ ! 2152: if (NEXT_INSN (after)) ! 2153: PREV_INSN (NEXT_INSN (after)) = to; ! 2154: ! 2155: NEXT_INSN (to) = NEXT_INSN (after); ! 2156: PREV_INSN (from) = after; ! 2157: NEXT_INSN (after) = from; ! 2158: if (after == last_insn) ! 2159: last_insn = to; ! 2160: } ! 2161: ! 2162: /* Return the line note insn preceding INSN. */ ! 2163: ! 2164: static rtx ! 2165: find_line_note (insn) ! 2166: rtx insn; ! 2167: { ! 2168: if (no_line_numbers) ! 2169: return 0; ! 2170: ! 2171: for (; insn; insn = PREV_INSN (insn)) ! 2172: if (GET_CODE (insn) == NOTE ! 2173: && NOTE_LINE_NUMBER (insn) >= 0) ! 2174: break; ! 2175: ! 2176: return insn; ! 2177: } ! 2178: ! 2179: /* Like reorder_insns, but inserts line notes to preserve the line numbers ! 2180: of the moved insns when debugging. This may insert a note between AFTER ! 2181: and FROM, and another one after TO. */ ! 2182: ! 2183: void ! 2184: reorder_insns_with_line_notes (from, to, after) ! 2185: rtx from, to, after; ! 2186: { ! 2187: rtx from_line = find_line_note (from); ! 2188: rtx after_line = find_line_note (after); ! 2189: ! 2190: reorder_insns (from, to, after); ! 2191: ! 2192: if (from_line == after_line) ! 2193: return; ! 2194: ! 2195: if (from_line) ! 2196: emit_line_note_after (NOTE_SOURCE_FILE (from_line), ! 2197: NOTE_LINE_NUMBER (from_line), ! 2198: after); ! 2199: if (after_line) ! 2200: emit_line_note_after (NOTE_SOURCE_FILE (after_line), ! 2201: NOTE_LINE_NUMBER (after_line), ! 2202: to); ! 2203: } ! 2204: ! 2205: /* Emit an insn of given code and pattern ! 2206: at a specified place within the doubly-linked list. */ ! 2207: ! 2208: /* Make an instruction with body PATTERN ! 2209: and output it before the instruction BEFORE. */ ! 2210: ! 2211: rtx ! 2212: emit_insn_before (pattern, before) ! 2213: register rtx pattern, before; ! 2214: { ! 2215: register rtx insn = before; ! 2216: ! 2217: if (GET_CODE (pattern) == SEQUENCE) ! 2218: { ! 2219: register int i; ! 2220: ! 2221: for (i = 0; i < XVECLEN (pattern, 0); i++) ! 2222: { ! 2223: insn = XVECEXP (pattern, 0, i); ! 2224: add_insn_after (insn, PREV_INSN (before)); ! 2225: } ! 2226: if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE) ! 2227: sequence_result[XVECLEN (pattern, 0)] = pattern; ! 2228: } ! 2229: else ! 2230: { ! 2231: insn = make_insn_raw (pattern); ! 2232: add_insn_after (insn, PREV_INSN (before)); ! 2233: } ! 2234: ! 2235: return insn; ! 2236: } ! 2237: ! 2238: /* Make an instruction with body PATTERN and code JUMP_INSN ! 2239: and output it before the instruction BEFORE. */ ! 2240: ! 2241: rtx ! 2242: emit_jump_insn_before (pattern, before) ! 2243: register rtx pattern, before; ! 2244: { ! 2245: register rtx insn; ! 2246: ! 2247: if (GET_CODE (pattern) == SEQUENCE) ! 2248: insn = emit_insn_before (pattern, before); ! 2249: else ! 2250: { ! 2251: insn = make_jump_insn_raw (pattern); ! 2252: add_insn_after (insn, PREV_INSN (before)); ! 2253: } ! 2254: ! 2255: return insn; ! 2256: } ! 2257: ! 2258: /* Make an instruction with body PATTERN and code CALL_INSN ! 2259: and output it before the instruction BEFORE. */ ! 2260: ! 2261: rtx ! 2262: emit_call_insn_before (pattern, before) ! 2263: register rtx pattern, before; ! 2264: { ! 2265: rtx insn = emit_insn_before (pattern, before); ! 2266: PUT_CODE (insn, CALL_INSN); ! 2267: return insn; ! 2268: } ! 2269: ! 2270: /* Make an insn of code BARRIER ! 2271: and output it before the insn AFTER. */ ! 2272: ! 2273: rtx ! 2274: emit_barrier_before (before) ! 2275: register rtx before; ! 2276: { ! 2277: register rtx insn = rtx_alloc (BARRIER); ! 2278: ! 2279: INSN_UID (insn) = cur_insn_uid++; ! 2280: ! 2281: add_insn_after (insn, PREV_INSN (before)); ! 2282: return insn; ! 2283: } ! 2284: ! 2285: /* Emit a note of subtype SUBTYPE before the insn BEFORE. */ ! 2286: ! 2287: rtx ! 2288: emit_note_before (subtype, before) ! 2289: int subtype; ! 2290: rtx before; ! 2291: { ! 2292: register rtx note = rtx_alloc (NOTE); ! 2293: INSN_UID (note) = cur_insn_uid++; ! 2294: NOTE_SOURCE_FILE (note) = 0; ! 2295: NOTE_LINE_NUMBER (note) = subtype; ! 2296: ! 2297: add_insn_after (note, PREV_INSN (before)); ! 2298: return note; ! 2299: } ! 2300: ! 2301: /* Make an insn of code INSN with body PATTERN ! 2302: and output it after the insn AFTER. */ ! 2303: ! 2304: rtx ! 2305: emit_insn_after (pattern, after) ! 2306: register rtx pattern, after; ! 2307: { ! 2308: register rtx insn = after; ! 2309: ! 2310: if (GET_CODE (pattern) == SEQUENCE) ! 2311: { ! 2312: register int i; ! 2313: ! 2314: for (i = 0; i < XVECLEN (pattern, 0); i++) ! 2315: { ! 2316: insn = XVECEXP (pattern, 0, i); ! 2317: add_insn_after (insn, after); ! 2318: after = insn; ! 2319: } ! 2320: if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE) ! 2321: sequence_result[XVECLEN (pattern, 0)] = pattern; ! 2322: } ! 2323: else ! 2324: { ! 2325: insn = make_insn_raw (pattern); ! 2326: add_insn_after (insn, after); ! 2327: } ! 2328: ! 2329: return insn; ! 2330: } ! 2331: ! 2332: /* Similar to emit_insn_after, except that line notes are to be inserted so ! 2333: as to act as if this insn were at FROM. */ ! 2334: ! 2335: void ! 2336: emit_insn_after_with_line_notes (pattern, after, from) ! 2337: rtx pattern, after, from; ! 2338: { ! 2339: rtx from_line = find_line_note (from); ! 2340: rtx after_line = find_line_note (after); ! 2341: rtx insn = emit_insn_after (pattern, after); ! 2342: ! 2343: if (from_line) ! 2344: emit_line_note_after (NOTE_SOURCE_FILE (from_line), ! 2345: NOTE_LINE_NUMBER (from_line), ! 2346: after); ! 2347: ! 2348: if (after_line) ! 2349: emit_line_note_after (NOTE_SOURCE_FILE (after_line), ! 2350: NOTE_LINE_NUMBER (after_line), ! 2351: insn); ! 2352: } ! 2353: ! 2354: /* Make an insn of code JUMP_INSN with body PATTERN ! 2355: and output it after the insn AFTER. */ ! 2356: ! 2357: rtx ! 2358: emit_jump_insn_after (pattern, after) ! 2359: register rtx pattern, after; ! 2360: { ! 2361: register rtx insn; ! 2362: ! 2363: if (GET_CODE (pattern) == SEQUENCE) ! 2364: insn = emit_insn_after (pattern, after); ! 2365: else ! 2366: { ! 2367: insn = make_jump_insn_raw (pattern); ! 2368: add_insn_after (insn, after); ! 2369: } ! 2370: ! 2371: return insn; ! 2372: } ! 2373: ! 2374: /* Make an insn of code BARRIER ! 2375: and output it after the insn AFTER. */ ! 2376: ! 2377: rtx ! 2378: emit_barrier_after (after) ! 2379: register rtx after; ! 2380: { ! 2381: register rtx insn = rtx_alloc (BARRIER); ! 2382: ! 2383: INSN_UID (insn) = cur_insn_uid++; ! 2384: ! 2385: add_insn_after (insn, after); ! 2386: return insn; ! 2387: } ! 2388: ! 2389: /* Emit the label LABEL after the insn AFTER. */ ! 2390: ! 2391: rtx ! 2392: emit_label_after (label, after) ! 2393: rtx label, after; ! 2394: { ! 2395: /* This can be called twice for the same label ! 2396: as a result of the confusion that follows a syntax error! ! 2397: So make it harmless. */ ! 2398: if (INSN_UID (label) == 0) ! 2399: { ! 2400: INSN_UID (label) = cur_insn_uid++; ! 2401: add_insn_after (label, after); ! 2402: } ! 2403: ! 2404: return label; ! 2405: } ! 2406: ! 2407: /* Emit a note of subtype SUBTYPE after the insn AFTER. */ ! 2408: ! 2409: rtx ! 2410: emit_note_after (subtype, after) ! 2411: int subtype; ! 2412: rtx after; ! 2413: { ! 2414: register rtx note = rtx_alloc (NOTE); ! 2415: INSN_UID (note) = cur_insn_uid++; ! 2416: NOTE_SOURCE_FILE (note) = 0; ! 2417: NOTE_LINE_NUMBER (note) = subtype; ! 2418: add_insn_after (note, after); ! 2419: return note; ! 2420: } ! 2421: ! 2422: /* Emit a line note for FILE and LINE after the insn AFTER. */ ! 2423: ! 2424: rtx ! 2425: emit_line_note_after (file, line, after) ! 2426: char *file; ! 2427: int line; ! 2428: rtx after; ! 2429: { ! 2430: register rtx note; ! 2431: ! 2432: if (no_line_numbers && line > 0) ! 2433: { ! 2434: cur_insn_uid++; ! 2435: return 0; ! 2436: } ! 2437: ! 2438: note = rtx_alloc (NOTE); ! 2439: INSN_UID (note) = cur_insn_uid++; ! 2440: NOTE_SOURCE_FILE (note) = file; ! 2441: NOTE_LINE_NUMBER (note) = line; ! 2442: add_insn_after (note, after); ! 2443: return note; ! 2444: } ! 2445: ! 2446: /* Make an insn of code INSN with pattern PATTERN ! 2447: and add it to the end of the doubly-linked list. ! 2448: If PATTERN is a SEQUENCE, take the elements of it ! 2449: and emit an insn for each element. ! 2450: ! 2451: Returns the last insn emitted. */ ! 2452: ! 2453: rtx ! 2454: emit_insn (pattern) ! 2455: rtx pattern; ! 2456: { ! 2457: rtx insn = last_insn; ! 2458: ! 2459: if (GET_CODE (pattern) == SEQUENCE) ! 2460: { ! 2461: register int i; ! 2462: ! 2463: for (i = 0; i < XVECLEN (pattern, 0); i++) ! 2464: { ! 2465: insn = XVECEXP (pattern, 0, i); ! 2466: add_insn (insn); ! 2467: } ! 2468: if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE) ! 2469: sequence_result[XVECLEN (pattern, 0)] = pattern; ! 2470: } ! 2471: else ! 2472: { ! 2473: insn = make_insn_raw (pattern); ! 2474: add_insn (insn); ! 2475: } ! 2476: ! 2477: return insn; ! 2478: } ! 2479: ! 2480: /* Emit the insns in a chain starting with INSN. ! 2481: Return the last insn emitted. */ ! 2482: ! 2483: rtx ! 2484: emit_insns (insn) ! 2485: rtx insn; ! 2486: { ! 2487: rtx last = 0; ! 2488: ! 2489: while (insn) ! 2490: { ! 2491: rtx next = NEXT_INSN (insn); ! 2492: add_insn (insn); ! 2493: last = insn; ! 2494: insn = next; ! 2495: } ! 2496: ! 2497: return last; ! 2498: } ! 2499: ! 2500: /* Emit the insns in a chain starting with INSN and place them in front of ! 2501: the insn BEFORE. Return the last insn emitted. */ ! 2502: ! 2503: rtx ! 2504: emit_insns_before (insn, before) ! 2505: rtx insn; ! 2506: rtx before; ! 2507: { ! 2508: rtx last = 0; ! 2509: ! 2510: while (insn) ! 2511: { ! 2512: rtx next = NEXT_INSN (insn); ! 2513: add_insn_after (insn, PREV_INSN (before)); ! 2514: last = insn; ! 2515: insn = next; ! 2516: } ! 2517: ! 2518: return last; ! 2519: } ! 2520: ! 2521: /* Emit the insns in a chain starting with FIRST and place them in back of ! 2522: the insn AFTER. Return the last insn emitted. */ ! 2523: ! 2524: rtx ! 2525: emit_insns_after (first, after) ! 2526: register rtx first; ! 2527: register rtx after; ! 2528: { ! 2529: register rtx last; ! 2530: register rtx after_after; ! 2531: ! 2532: if (!after) ! 2533: abort (); ! 2534: ! 2535: if (!first) ! 2536: return first; ! 2537: ! 2538: for (last = first; NEXT_INSN (last); last = NEXT_INSN (last)) ! 2539: continue; ! 2540: ! 2541: after_after = NEXT_INSN (after); ! 2542: ! 2543: NEXT_INSN (after) = first; ! 2544: PREV_INSN (first) = after; ! 2545: NEXT_INSN (last) = after_after; ! 2546: if (after_after) ! 2547: PREV_INSN (after_after) = last; ! 2548: ! 2549: if (after == last_insn) ! 2550: last_insn = last; ! 2551: return last; ! 2552: } ! 2553: ! 2554: /* Make an insn of code JUMP_INSN with pattern PATTERN ! 2555: and add it to the end of the doubly-linked list. */ ! 2556: ! 2557: rtx ! 2558: emit_jump_insn (pattern) ! 2559: rtx pattern; ! 2560: { ! 2561: if (GET_CODE (pattern) == SEQUENCE) ! 2562: return emit_insn (pattern); ! 2563: else ! 2564: { ! 2565: register rtx insn = make_jump_insn_raw (pattern); ! 2566: add_insn (insn); ! 2567: return insn; ! 2568: } ! 2569: } ! 2570: ! 2571: /* Make an insn of code CALL_INSN with pattern PATTERN ! 2572: and add it to the end of the doubly-linked list. */ ! 2573: ! 2574: rtx ! 2575: emit_call_insn (pattern) ! 2576: rtx pattern; ! 2577: { ! 2578: if (GET_CODE (pattern) == SEQUENCE) ! 2579: return emit_insn (pattern); ! 2580: else ! 2581: { ! 2582: register rtx insn = make_insn_raw (pattern); ! 2583: add_insn (insn); ! 2584: PUT_CODE (insn, CALL_INSN); ! 2585: return insn; ! 2586: } ! 2587: } ! 2588: ! 2589: /* Add the label LABEL to the end of the doubly-linked list. */ ! 2590: ! 2591: rtx ! 2592: emit_label (label) ! 2593: rtx label; ! 2594: { ! 2595: /* This can be called twice for the same label ! 2596: as a result of the confusion that follows a syntax error! ! 2597: So make it harmless. */ ! 2598: if (INSN_UID (label) == 0) ! 2599: { ! 2600: INSN_UID (label) = cur_insn_uid++; ! 2601: add_insn (label); ! 2602: } ! 2603: return label; ! 2604: } ! 2605: ! 2606: /* Make an insn of code BARRIER ! 2607: and add it to the end of the doubly-linked list. */ ! 2608: ! 2609: rtx ! 2610: emit_barrier () ! 2611: { ! 2612: register rtx barrier = rtx_alloc (BARRIER); ! 2613: INSN_UID (barrier) = cur_insn_uid++; ! 2614: add_insn (barrier); ! 2615: return barrier; ! 2616: } ! 2617: ! 2618: /* Make an insn of code NOTE ! 2619: with data-fields specified by FILE and LINE ! 2620: and add it to the end of the doubly-linked list, ! 2621: but only if line-numbers are desired for debugging info. */ ! 2622: ! 2623: rtx ! 2624: emit_line_note (file, line) ! 2625: char *file; ! 2626: int line; ! 2627: { ! 2628: if (output_bytecode) ! 2629: { ! 2630: /* FIXME: for now we do nothing, but eventually we will have to deal with ! 2631: debugging information. */ ! 2632: return 0; ! 2633: } ! 2634: ! 2635: emit_filename = file; ! 2636: emit_lineno = line; ! 2637: ! 2638: #if 0 ! 2639: if (no_line_numbers) ! 2640: return 0; ! 2641: #endif ! 2642: ! 2643: return emit_note (file, line); ! 2644: } ! 2645: ! 2646: /* Make an insn of code NOTE ! 2647: with data-fields specified by FILE and LINE ! 2648: and add it to the end of the doubly-linked list. ! 2649: If it is a line-number NOTE, omit it if it matches the previous one. */ ! 2650: ! 2651: rtx ! 2652: emit_note (file, line) ! 2653: char *file; ! 2654: int line; ! 2655: { ! 2656: register rtx note; ! 2657: ! 2658: if (line > 0) ! 2659: { ! 2660: if (file && last_filename && !strcmp (file, last_filename) ! 2661: && line == last_linenum) ! 2662: return 0; ! 2663: last_filename = file; ! 2664: last_linenum = line; ! 2665: } ! 2666: ! 2667: if (no_line_numbers && line > 0) ! 2668: { ! 2669: cur_insn_uid++; ! 2670: return 0; ! 2671: } ! 2672: ! 2673: note = rtx_alloc (NOTE); ! 2674: INSN_UID (note) = cur_insn_uid++; ! 2675: NOTE_SOURCE_FILE (note) = file; ! 2676: NOTE_LINE_NUMBER (note) = line; ! 2677: add_insn (note); ! 2678: return note; ! 2679: } ! 2680: ! 2681: /* Emit a NOTE, and don't omit it even if LINE it the previous note. */ ! 2682: ! 2683: rtx ! 2684: emit_line_note_force (file, line) ! 2685: char *file; ! 2686: int line; ! 2687: { ! 2688: last_linenum = -1; ! 2689: return emit_line_note (file, line); ! 2690: } ! 2691: ! 2692: /* Cause next statement to emit a line note even if the line number ! 2693: has not changed. This is used at the beginning of a function. */ ! 2694: ! 2695: void ! 2696: force_next_line_note () ! 2697: { ! 2698: last_linenum = -1; ! 2699: } ! 2700: ! 2701: /* Return an indication of which type of insn should have X as a body. ! 2702: The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN. */ ! 2703: ! 2704: enum rtx_code ! 2705: classify_insn (x) ! 2706: rtx x; ! 2707: { ! 2708: if (GET_CODE (x) == CODE_LABEL) ! 2709: return CODE_LABEL; ! 2710: if (GET_CODE (x) == CALL) ! 2711: return CALL_INSN; ! 2712: if (GET_CODE (x) == RETURN) ! 2713: return JUMP_INSN; ! 2714: if (GET_CODE (x) == SET) ! 2715: { ! 2716: if (SET_DEST (x) == pc_rtx) ! 2717: return JUMP_INSN; ! 2718: else if (GET_CODE (SET_SRC (x)) == CALL) ! 2719: return CALL_INSN; ! 2720: else ! 2721: return INSN; ! 2722: } ! 2723: if (GET_CODE (x) == PARALLEL) ! 2724: { ! 2725: register int j; ! 2726: for (j = XVECLEN (x, 0) - 1; j >= 0; j--) ! 2727: if (GET_CODE (XVECEXP (x, 0, j)) == CALL) ! 2728: return CALL_INSN; ! 2729: else if (GET_CODE (XVECEXP (x, 0, j)) == SET ! 2730: && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx) ! 2731: return JUMP_INSN; ! 2732: else if (GET_CODE (XVECEXP (x, 0, j)) == SET ! 2733: && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL) ! 2734: return CALL_INSN; ! 2735: } ! 2736: return INSN; ! 2737: } ! 2738: ! 2739: /* Emit the rtl pattern X as an appropriate kind of insn. ! 2740: If X is a label, it is simply added into the insn chain. */ ! 2741: ! 2742: rtx ! 2743: emit (x) ! 2744: rtx x; ! 2745: { ! 2746: enum rtx_code code = classify_insn (x); ! 2747: ! 2748: if (code == CODE_LABEL) ! 2749: return emit_label (x); ! 2750: else if (code == INSN) ! 2751: return emit_insn (x); ! 2752: else if (code == JUMP_INSN) ! 2753: { ! 2754: register rtx insn = emit_jump_insn (x); ! 2755: if (simplejump_p (insn) || GET_CODE (x) == RETURN) ! 2756: return emit_barrier (); ! 2757: return insn; ! 2758: } ! 2759: else if (code == CALL_INSN) ! 2760: return emit_call_insn (x); ! 2761: else ! 2762: abort (); ! 2763: } ! 2764: ! 2765: /* Begin emitting insns to a sequence which can be packaged in an RTL_EXPR. */ ! 2766: ! 2767: void ! 2768: start_sequence () ! 2769: { ! 2770: struct sequence_stack *tem; ! 2771: ! 2772: if (sequence_element_free_list) ! 2773: { ! 2774: /* Reuse a previously-saved struct sequence_stack. */ ! 2775: tem = sequence_element_free_list; ! 2776: sequence_element_free_list = tem->next; ! 2777: } ! 2778: else ! 2779: tem = (struct sequence_stack *) permalloc (sizeof (struct sequence_stack)); ! 2780: ! 2781: tem->next = sequence_stack; ! 2782: tem->first = first_insn; ! 2783: tem->last = last_insn; ! 2784: tem->sequence_rtl_expr = sequence_rtl_expr; ! 2785: ! 2786: sequence_stack = tem; ! 2787: ! 2788: first_insn = 0; ! 2789: last_insn = 0; ! 2790: } ! 2791: ! 2792: /* Similarly, but indicate that this sequence will be placed in ! 2793: T, an RTL_EXPR. */ ! 2794: ! 2795: void ! 2796: start_sequence_for_rtl_expr (t) ! 2797: tree t; ! 2798: { ! 2799: start_sequence (); ! 2800: ! 2801: sequence_rtl_expr = t; ! 2802: } ! 2803: ! 2804: /* Set up the insn chain starting with FIRST ! 2805: as the current sequence, saving the previously current one. */ ! 2806: ! 2807: void ! 2808: push_to_sequence (first) ! 2809: rtx first; ! 2810: { ! 2811: rtx last; ! 2812: ! 2813: start_sequence (); ! 2814: ! 2815: for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last)); ! 2816: ! 2817: first_insn = first; ! 2818: last_insn = last; ! 2819: } ! 2820: ! 2821: /* Set up the outer-level insn chain ! 2822: as the current sequence, saving the previously current one. */ ! 2823: ! 2824: void ! 2825: push_topmost_sequence () ! 2826: { ! 2827: struct sequence_stack *stack, *top; ! 2828: ! 2829: start_sequence (); ! 2830: ! 2831: for (stack = sequence_stack; stack; stack = stack->next) ! 2832: top = stack; ! 2833: ! 2834: first_insn = top->first; ! 2835: last_insn = top->last; ! 2836: sequence_rtl_expr = top->sequence_rtl_expr; ! 2837: } ! 2838: ! 2839: /* After emitting to the outer-level insn chain, update the outer-level ! 2840: insn chain, and restore the previous saved state. */ ! 2841: ! 2842: void ! 2843: pop_topmost_sequence () ! 2844: { ! 2845: struct sequence_stack *stack, *top; ! 2846: ! 2847: for (stack = sequence_stack; stack; stack = stack->next) ! 2848: top = stack; ! 2849: ! 2850: top->first = first_insn; ! 2851: top->last = last_insn; ! 2852: /* ??? Why don't we save sequence_rtl_expr here? */ ! 2853: ! 2854: end_sequence (); ! 2855: } ! 2856: ! 2857: /* After emitting to a sequence, restore previous saved state. ! 2858: ! 2859: To get the contents of the sequence just made, ! 2860: you must call `gen_sequence' *before* calling here. */ ! 2861: ! 2862: void ! 2863: end_sequence () ! 2864: { ! 2865: struct sequence_stack *tem = sequence_stack; ! 2866: ! 2867: first_insn = tem->first; ! 2868: last_insn = tem->last; ! 2869: sequence_rtl_expr = tem->sequence_rtl_expr; ! 2870: sequence_stack = tem->next; ! 2871: ! 2872: tem->next = sequence_element_free_list; ! 2873: sequence_element_free_list = tem; ! 2874: } ! 2875: ! 2876: /* Return 1 if currently emitting into a sequence. */ ! 2877: ! 2878: int ! 2879: in_sequence_p () ! 2880: { ! 2881: return sequence_stack != 0; ! 2882: } ! 2883: ! 2884: /* Generate a SEQUENCE rtx containing the insns already emitted ! 2885: to the current sequence. ! 2886: ! 2887: This is how the gen_... function from a DEFINE_EXPAND ! 2888: constructs the SEQUENCE that it returns. */ ! 2889: ! 2890: rtx ! 2891: gen_sequence () ! 2892: { ! 2893: rtx result; ! 2894: rtx tem; ! 2895: rtvec newvec; ! 2896: int i; ! 2897: int len; ! 2898: ! 2899: /* Count the insns in the chain. */ ! 2900: len = 0; ! 2901: for (tem = first_insn; tem; tem = NEXT_INSN (tem)) ! 2902: len++; ! 2903: ! 2904: /* If only one insn, return its pattern rather than a SEQUENCE. ! 2905: (Now that we cache SEQUENCE expressions, it isn't worth special-casing ! 2906: the case of an empty list.) */ ! 2907: if (len == 1 ! 2908: && (GET_CODE (first_insn) == INSN ! 2909: || GET_CODE (first_insn) == JUMP_INSN ! 2910: || GET_CODE (first_insn) == CALL_INSN)) ! 2911: return PATTERN (first_insn); ! 2912: ! 2913: /* Put them in a vector. See if we already have a SEQUENCE of the ! 2914: appropriate length around. */ ! 2915: if (len < SEQUENCE_RESULT_SIZE && (result = sequence_result[len]) != 0) ! 2916: sequence_result[len] = 0; ! 2917: else ! 2918: { ! 2919: /* Ensure that this rtl goes in saveable_obstack, since we may be ! 2920: caching it. */ ! 2921: push_obstacks_nochange (); ! 2922: rtl_in_saveable_obstack (); ! 2923: result = gen_rtx (SEQUENCE, VOIDmode, rtvec_alloc (len)); ! 2924: pop_obstacks (); ! 2925: } ! 2926: ! 2927: for (i = 0, tem = first_insn; tem; tem = NEXT_INSN (tem), i++) ! 2928: XVECEXP (result, 0, i) = tem; ! 2929: ! 2930: return result; ! 2931: } ! 2932: ! 2933: /* Set up regno_reg_rtx, reg_rtx_no and regno_pointer_flag ! 2934: according to the chain of insns starting with FIRST. ! 2935: ! 2936: Also set cur_insn_uid to exceed the largest uid in that chain. ! 2937: ! 2938: This is used when an inline function's rtl is saved ! 2939: and passed to rest_of_compilation later. */ ! 2940: ! 2941: static void restore_reg_data_1 (); ! 2942: ! 2943: void ! 2944: restore_reg_data (first) ! 2945: rtx first; ! 2946: { ! 2947: register rtx insn; ! 2948: int i; ! 2949: register int max_uid = 0; ! 2950: ! 2951: for (insn = first; insn; insn = NEXT_INSN (insn)) ! 2952: { ! 2953: if (INSN_UID (insn) >= max_uid) ! 2954: max_uid = INSN_UID (insn); ! 2955: ! 2956: switch (GET_CODE (insn)) ! 2957: { ! 2958: case NOTE: ! 2959: case CODE_LABEL: ! 2960: case BARRIER: ! 2961: break; ! 2962: ! 2963: case JUMP_INSN: ! 2964: case CALL_INSN: ! 2965: case INSN: ! 2966: restore_reg_data_1 (PATTERN (insn)); ! 2967: break; ! 2968: } ! 2969: } ! 2970: ! 2971: /* Don't duplicate the uids already in use. */ ! 2972: cur_insn_uid = max_uid + 1; ! 2973: ! 2974: /* If any regs are missing, make them up. ! 2975: ! 2976: ??? word_mode is not necessarily the right mode. Most likely these REGs ! 2977: are never used. At some point this should be checked. */ ! 2978: ! 2979: for (i = FIRST_PSEUDO_REGISTER; i < reg_rtx_no; i++) ! 2980: if (regno_reg_rtx[i] == 0) ! 2981: regno_reg_rtx[i] = gen_rtx (REG, word_mode, i); ! 2982: } ! 2983: ! 2984: static void ! 2985: restore_reg_data_1 (orig) ! 2986: rtx orig; ! 2987: { ! 2988: register rtx x = orig; ! 2989: register int i; ! 2990: register enum rtx_code code; ! 2991: register char *format_ptr; ! 2992: ! 2993: code = GET_CODE (x); ! 2994: ! 2995: switch (code) ! 2996: { ! 2997: case QUEUED: ! 2998: case CONST_INT: ! 2999: case CONST_DOUBLE: ! 3000: case SYMBOL_REF: ! 3001: case CODE_LABEL: ! 3002: case PC: ! 3003: case CC0: ! 3004: case LABEL_REF: ! 3005: return; ! 3006: ! 3007: case REG: ! 3008: if (REGNO (x) >= FIRST_PSEUDO_REGISTER) ! 3009: { ! 3010: /* Make sure regno_pointer_flag and regno_reg_rtx are large ! 3011: enough to have an element for this pseudo reg number. */ ! 3012: if (REGNO (x) >= reg_rtx_no) ! 3013: { ! 3014: reg_rtx_no = REGNO (x); ! 3015: ! 3016: if (reg_rtx_no >= regno_pointer_flag_length) ! 3017: { ! 3018: int newlen = MAX (regno_pointer_flag_length * 2, ! 3019: reg_rtx_no + 30); ! 3020: rtx *new1; ! 3021: char *new = (char *) oballoc (newlen); ! 3022: bzero (new, newlen); ! 3023: bcopy (regno_pointer_flag, new, regno_pointer_flag_length); ! 3024: ! 3025: new1 = (rtx *) oballoc (newlen * sizeof (rtx)); ! 3026: bzero (new1, newlen * sizeof (rtx)); ! 3027: bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx)); ! 3028: ! 3029: regno_pointer_flag = new; ! 3030: regno_reg_rtx = new1; ! 3031: regno_pointer_flag_length = newlen; ! 3032: } ! 3033: reg_rtx_no ++; ! 3034: } ! 3035: regno_reg_rtx[REGNO (x)] = x; ! 3036: } ! 3037: return; ! 3038: ! 3039: case MEM: ! 3040: if (GET_CODE (XEXP (x, 0)) == REG) ! 3041: mark_reg_pointer (XEXP (x, 0)); ! 3042: restore_reg_data_1 (XEXP (x, 0)); ! 3043: return; ! 3044: } ! 3045: ! 3046: /* Now scan the subexpressions recursively. */ ! 3047: ! 3048: format_ptr = GET_RTX_FORMAT (code); ! 3049: ! 3050: for (i = 0; i < GET_RTX_LENGTH (code); i++) ! 3051: { ! 3052: switch (*format_ptr++) ! 3053: { ! 3054: case 'e': ! 3055: restore_reg_data_1 (XEXP (x, i)); ! 3056: break; ! 3057: ! 3058: case 'E': ! 3059: if (XVEC (x, i) != NULL) ! 3060: { ! 3061: register int j; ! 3062: ! 3063: for (j = 0; j < XVECLEN (x, i); j++) ! 3064: restore_reg_data_1 (XVECEXP (x, i, j)); ! 3065: } ! 3066: break; ! 3067: } ! 3068: } ! 3069: } ! 3070: ! 3071: /* Initialize data structures and variables in this file ! 3072: before generating rtl for each function. */ ! 3073: ! 3074: void ! 3075: init_emit () ! 3076: { ! 3077: int i; ! 3078: ! 3079: first_insn = NULL; ! 3080: last_insn = NULL; ! 3081: sequence_rtl_expr = NULL; ! 3082: cur_insn_uid = 1; ! 3083: reg_rtx_no = LAST_VIRTUAL_REGISTER + 1; ! 3084: last_linenum = 0; ! 3085: last_filename = 0; ! 3086: first_label_num = label_num; ! 3087: last_label_num = 0; ! 3088: sequence_stack = NULL; ! 3089: ! 3090: /* Clear the start_sequence/gen_sequence cache. */ ! 3091: sequence_element_free_list = 0; ! 3092: for (i = 0; i < SEQUENCE_RESULT_SIZE; i++) ! 3093: sequence_result[i] = 0; ! 3094: ! 3095: /* Init the tables that describe all the pseudo regs. */ ! 3096: ! 3097: regno_pointer_flag_length = LAST_VIRTUAL_REGISTER + 101; ! 3098: ! 3099: regno_pointer_flag ! 3100: = (char *) oballoc (regno_pointer_flag_length); ! 3101: bzero (regno_pointer_flag, regno_pointer_flag_length); ! 3102: ! 3103: regno_reg_rtx ! 3104: = (rtx *) oballoc (regno_pointer_flag_length * sizeof (rtx)); ! 3105: bzero (regno_reg_rtx, regno_pointer_flag_length * sizeof (rtx)); ! 3106: ! 3107: /* Put copies of all the virtual register rtx into regno_reg_rtx. */ ! 3108: regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx; ! 3109: regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx; ! 3110: regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx; ! 3111: regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx; ! 3112: ! 3113: /* Indicate that the virtual registers and stack locations are ! 3114: all pointers. */ ! 3115: REGNO_POINTER_FLAG (STACK_POINTER_REGNUM) = 1; ! 3116: REGNO_POINTER_FLAG (FRAME_POINTER_REGNUM) = 1; ! 3117: REGNO_POINTER_FLAG (ARG_POINTER_REGNUM) = 1; ! 3118: ! 3119: REGNO_POINTER_FLAG (VIRTUAL_INCOMING_ARGS_REGNUM) = 1; ! 3120: REGNO_POINTER_FLAG (VIRTUAL_STACK_VARS_REGNUM) = 1; ! 3121: REGNO_POINTER_FLAG (VIRTUAL_STACK_DYNAMIC_REGNUM) = 1; ! 3122: REGNO_POINTER_FLAG (VIRTUAL_OUTGOING_ARGS_REGNUM) = 1; ! 3123: ! 3124: #ifdef INIT_EXPANDERS ! 3125: INIT_EXPANDERS; ! 3126: #endif ! 3127: } ! 3128: ! 3129: /* Create some permanent unique rtl objects shared between all functions. ! 3130: LINE_NUMBERS is nonzero if line numbers are to be generated. */ ! 3131: ! 3132: void ! 3133: init_emit_once (line_numbers) ! 3134: int line_numbers; ! 3135: { ! 3136: int i; ! 3137: enum machine_mode mode; ! 3138: ! 3139: no_line_numbers = ! line_numbers; ! 3140: ! 3141: sequence_stack = NULL; ! 3142: ! 3143: /* Compute the word and byte modes. */ ! 3144: ! 3145: byte_mode = VOIDmode; ! 3146: word_mode = VOIDmode; ! 3147: ! 3148: for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; ! 3149: mode = GET_MODE_WIDER_MODE (mode)) ! 3150: { ! 3151: if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT ! 3152: && byte_mode == VOIDmode) ! 3153: byte_mode = mode; ! 3154: ! 3155: if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD ! 3156: && word_mode == VOIDmode) ! 3157: word_mode = mode; ! 3158: } ! 3159: ! 3160: /* Create the unique rtx's for certain rtx codes and operand values. */ ! 3161: ! 3162: pc_rtx = gen_rtx (PC, VOIDmode); ! 3163: cc0_rtx = gen_rtx (CC0, VOIDmode); ! 3164: ! 3165: /* Don't use gen_rtx here since gen_rtx in this case ! 3166: tries to use these variables. */ ! 3167: for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++) ! 3168: { ! 3169: const_int_rtx[i + MAX_SAVED_CONST_INT] = rtx_alloc (CONST_INT); ! 3170: PUT_MODE (const_int_rtx[i + MAX_SAVED_CONST_INT], VOIDmode); ! 3171: INTVAL (const_int_rtx[i + MAX_SAVED_CONST_INT]) = i; ! 3172: } ! 3173: ! 3174: /* These four calls obtain some of the rtx expressions made above. */ ! 3175: const0_rtx = GEN_INT (0); ! 3176: const1_rtx = GEN_INT (1); ! 3177: const2_rtx = GEN_INT (2); ! 3178: constm1_rtx = GEN_INT (-1); ! 3179: ! 3180: /* This will usually be one of the above constants, but may be a new rtx. */ ! 3181: const_true_rtx = GEN_INT (STORE_FLAG_VALUE); ! 3182: ! 3183: dconst0 = REAL_VALUE_ATOF ("0", DFmode); ! 3184: dconst1 = REAL_VALUE_ATOF ("1", DFmode); ! 3185: dconst2 = REAL_VALUE_ATOF ("2", DFmode); ! 3186: dconstm1 = REAL_VALUE_ATOF ("-1", DFmode); ! 3187: ! 3188: for (i = 0; i <= 2; i++) ! 3189: { ! 3190: for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode; ! 3191: mode = GET_MODE_WIDER_MODE (mode)) ! 3192: { ! 3193: rtx tem = rtx_alloc (CONST_DOUBLE); ! 3194: union real_extract u; ! 3195: ! 3196: bzero (&u, sizeof u); /* Zero any holes in a structure. */ ! 3197: u.d = i == 0 ? dconst0 : i == 1 ? dconst1 : dconst2; ! 3198: ! 3199: bcopy (&u, &CONST_DOUBLE_LOW (tem), sizeof u); ! 3200: CONST_DOUBLE_MEM (tem) = cc0_rtx; ! 3201: PUT_MODE (tem, mode); ! 3202: ! 3203: const_tiny_rtx[i][(int) mode] = tem; ! 3204: } ! 3205: ! 3206: const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i); ! 3207: ! 3208: for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; ! 3209: mode = GET_MODE_WIDER_MODE (mode)) ! 3210: const_tiny_rtx[i][(int) mode] = GEN_INT (i); ! 3211: ! 3212: for (mode = GET_CLASS_NARROWEST_MODE (MODE_PARTIAL_INT); ! 3213: mode != VOIDmode; ! 3214: mode = GET_MODE_WIDER_MODE (mode)) ! 3215: const_tiny_rtx[i][(int) mode] = GEN_INT (i); ! 3216: } ! 3217: ! 3218: for (mode = GET_CLASS_NARROWEST_MODE (MODE_CC); mode != VOIDmode; ! 3219: mode = GET_MODE_WIDER_MODE (mode)) ! 3220: const_tiny_rtx[0][(int) mode] = const0_rtx; ! 3221: ! 3222: stack_pointer_rtx = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM); ! 3223: frame_pointer_rtx = gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM); ! 3224: ! 3225: if (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM) ! 3226: hard_frame_pointer_rtx = frame_pointer_rtx; ! 3227: else ! 3228: hard_frame_pointer_rtx = gen_rtx (REG, Pmode, HARD_FRAME_POINTER_REGNUM); ! 3229: ! 3230: if (FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM) ! 3231: arg_pointer_rtx = frame_pointer_rtx; ! 3232: else if (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM) ! 3233: arg_pointer_rtx = hard_frame_pointer_rtx; ! 3234: else if (STACK_POINTER_REGNUM == ARG_POINTER_REGNUM) ! 3235: arg_pointer_rtx = stack_pointer_rtx; ! 3236: else ! 3237: arg_pointer_rtx = gen_rtx (REG, Pmode, ARG_POINTER_REGNUM); ! 3238: ! 3239: /* Create the virtual registers. Do so here since the following objects ! 3240: might reference them. */ ! 3241: ! 3242: virtual_incoming_args_rtx = gen_rtx (REG, Pmode, ! 3243: VIRTUAL_INCOMING_ARGS_REGNUM); ! 3244: virtual_stack_vars_rtx = gen_rtx (REG, Pmode, ! 3245: VIRTUAL_STACK_VARS_REGNUM); ! 3246: virtual_stack_dynamic_rtx = gen_rtx (REG, Pmode, ! 3247: VIRTUAL_STACK_DYNAMIC_REGNUM); ! 3248: virtual_outgoing_args_rtx = gen_rtx (REG, Pmode, ! 3249: VIRTUAL_OUTGOING_ARGS_REGNUM); ! 3250: ! 3251: #ifdef STRUCT_VALUE ! 3252: struct_value_rtx = STRUCT_VALUE; ! 3253: #else ! 3254: struct_value_rtx = gen_rtx (REG, Pmode, STRUCT_VALUE_REGNUM); ! 3255: #endif ! 3256: ! 3257: #ifdef STRUCT_VALUE_INCOMING ! 3258: struct_value_incoming_rtx = STRUCT_VALUE_INCOMING; ! 3259: #else ! 3260: #ifdef STRUCT_VALUE_INCOMING_REGNUM ! 3261: struct_value_incoming_rtx ! 3262: = gen_rtx (REG, Pmode, STRUCT_VALUE_INCOMING_REGNUM); ! 3263: #else ! 3264: struct_value_incoming_rtx = struct_value_rtx; ! 3265: #endif ! 3266: #endif ! 3267: ! 3268: #ifdef STATIC_CHAIN_REGNUM ! 3269: static_chain_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM); ! 3270: ! 3271: #ifdef STATIC_CHAIN_INCOMING_REGNUM ! 3272: if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM) ! 3273: static_chain_incoming_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_INCOMING_REGNUM); ! 3274: else ! 3275: #endif ! 3276: static_chain_incoming_rtx = static_chain_rtx; ! 3277: #endif ! 3278: ! 3279: #ifdef STATIC_CHAIN ! 3280: static_chain_rtx = STATIC_CHAIN; ! 3281: ! 3282: #ifdef STATIC_CHAIN_INCOMING ! 3283: static_chain_incoming_rtx = STATIC_CHAIN_INCOMING; ! 3284: #else ! 3285: static_chain_incoming_rtx = static_chain_rtx; ! 3286: #endif ! 3287: #endif ! 3288: ! 3289: #ifdef PIC_OFFSET_TABLE_REGNUM ! 3290: pic_offset_table_rtx = gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM); ! 3291: #endif ! 3292: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.