|
|
1.1 root 1: /* Definitions for code generation pass of GNU compiler. 1.1.1.8 ! root 2: Copyright (C) 1987, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU CC. 5: 6: GNU CC is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU CC is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU CC; see the file COPYING. If not, write to 1.1.1.8 ! root 18: the Free Software Foundation, 59 Temple Place - Suite 330, ! 19: Boston, MA 02111-1307, USA. */ 1.1 root 20: 21: 22: #ifndef __STDC__ 23: #ifndef const 24: #define const 25: #endif 26: #endif 27: 28: /* The default branch cost is 1. */ 29: #ifndef BRANCH_COST 30: #define BRANCH_COST 1 31: #endif 32: 33: /* Macros to access the slots of a QUEUED rtx. 34: Here rather than in rtl.h because only the expansion pass 35: should ever encounter a QUEUED. */ 36: 37: /* The variable for which an increment is queued. */ 38: #define QUEUED_VAR(P) XEXP (P, 0) 39: /* If the increment has been emitted, this is the insn 40: that does the increment. It is zero before the increment is emitted. */ 41: #define QUEUED_INSN(P) XEXP (P, 1) 42: /* If a pre-increment copy has been generated, this is the copy 43: (it is a temporary reg). Zero if no copy made yet. */ 44: #define QUEUED_COPY(P) XEXP (P, 2) 45: /* This is the body to use for the insn to do the increment. 46: It is used to emit the increment. */ 47: #define QUEUED_BODY(P) XEXP (P, 3) 48: /* Next QUEUED in the queue. */ 49: #define QUEUED_NEXT(P) XEXP (P, 4) 50: 51: /* This is the 4th arg to `expand_expr'. 52: EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx. 53: EXPAND_INITIALIZER is similar but also record any labels on forced_labels. 54: EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address 55: is a constant that is not a legitimate address. */ 56: enum expand_modifier {EXPAND_NORMAL, EXPAND_SUM, 57: EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER}; 58: 59: /* List of labels that must never be deleted. */ 60: extern rtx forced_labels; 61: 62: /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs. 63: So we can mark them all live at the end of the function, if stupid. */ 64: extern rtx save_expr_regs; 65: 66: extern int current_function_calls_alloca; 67: extern int current_function_outgoing_args_size; 68: 69: /* This is the offset from the arg pointer to the place where the first 70: anonymous arg can be found, if there is one. */ 71: extern rtx current_function_arg_offset_rtx; 72: 73: /* This is nonzero if the current function uses the constant pool. */ 74: extern int current_function_uses_const_pool; 75: 76: /* This is nonzero if the current function uses pic_offset_table_rtx. */ 77: extern int current_function_uses_pic_offset_table; 78: 79: /* The arg pointer hard register, or the pseudo into which it was copied. */ 80: extern rtx current_function_internal_arg_pointer; 81: 82: /* Nonzero means stack pops must not be deferred, and deferred stack 83: pops must not be output. It is nonzero inside a function call, 84: inside a conditional expression, inside a statement expression, 85: and in other cases as well. */ 86: extern int inhibit_defer_pop; 87: 88: /* Number of function calls seen so far in current function. */ 89: 90: extern int function_call_count; 91: 92: /* RTX for stack slot that holds the current handler for nonlocal gotos. 93: Zero when function does not have nonlocal labels. */ 94: 95: extern rtx nonlocal_goto_handler_slot; 96: 97: /* RTX for stack slot that holds the stack pointer value to restore 98: for a nonlocal goto. 99: Zero when function does not have nonlocal labels. */ 100: 101: extern rtx nonlocal_goto_stack_level; 102: 103: /* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels 104: (labels to which there can be nonlocal gotos from nested functions) 105: in this function. */ 106: 107: #ifdef TREE_CODE /* Don't lose if tree.h not included. */ 108: extern tree nonlocal_labels; 109: #endif 110: 111: #define NO_DEFER_POP (inhibit_defer_pop += 1) 112: #define OK_DEFER_POP (inhibit_defer_pop -= 1) 113: 114: /* Number of units that we should eventually pop off the stack. 115: These are the arguments to function calls that have already returned. */ 116: extern int pending_stack_adjust; 117: 118: /* A list of all cleanups which belong to the arguments of 119: function calls being expanded by expand_call. */ 120: #ifdef TREE_CODE /* Don't lose if tree.h not included. */ 121: extern tree cleanups_this_call; 122: #endif 1.1.1.7 root 123: 124: /* When temporaries are created by TARGET_EXPRs, they are created at 125: this level of temp_slot_level, so that they can remain allocated 126: until no longer needed. CLEANUP_POINT_EXPRs define the lifetime 127: of TARGET_EXPRs. */ 128: extern int target_temp_slot_level; 1.1 root 129: 130: #ifdef TREE_CODE /* Don't lose if tree.h not included. */ 131: /* Structure to record the size of a sequence of arguments 132: as the sum of a tree-expression and a constant. */ 133: 134: struct args_size 135: { 136: int constant; 137: tree var; 138: }; 139: #endif 140: 141: /* Add the value of the tree INC to the `struct args_size' TO. */ 142: 143: #define ADD_PARM_SIZE(TO, INC) \ 144: { tree inc = (INC); \ 145: if (TREE_CODE (inc) == INTEGER_CST) \ 146: (TO).constant += TREE_INT_CST_LOW (inc); \ 147: else if ((TO).var == 0) \ 148: (TO).var = inc; \ 149: else \ 150: (TO).var = size_binop (PLUS_EXPR, (TO).var, inc); } 151: 152: #define SUB_PARM_SIZE(TO, DEC) \ 153: { tree dec = (DEC); \ 154: if (TREE_CODE (dec) == INTEGER_CST) \ 155: (TO).constant -= TREE_INT_CST_LOW (dec); \ 156: else if ((TO).var == 0) \ 157: (TO).var = size_binop (MINUS_EXPR, integer_zero_node, dec); \ 158: else \ 159: (TO).var = size_binop (MINUS_EXPR, (TO).var, dec); } 160: 161: /* Convert the implicit sum in a `struct args_size' into an rtx. */ 162: #define ARGS_SIZE_RTX(SIZE) \ 1.1.1.4 root 163: ((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \ 1.1 root 164: : expand_expr (size_binop (PLUS_EXPR, (SIZE).var, \ 165: size_int ((SIZE).constant)), \ 1.1.1.4 root 166: NULL_RTX, VOIDmode, 0)) 1.1 root 167: 168: /* Convert the implicit sum in a `struct args_size' into a tree. */ 169: #define ARGS_SIZE_TREE(SIZE) \ 170: ((SIZE).var == 0 ? size_int ((SIZE).constant) \ 171: : size_binop (PLUS_EXPR, (SIZE).var, size_int ((SIZE).constant))) 172: 173: /* Supply a default definition for FUNCTION_ARG_PADDING: 1.1.1.4 root 174: usually pad upward, but pad short args downward on 1.1 root 175: big-endian machines. */ 176: 177: enum direction {none, upward, downward}; /* Value has this type. */ 178: 179: #ifndef FUNCTION_ARG_PADDING 180: #define FUNCTION_ARG_PADDING(MODE, TYPE) \ 1.1.1.8 ! root 181: (! BYTES_BIG_ENDIAN \ ! 182: ? upward \ ! 183: : (((MODE) == BLKmode \ ! 184: ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ ! 185: && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \ ! 186: : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \ ! 187: ? downward : upward)) 1.1 root 188: #endif 189: 190: /* Supply a default definition for FUNCTION_ARG_BOUNDARY. Normally, we let 191: FUNCTION_ARG_PADDING, which also pads the length, handle any needed 192: alignment. */ 193: 194: #ifndef FUNCTION_ARG_BOUNDARY 195: #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) PARM_BOUNDARY 196: #endif 197: 198: /* Nonzero if we do not know how to pass TYPE solely in registers. 199: We cannot do so in the following cases: 200: 201: - if the type has variable size 202: - if the type is marked as addressable (it is required to be constructed 203: into the stack) 204: - if the padding and mode of the type is such that a copy into a register 1.1.1.5 root 205: would put it into the wrong part of the register. 206: 207: Which padding can't be supported depends on the byte endianness. 1.1 root 208: 1.1.1.5 root 209: A value in a register is implicitly padded at the most significant end. 1.1 root 210: On a big-endian machine, that is the lower end in memory. 211: So a value padded in memory at the upper end can't go in a register. 212: For a little-endian machine, the reverse is true. */ 213: 214: #define MUST_PASS_IN_STACK(MODE,TYPE) \ 215: ((TYPE) != 0 \ 216: && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \ 217: || TREE_ADDRESSABLE (TYPE) \ 218: || ((MODE) == BLKmode \ 1.1.1.5 root 219: && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ 220: && 0 == (int_size_in_bytes (TYPE) \ 221: % (PARM_BOUNDARY / BITS_PER_UNIT))) \ 1.1 root 222: && (FUNCTION_ARG_PADDING (MODE, TYPE) \ 1.1.1.8 ! root 223: == (BYTES_BIG_ENDIAN ? upward : downward))))) 1.1 root 224: 1.1.1.5 root 225: /* Nonzero if type TYPE should be returned in memory. 1.1 root 226: Most machines can use the following default definition. */ 227: 228: #ifndef RETURN_IN_MEMORY 1.1.1.5 root 229: #define RETURN_IN_MEMORY(TYPE) (TYPE_MODE (TYPE) == BLKmode) 1.1 root 230: #endif 231: 232: /* Optabs are tables saying how to generate insn bodies 233: for various machine modes and numbers of operands. 234: Each optab applies to one operation. 235: For example, add_optab applies to addition. 236: 237: The insn_code slot is the enum insn_code that says how to 238: generate an insn for this operation on a particular machine mode. 239: It is CODE_FOR_nothing if there is no such insn on the target machine. 240: 241: The `lib_call' slot is the name of the library function that 242: can be used to perform the operation. 243: 244: A few optabs, such as move_optab and cmp_optab, are used 245: by special code. */ 246: 247: /* Everything that uses expr.h needs to define enum insn_code 248: but we don't list it in the Makefile dependencies just for that. */ 249: #include "insn-codes.h" 250: 251: typedef struct optab 252: { 253: enum rtx_code code; 254: struct { 255: enum insn_code insn_code; 256: rtx libfunc; 257: } handlers [NUM_MACHINE_MODES]; 258: } * optab; 259: 260: /* Given an enum insn_code, access the function to construct 261: the body of that kind of insn. */ 262: #ifdef FUNCTION_CONVERSION_BUG 263: /* Some compilers fail to convert a function properly to a 264: pointer-to-function when used as an argument. 265: So produce the pointer-to-function directly. 266: Luckily, these compilers seem to work properly when you 267: call the pointer-to-function. */ 268: #define GEN_FCN(CODE) (insn_gen_function[(int) (CODE)]) 269: #else 270: #define GEN_FCN(CODE) (*insn_gen_function[(int) (CODE)]) 271: #endif 272: 273: extern rtx (*const insn_gen_function[]) (); 274: 275: extern optab add_optab; 276: extern optab sub_optab; 1.1.1.3 root 277: extern optab smul_optab; /* Signed and floating-point multiply */ 1.1.1.7 root 278: extern optab smul_highpart_optab; /* Signed multiply, return high word */ 279: extern optab umul_highpart_optab; 1.1 root 280: extern optab smul_widen_optab; /* Signed multiply with result 281: one machine mode wider than args */ 282: extern optab umul_widen_optab; 283: extern optab sdiv_optab; /* Signed divide */ 284: extern optab sdivmod_optab; /* Signed divide-and-remainder in one */ 285: extern optab udiv_optab; 286: extern optab udivmod_optab; 287: extern optab smod_optab; /* Signed remainder */ 288: extern optab umod_optab; 289: extern optab flodiv_optab; /* Optab for floating divide. */ 290: extern optab ftrunc_optab; /* Convert float to integer in float fmt */ 291: extern optab and_optab; /* Logical and */ 292: extern optab ior_optab; /* Logical or */ 293: extern optab xor_optab; /* Logical xor */ 294: extern optab ashl_optab; /* Arithmetic shift left */ 295: extern optab ashr_optab; /* Arithmetic shift right */ 296: extern optab lshr_optab; /* Logical shift right */ 297: extern optab rotl_optab; /* Rotate left */ 298: extern optab rotr_optab; /* Rotate right */ 1.1.1.3 root 299: extern optab smin_optab; /* Signed and floating-point minimum value */ 300: extern optab smax_optab; /* Signed and floating-point maximum value */ 1.1 root 301: extern optab umin_optab; /* Unsigned minimum value */ 302: extern optab umax_optab; /* Unsigned maximum value */ 303: 304: extern optab mov_optab; /* Move instruction. */ 305: extern optab movstrict_optab; /* Move, preserving high part of register. */ 306: 307: extern optab cmp_optab; /* Compare insn; two operands. */ 308: extern optab tst_optab; /* tst insn; compare one operand against 0 */ 309: 310: /* Unary operations */ 311: extern optab neg_optab; /* Negation */ 312: extern optab abs_optab; /* Abs value */ 313: extern optab one_cmpl_optab; /* Bitwise not */ 314: extern optab ffs_optab; /* Find first bit set */ 1.1.1.2 root 315: extern optab sqrt_optab; /* Square root */ 1.1.1.4 root 316: extern optab sin_optab; /* Sine */ 317: extern optab cos_optab; /* Cosine */ 1.1.1.3 root 318: extern optab strlen_optab; /* String length */ 1.1 root 319: 1.1.1.5 root 320: /* Tables of patterns for extending one integer mode to another. */ 321: extern enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2]; 322: 323: /* Tables of patterns for converting between fixed and floating point. */ 324: extern enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; 325: extern enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; 326: extern enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; 327: 1.1.1.6 root 328: /* Contains the optab used for each rtx code. */ 329: extern optab code_to_optab[NUM_RTX_CODE + 1]; 330: 1.1 root 331: /* Passed to expand_binop and expand_unop to say which options to try to use 332: if the requested operation can't be open-coded on the requisite mode. 333: Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using a library call. 334: Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try using a wider mode. 335: OPTAB_MUST_WIDEN says try widening and don't try anything else. */ 336: 337: enum optab_methods 338: { 339: OPTAB_DIRECT, 340: OPTAB_LIB, 341: OPTAB_WIDEN, 342: OPTAB_LIB_WIDEN, 343: OPTAB_MUST_WIDEN 344: }; 345: 346: /* SYMBOL_REF rtx's for the library functions that are called 347: implicitly and not via optabs. */ 348: 349: extern rtx extendsfdf2_libfunc; 1.1.1.4 root 350: extern rtx extendsfxf2_libfunc; 351: extern rtx extendsftf2_libfunc; 352: extern rtx extenddfxf2_libfunc; 353: extern rtx extenddftf2_libfunc; 354: 1.1 root 355: extern rtx truncdfsf2_libfunc; 1.1.1.4 root 356: extern rtx truncxfsf2_libfunc; 357: extern rtx trunctfsf2_libfunc; 358: extern rtx truncxfdf2_libfunc; 359: extern rtx trunctfdf2_libfunc; 360: 1.1 root 361: extern rtx memcpy_libfunc; 362: extern rtx bcopy_libfunc; 363: extern rtx memcmp_libfunc; 364: extern rtx bcmp_libfunc; 365: extern rtx memset_libfunc; 366: extern rtx bzero_libfunc; 1.1.1.4 root 367: 1.1.1.7 root 368: extern rtx eqhf2_libfunc; 369: extern rtx nehf2_libfunc; 370: extern rtx gthf2_libfunc; 371: extern rtx gehf2_libfunc; 372: extern rtx lthf2_libfunc; 373: extern rtx lehf2_libfunc; 374: 1.1 root 375: extern rtx eqsf2_libfunc; 376: extern rtx nesf2_libfunc; 377: extern rtx gtsf2_libfunc; 378: extern rtx gesf2_libfunc; 379: extern rtx ltsf2_libfunc; 380: extern rtx lesf2_libfunc; 1.1.1.4 root 381: 1.1 root 382: extern rtx eqdf2_libfunc; 383: extern rtx nedf2_libfunc; 384: extern rtx gtdf2_libfunc; 385: extern rtx gedf2_libfunc; 386: extern rtx ltdf2_libfunc; 387: extern rtx ledf2_libfunc; 1.1.1.4 root 388: 389: extern rtx eqxf2_libfunc; 390: extern rtx nexf2_libfunc; 391: extern rtx gtxf2_libfunc; 392: extern rtx gexf2_libfunc; 393: extern rtx ltxf2_libfunc; 394: extern rtx lexf2_libfunc; 395: 396: extern rtx eqtf2_libfunc; 397: extern rtx netf2_libfunc; 398: extern rtx gttf2_libfunc; 399: extern rtx getf2_libfunc; 400: extern rtx lttf2_libfunc; 401: extern rtx letf2_libfunc; 402: 1.1 root 403: extern rtx floatsisf_libfunc; 1.1.1.4 root 404: extern rtx floatdisf_libfunc; 405: extern rtx floattisf_libfunc; 406: 1.1 root 407: extern rtx floatsidf_libfunc; 1.1.1.4 root 408: extern rtx floatdidf_libfunc; 409: extern rtx floattidf_libfunc; 410: 411: extern rtx floatsixf_libfunc; 412: extern rtx floatdixf_libfunc; 413: extern rtx floattixf_libfunc; 414: 415: extern rtx floatsitf_libfunc; 416: extern rtx floatditf_libfunc; 417: extern rtx floattitf_libfunc; 418: 1.1 root 419: extern rtx fixsfsi_libfunc; 420: extern rtx fixsfdi_libfunc; 1.1.1.4 root 421: extern rtx fixsfti_libfunc; 422: 1.1 root 423: extern rtx fixdfsi_libfunc; 424: extern rtx fixdfdi_libfunc; 1.1.1.4 root 425: extern rtx fixdfti_libfunc; 426: 427: extern rtx fixxfsi_libfunc; 428: extern rtx fixxfdi_libfunc; 429: extern rtx fixxfti_libfunc; 430: 431: extern rtx fixtfsi_libfunc; 432: extern rtx fixtfdi_libfunc; 433: extern rtx fixtfti_libfunc; 434: 1.1 root 435: extern rtx fixunssfsi_libfunc; 436: extern rtx fixunssfdi_libfunc; 1.1.1.4 root 437: extern rtx fixunssfti_libfunc; 438: 1.1 root 439: extern rtx fixunsdfsi_libfunc; 440: extern rtx fixunsdfdi_libfunc; 1.1.1.4 root 441: extern rtx fixunsdfti_libfunc; 442: 443: extern rtx fixunsxfsi_libfunc; 444: extern rtx fixunsxfdi_libfunc; 445: extern rtx fixunsxfti_libfunc; 446: 447: extern rtx fixunstfsi_libfunc; 448: extern rtx fixunstfdi_libfunc; 449: extern rtx fixunstfti_libfunc; 1.1 root 450: 451: typedef rtx (*rtxfun) (); 452: 453: /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) 454: gives the gen_function to make a branch to test that condition. */ 455: 456: extern rtxfun bcc_gen_fctn[NUM_RTX_CODE]; 457: 458: /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) 459: gives the insn code to make a store-condition insn 460: to test that condition. */ 461: 462: extern enum insn_code setcc_gen_code[NUM_RTX_CODE]; 463: 1.1.1.8 ! root 464: #ifdef HAVE_conditional_move ! 465: /* Indexed by the the machine mode, gives the insn code to make a conditional ! 466: move insn. */ ! 467: ! 468: extern enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; ! 469: #endif ! 470: 1.1.1.5 root 471: /* This array records the insn_code of insns to perform block moves. */ 472: extern enum insn_code movstr_optab[NUM_MACHINE_MODES]; 473: 474: /* Define functions given in optabs.c. */ 475: 1.1 root 476: /* Expand a binary operation given optab and rtx operands. */ 1.1.1.5 root 477: extern rtx expand_binop PROTO((enum machine_mode, optab, rtx, rtx, rtx, 478: int, enum optab_methods)); 1.1 root 479: 480: /* Expand a binary operation with both signed and unsigned forms. */ 1.1.1.5 root 481: extern rtx sign_expand_binop PROTO((enum machine_mode, optab, optab, rtx, 482: rtx, rtx, int, enum optab_methods)); 483: 484: /* Generate code to perform an operation on two operands with two results. */ 485: extern int expand_twoval_binop PROTO((optab, rtx, rtx, rtx, rtx, int)); 1.1 root 486: 487: /* Expand a unary arithmetic operation given optab rtx operand. */ 1.1.1.5 root 488: extern rtx expand_unop PROTO((enum machine_mode, optab, rtx, rtx, int)); 1.1 root 489: 1.1.1.7 root 490: /* Expand the absolute value operation. */ 491: extern rtx expand_abs PROTO((enum machine_mode, rtx, rtx, int, int)); 492: 1.1.1.4 root 493: /* Expand the complex absolute value operation. */ 1.1.1.5 root 494: extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int)); 1.1.1.4 root 495: 1.1.1.5 root 496: /* Generate an instruction with a given INSN_CODE with an output and 497: an input. */ 498: extern void emit_unop_insn PROTO((int, rtx, rtx, enum rtx_code)); 499: 500: /* Emit code to perform a series of operations on a multi-word quantity, one 501: word at a time. */ 502: extern rtx emit_no_conflict_block PROTO((rtx, rtx, rtx, rtx, rtx)); 1.1 root 503: 1.1.1.5 root 504: /* Emit code to make a call to a constant function or a library call. */ 505: extern void emit_libcall_block PROTO((rtx, rtx, rtx, rtx)); 1.1 root 506: 1.1.1.5 root 507: /* Emit one rtl instruction to store zero in specified rtx. */ 508: extern void emit_clr_insn PROTO((rtx)); 1.1 root 509: 1.1.1.5 root 510: /* Emit one rtl insn to store 1 in specified rtx assuming it contains 0. */ 511: extern void emit_0_to_1_insn PROTO((rtx)); 1.1 root 512: 1.1.1.5 root 513: /* Emit one rtl insn to compare two rtx's. */ 514: extern void emit_cmp_insn PROTO((rtx, rtx, enum rtx_code, rtx, 515: enum machine_mode, int, int)); 516: 517: /* Nonzero if a compare of mode MODE can be done straightforwardly 518: (without splitting it into pieces). */ 519: extern int can_compare_p PROTO((enum machine_mode)); 520: 1.1.1.7 root 521: /* Emit a library call comparison between floating point X and Y. 522: COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */ 523: extern void emit_float_lib_cmp PROTO((rtx, rtx, enum rtx_code)); 524: 1.1.1.5 root 525: /* Generate code to indirectly jump to a location given in the rtx LOC. */ 526: extern void emit_indirect_jump PROTO((rtx)); 527: 1.1.1.8 ! root 528: #ifdef HAVE_conditional_move ! 529: /* Emit a conditional move operation. */ ! 530: rtx emit_conditional_move PROTO((rtx, enum rtx_code, rtx, rtx, ! 531: enum machine_mode, rtx, rtx, ! 532: enum machine_mode, int)); ! 533: ! 534: /* Return non-zero if the conditional move is supported. */ ! 535: int can_conditionally_move_p PROTO((enum machine_mode mode)); ! 536: #endif ! 537: 1.1.1.5 root 538: /* Create but don't emit one rtl instruction to add one rtx into another. 539: Modes must match; operands must meet the operation's predicates. 540: Likewise for subtraction and for just copying. 541: These do not call protect_from_queue; caller must do so. */ 542: extern rtx gen_add2_insn PROTO((rtx, rtx)); 543: extern rtx gen_sub2_insn PROTO((rtx, rtx)); 544: extern rtx gen_move_insn PROTO((rtx, rtx)); 545: extern int have_add2_insn PROTO((enum machine_mode)); 546: extern int have_sub2_insn PROTO((enum machine_mode)); 1.1 root 547: 548: /* Return the INSN_CODE to use for an extend operation. */ 1.1.1.5 root 549: extern enum insn_code can_extend_p PROTO((enum machine_mode, 550: enum machine_mode, int)); 551: 552: /* Generate the body of an insn to extend Y (with mode MFROM) 553: into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ 554: extern rtx gen_extend_insn PROTO((rtx, rtx, enum machine_mode, 555: enum machine_mode, int)); 1.1 root 556: 557: /* Initialize the tables that control conversion between fixed and 558: floating values. */ 1.1.1.5 root 559: extern void init_fixtab PROTO((void)); 560: extern void init_floattab PROTO((void)); 561: 562: /* Generate code for a FLOAT_EXPR. */ 563: extern void expand_float PROTO((rtx, rtx, int)); 1.1 root 564: 565: /* Generate code for a FIX_EXPR. */ 1.1.1.5 root 566: extern void expand_fix PROTO((rtx, rtx, int)); 1.1 root 567: 1.1.1.5 root 568: /* Call this once to initialize the contents of the optabs 569: appropriately for the current target machine. */ 570: extern void init_optabs PROTO((void)); 571: 572: /* Functions from expmed.c: */ 1.1 root 573: 1.1.1.5 root 574: /* Arguments MODE, RTX: return an rtx for the negation of that value. 575: May emit insns. */ 576: extern rtx negate_rtx PROTO((enum machine_mode, rtx)); 1.1 root 577: 1.1.1.5 root 578: /* Expand a logical AND operation. */ 579: extern rtx expand_and PROTO((rtx, rtx, rtx)); 1.1 root 580: 1.1.1.5 root 581: /* Emit a store-flag operation. */ 582: extern rtx emit_store_flag PROTO((rtx, enum rtx_code, rtx, rtx, 583: enum machine_mode, int, int)); 1.1 root 584: 1.1.1.5 root 585: /* Functions from loop.c: */ 1.1 root 586: 1.1.1.5 root 587: /* Given a JUMP_INSN, return a description of the test being made. */ 588: extern rtx get_condition PROTO((rtx, rtx *)); 589: 590: /* Functions from expr.c: */ 591: 592: /* This is run once per compilation to set up which modes can be used 593: directly in memory and to initialize the block move optab. */ 594: extern void init_expr_once PROTO((void)); 595: 596: /* This is run at the start of compiling a function. */ 597: extern void init_expr PROTO((void)); 598: 599: /* Use protect_from_queue to convert a QUEUED expression 600: into something that you can put immediately into an instruction. */ 601: extern rtx protect_from_queue PROTO((rtx, int)); 602: 603: /* Perform all the pending incrementations. */ 604: extern void emit_queue PROTO((void)); 1.1 root 605: 606: /* Emit some rtl insns to move data between rtx's, converting machine modes. 607: Both modes must be floating or both fixed. */ 1.1.1.5 root 608: extern void convert_move PROTO((rtx, rtx, int)); 1.1 root 609: 610: /* Convert an rtx to specified machine mode and return the result. */ 1.1.1.5 root 611: extern rtx convert_to_mode PROTO((enum machine_mode, rtx, int)); 612: 1.1.1.6 root 613: /* Convert an rtx to MODE from OLDMODE and return the result. */ 614: extern rtx convert_modes PROTO((enum machine_mode, enum machine_mode, rtx, int)); 615: 1.1.1.5 root 616: /* Emit code to move a block Y to a block X. */ 617: extern void emit_block_move PROTO((rtx, rtx, rtx, int)); 618: 619: /* Copy all or part of a value X into registers starting at REGNO. 620: The number of registers to be filled is NREGS. */ 621: extern void move_block_to_reg PROTO((int, rtx, int, enum machine_mode)); 622: 623: /* Copy all or part of a BLKmode value X out of registers starting at REGNO. 624: The number of registers to be filled is NREGS. */ 1.1.1.6 root 625: extern void move_block_from_reg PROTO((int, rtx, int, int)); 1.1.1.5 root 626: 1.1.1.7 root 627: /* Mark REG as holding a parameter for the next CALL_INSN. */ 628: extern void use_reg PROTO((rtx*, rtx)); 629: /* Mark NREGS consecutive regs, starting at REGNO, as holding parameters 630: for the next CALL_INSN. */ 631: extern void use_regs PROTO((rtx*, int, int)); 1.1.1.5 root 632: 633: /* Write zeros through the storage of OBJECT. 634: If OBJECT has BLKmode, SIZE is its length in bytes. */ 1.1.1.8 ! root 635: extern void clear_storage PROTO((rtx, rtx)); 1.1.1.5 root 636: 637: /* Emit insns to set X from Y. */ 638: extern rtx emit_move_insn PROTO((rtx, rtx)); 639: 640: /* Emit insns to set X from Y, with no frills. */ 641: extern rtx emit_move_insn_1 PROTO ((rtx, rtx)); 642: 643: /* Push a block of length SIZE (perhaps variable) 644: and return an rtx to address the beginning of the block. */ 645: extern rtx push_block PROTO((rtx, int, int)); 646: 1.1.1.8 ! root 647: /* Make an operand to push something on the stack. */ 1.1.1.5 root 648: extern rtx gen_push_operand PROTO((void)); 1.1 root 649: 1.1.1.5 root 650: #ifdef TREE_CODE 651: /* Generate code to push something onto the stack, given its mode and type. */ 652: extern void emit_push_insn PROTO((rtx, enum machine_mode, tree, rtx, int, 653: int, rtx, int, rtx, rtx)); 654: 1.1.1.7 root 655: /* Emit library call. */ 656: extern void emit_library_call PVPROTO((rtx orgfun, int no_queue, 657: enum machine_mode outmode, int nargs, ...)); 658: extern rtx emit_library_call_value PVPROTO((rtx orgfun, rtx value, int no_queue, 659: enum machine_mode outmode, int nargs, ...)); 1.1.1.5 root 660: 661: /* Expand an assignment that stores the value of FROM into TO. */ 662: extern rtx expand_assignment PROTO((tree, tree, int, int)); 663: 664: /* Generate code for computing expression EXP, 665: and storing the value into TARGET. 666: If SUGGEST_REG is nonzero, copy the value through a register 667: and return that register, if that is possible. */ 668: extern rtx store_expr PROTO((tree, rtx, int)); 669: #endif 1.1 root 670: 671: /* Given an rtx that may include add and multiply operations, 672: generate them as insns and return a pseudo-reg containing the value. 673: Useful after calling expand_expr with 1 as sum_ok. */ 1.1.1.5 root 674: extern rtx force_operand PROTO((rtx, rtx)); 675: 676: #ifdef TREE_CODE 677: /* Generate code for computing expression EXP. 678: An rtx for the computed value is returned. The value is never null. 679: In the case of a void EXP, const0_rtx is returned. */ 680: extern rtx expand_expr PROTO((tree, rtx, enum machine_mode, 681: enum expand_modifier)); 682: #endif 683: 684: /* At the start of a function, record that we have no previously-pushed 685: arguments waiting to be popped. */ 686: extern void init_pending_stack_adjust PROTO((void)); 687: 688: /* When exiting from function, if safe, clear out any pending stack adjust 689: so the adjustment won't get done. */ 690: extern void clear_pending_stack_adjust PROTO((void)); 1.1 root 691: 1.1.1.5 root 692: /* Pop any previously-pushed arguments that have not been popped yet. */ 693: extern void do_pending_stack_adjust PROTO((void)); 694: 695: #ifdef TREE_CODE 696: /* Expand all cleanups up to OLD_CLEANUPS. */ 697: extern void expand_cleanups_to PROTO((tree)); 698: 699: /* Generate code to evaluate EXP and jump to LABEL if the value is zero. */ 700: extern void jumpifnot PROTO((tree, rtx)); 701: 702: /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */ 703: extern void jumpif PROTO((tree, rtx)); 704: 705: /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if 706: the result is zero, or IF_TRUE_LABEL if the result is one. */ 707: extern void do_jump PROTO((tree, rtx, rtx)); 708: #endif 709: 710: /* Generate rtl to compare two rtx's, will call emit_cmp_insn. */ 711: extern rtx compare_from_rtx PROTO((rtx, rtx, enum rtx_code, int, 712: enum machine_mode, rtx, int)); 713: 714: /* Generate a tablejump instruction (used for switch statements). */ 715: extern void do_tablejump PROTO((rtx, enum machine_mode, rtx, rtx, rtx)); 716: 717: #ifdef TREE_CODE 718: /* rtl.h and tree.h were included. */ 1.1 root 719: /* Return an rtx for the size in bytes of the value of an expr. */ 1.1.1.5 root 720: extern rtx expr_size PROTO((tree)); 1.1 root 721: 1.1.1.5 root 722: extern rtx lookup_static_chain PROTO((tree)); 723: 724: /* Convert a stack slot address ADDR valid in function FNDECL 725: into an address valid in this function (using a static chain). */ 726: extern rtx fix_lexical_addr PROTO((rtx, tree)); 727: 728: /* Return the address of the trampoline for entering nested fn FUNCTION. */ 729: extern rtx trampoline_address PROTO((tree)); 730: 731: /* Return an rtx that refers to the value returned by a function 732: in its original home. This becomes invalid if any more code is emitted. */ 733: extern rtx hard_function_value PROTO((tree, tree)); 734: 1.1.1.7 root 735: extern rtx prepare_call_address PROTO((rtx, tree, rtx *, int)); 1.1.1.5 root 736: 737: extern rtx expand_call PROTO((tree, rtx, int)); 738: 739: extern rtx expand_shift PROTO((enum tree_code, enum machine_mode, rtx, tree, rtx, int)); 740: extern rtx expand_divmod PROTO((int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int)); 741: extern void locate_and_pad_parm PROTO((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *)); 742: extern rtx expand_inline_function PROTO((tree, tree, rtx, int, tree, rtx)); 743: /* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */ 744: extern rtx label_rtx PROTO((tree)); 745: #endif 746: 747: /* Indicate how an input argument register was promoted. */ 748: extern rtx promoted_input_arg PROTO((int, enum machine_mode *, int *)); 1.1 root 749: 750: /* Return an rtx like arg but sans any constant terms. 751: Returns the original rtx if it has no constant terms. 752: The constant terms are added and stored via a second arg. */ 1.1.1.5 root 753: extern rtx eliminate_constant_term PROTO((rtx, rtx *)); 1.1 root 754: 755: /* Convert arg to a valid memory address for specified machine mode, 756: by emitting insns to perform arithmetic if nec. */ 1.1.1.5 root 757: extern rtx memory_address PROTO((enum machine_mode, rtx)); 1.1 root 758: 759: /* Like `memory_address' but pretent `flag_force_addr' is 0. */ 1.1.1.5 root 760: extern rtx memory_address_noforce PROTO((enum machine_mode, rtx)); 1.1 root 761: 762: /* Return a memory reference like MEMREF, but with its mode changed 763: to MODE and its address changed to ADDR. 764: (VOIDmode means don't change the mode. 765: NULL for ADDR means don't change the address.) */ 1.1.1.5 root 766: extern rtx change_address PROTO((rtx, enum machine_mode, rtx)); 1.1 root 767: 768: /* Return a memory reference like MEMREF, but which is known to have a 769: valid address. */ 770: 1.1.1.5 root 771: extern rtx validize_mem PROTO((rtx)); 1.1 root 772: 773: /* Assemble the static constant template for function entry trampolines. */ 1.1.1.5 root 774: extern rtx assemble_trampoline_template PROTO((void)); 1.1 root 775: 776: /* Return 1 if two rtx's are equivalent in structure and elements. */ 1.1.1.5 root 777: extern int rtx_equal_p PROTO((rtx, rtx)); 1.1 root 778: 779: /* Given rtx, return new rtx whose address won't be affected by 780: any side effects. It has been copied to a new temporary reg. */ 1.1.1.5 root 781: extern rtx stabilize PROTO((rtx)); 1.1 root 782: 783: /* Given an rtx, copy all regs it refers to into new temps 784: and return a modified copy that refers to the new temps. */ 1.1.1.5 root 785: extern rtx copy_all_regs PROTO((rtx)); 1.1 root 786: 787: /* Copy given rtx to a new temp reg and return that. */ 1.1.1.5 root 788: extern rtx copy_to_reg PROTO((rtx)); 1.1 root 789: 790: /* Like copy_to_reg but always make the reg Pmode. */ 1.1.1.5 root 791: extern rtx copy_addr_to_reg PROTO((rtx)); 1.1 root 792: 793: /* Like copy_to_reg but always make the reg the specified mode MODE. */ 1.1.1.5 root 794: extern rtx copy_to_mode_reg PROTO((enum machine_mode, rtx)); 1.1 root 795: 796: /* Copy given rtx to given temp reg and return that. */ 1.1.1.5 root 797: extern rtx copy_to_suggested_reg PROTO((rtx, rtx, enum machine_mode)); 1.1 root 798: 799: /* Copy a value to a register if it isn't already a register. 800: Args are mode (in case value is a constant) and the value. */ 1.1.1.5 root 801: extern rtx force_reg PROTO((enum machine_mode, rtx)); 1.1 root 802: 803: /* Return given rtx, copied into a new temp reg if it was in memory. */ 1.1.1.5 root 804: extern rtx force_not_mem PROTO((rtx)); 1.1 root 805: 1.1.1.7 root 806: #ifdef TREE_CODE 807: /* Return mode and signedness to use when object is promoted. */ 808: extern enum machine_mode promote_mode PROTO((tree, enum machine_mode, 809: int *, int)); 810: #endif 811: 1.1 root 812: /* Remove some bytes from the stack. An rtx says how many. */ 1.1.1.5 root 813: extern void adjust_stack PROTO((rtx)); 1.1 root 814: 815: /* Add some bytes to the stack. An rtx says how many. */ 1.1.1.5 root 816: extern void anti_adjust_stack PROTO((rtx)); 1.1 root 817: 1.1.1.3 root 818: /* This enum is used for the following two functions. */ 819: enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL}; 820: 821: /* Save the stack pointer at the specified level. */ 1.1.1.5 root 822: extern void emit_stack_save PROTO((enum save_level, rtx *, rtx)); 1.1.1.3 root 823: 824: /* Restore the stack pointer from a save area of the specified level. */ 1.1.1.5 root 825: extern void emit_stack_restore PROTO((enum save_level, rtx, rtx)); 1.1.1.3 root 826: 1.1 root 827: /* Allocate some space on the stack dynamically and return its address. An rtx 828: says how many bytes. */ 1.1.1.5 root 829: extern rtx allocate_dynamic_stack_space PROTO((rtx, rtx, int)); 1.1 root 830: 831: /* Emit code to copy function value to a new temp reg and return that reg. */ 832: extern rtx function_value (); 833: 834: /* Return an rtx that refers to the value returned by a library call 835: in its original home. This becomes invalid if any more code is emitted. */ 1.1.1.5 root 836: extern rtx hard_libcall_value PROTO((enum machine_mode)); 1.1 root 837: 838: /* Given an rtx, return an rtx for a value rounded up to a multiple 839: of STACK_BOUNDARY / BITS_PER_UNIT. */ 1.1.1.5 root 840: extern rtx round_push PROTO((rtx)); 1.1 root 841: 1.1.1.5 root 842: extern void emit_block_move PROTO((rtx, rtx, rtx, int)); 1.1 root 843: 1.1.1.5 root 844: extern rtx store_bit_field PROTO((rtx, int, int, enum machine_mode, rtx, int, int)); 845: extern rtx extract_bit_field PROTO((rtx, int, int, int, rtx, enum machine_mode, enum machine_mode, int, int)); 846: extern rtx expand_mult PROTO((enum machine_mode, rtx, rtx, rtx, int)); 847: extern rtx expand_mult_add PROTO((rtx, rtx, rtx, rtx,enum machine_mode, int)); 1.1 root 848: 1.1.1.5 root 849: extern rtx assemble_static_space PROTO((int)); 1.1 root 850: 851: /* Hook called by expand_expr for language-specific tree codes. 852: It is up to the language front end to install a hook 853: if it has any such codes that expand_expr needs to know about. */ 854: extern rtx (*lang_expand_expr) ();
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.