|
|
1.1 ! root 1: /* Definitions for code generation pass of GNU compiler. ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU CC General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU CC, but only under the conditions described in the ! 15: GNU CC General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU CC so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: /* Macros to access the slots of a QUEUED rtx. ! 23: Here rather than in rtl.h because only the expansion pass ! 24: should ever encounter a QUEUED. */ ! 25: ! 26: /* The variable for which an increment is queued. */ ! 27: #define QUEUED_VAR(P) XEXP (P, 0) ! 28: /* If the increment has been emitted, this is the insn ! 29: that does the increment. It is zero before the increment is emitted. */ ! 30: #define QUEUED_INSN(P) XEXP (P, 1) ! 31: /* If a pre-increment copy has been generated, this is the copy ! 32: (it is a temporary reg). Zero if no copy made yet. */ ! 33: #define QUEUED_COPY(P) XEXP (P, 2) ! 34: /* This is the body to use for the insn to do the increment. ! 35: It is used to emit the increment. */ ! 36: #define QUEUED_BODY(P) XEXP (P, 3) ! 37: /* Next QUEUED in the queue. */ ! 38: #define QUEUED_NEXT(P) XEXP (P, 4) ! 39: ! 40: /* This is the 4th arg to `expand_expr'. ! 41: EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx. ! 42: EXPND_CONST_ADDRESS means it is ok to return a MEM whose address ! 43: is a constant that is not a legitimate address. */ ! 44: enum expand_modifier {EXPAND_NORMAL, EXPAND_SUM, EXPAND_CONST_ADDRESS}; ! 45: ! 46: /* If this is nonzero, we do not bother generating VOLATILE ! 47: around volatile memory references, and we are willing to ! 48: output indirect addresses. If cse is to follow, we reject ! 49: indirect addresses so a useful potential cse is generated; ! 50: if it is used only once, instruction combination will produce ! 51: the same indirect address eventually. */ ! 52: extern int cse_not_expected; ! 53: ! 54: #ifdef TREE_CODE /* Don't lose if tree.h not included. */ ! 55: /* Structure to record the size of a sequence of arguments ! 56: as the sum of a tree-expression and a constant. */ ! 57: ! 58: struct args_size ! 59: { ! 60: int constant; ! 61: tree var; ! 62: }; ! 63: #endif ! 64: ! 65: /* Add the value of the tree INC to the `struct args_size' TO. */ ! 66: ! 67: #define ADD_PARM_SIZE(TO, INC) \ ! 68: { tree inc = (INC); \ ! 69: if (TREE_CODE (inc) == INTEGER_CST) \ ! 70: (TO).constant += TREE_INT_CST_LOW (inc); \ ! 71: else if ((TO).var == 0) \ ! 72: (TO).var = inc; \ ! 73: else \ ! 74: (TO).var = genop (PLUS_EXPR, (TO).var, inc); } ! 75: ! 76: /* Convert the implicit sum in a `struct args_size' into an rtx. */ ! 77: #define ARGS_SIZE_RTX(SIZE) \ ! 78: ((SIZE).var == 0 ? gen_rtx (CONST_INT, VOIDmode, (SIZE).constant) \ ! 79: : plus_constant (expand_expr ((SIZE).var, 0, VOIDmode, 0), \ ! 80: (SIZE).constant)) ! 81: ! 82: /* Optabs are tables saying how to generate insn bodies ! 83: for various machine modes and numbers of operands. ! 84: Each optab applies to one operation. ! 85: For example, add_optab applies to addition. ! 86: ! 87: The insn_code slot is the enum insn_code that says how to ! 88: generate an insn for this operation on a particular machine mode. ! 89: It is CODE_FOR_nothing if there is no such insn on the target machine. ! 90: ! 91: The `lib_call' slot is the name of the library function that ! 92: can be used to perform the operation. ! 93: ! 94: A few optabs, such as move_optab and cmp_optab, are used ! 95: by special code. */ ! 96: ! 97: /* Everything that uses expr.h needs to define enum insn_code ! 98: but we don't list it in the Makefile dependencies just for that. */ ! 99: #include "insn-codes.h" ! 100: ! 101: typedef struct optab ! 102: { ! 103: enum rtx_code code; ! 104: struct { ! 105: enum insn_code insn_code; ! 106: char *lib_call; ! 107: } handlers [NUM_MACHINE_MODES]; ! 108: } * optab; ! 109: ! 110: /* Given an enum insn_code, access the function to construct ! 111: the body of that kind of insn. */ ! 112: #define GEN_FCN(CODE) (*insn_gen_function[(int) (CODE)]) ! 113: extern rtx (*insn_gen_function[]) (); ! 114: ! 115: extern optab add_optab; ! 116: extern optab sub_optab; ! 117: extern optab smul_optab; /* Signed multiply */ ! 118: extern optab umul_optab; /* Unsigned multiply */ ! 119: extern optab smul_widen_optab; /* Signed multiply with result ! 120: one machine mode wider than args */ ! 121: extern optab umul_widen_optab; ! 122: extern optab sdiv_optab; /* Signed divide */ ! 123: extern optab sdivmod_optab; /* Signed divide-and-remainder in one */ ! 124: extern optab udiv_optab; ! 125: extern optab udivmod_optab; ! 126: extern optab smod_optab; /* Signed remainder */ ! 127: extern optab umod_optab; ! 128: extern optab flodiv_optab; /* Optab for floating divide. */ ! 129: extern optab ftrunc_optab; /* Convert float to integer in float fmt */ ! 130: extern optab and_optab; /* Logical and */ ! 131: extern optab andcb_optab; /* Logical and with complement of 2nd arg */ ! 132: extern optab ior_optab; /* Logical or */ ! 133: extern optab xor_optab; /* Logical xor */ ! 134: extern optab ashl_optab; /* Arithmetic shift left */ ! 135: extern optab ashr_optab; /* Arithmetic shift right */ ! 136: extern optab lshl_optab; /* Logical shift left */ ! 137: extern optab lshr_optab; /* Logical shift right */ ! 138: extern optab rotl_optab; /* Rotate left */ ! 139: extern optab rotr_optab; /* Rotate right */ ! 140: ! 141: extern optab mov_optab; /* Move instruction. */ ! 142: extern optab movstrict_optab; /* Move, preserving high part of register. */ ! 143: ! 144: extern optab cmp_optab; /* Compare insn; two operands. */ ! 145: extern optab tst_optab; /* tst insn; compare one operand against 0 */ ! 146: ! 147: /* Unary operations */ ! 148: extern optab neg_optab; /* Negation */ ! 149: extern optab abs_optab; /* Abs value */ ! 150: extern optab one_cmpl_optab; /* Bitwise not */ ! 151: extern optab ffs_optab; /* Find first bit set */ ! 152: ! 153: /* Passed to expand_binop and expand_unop to say which options to try to use ! 154: if the requested operation can't be open-coded on the requisite mode. ! 155: Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using a library call. ! 156: Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try using a wider mode. */ ! 157: ! 158: enum optab_methods ! 159: { ! 160: OPTAB_DIRECT, ! 161: OPTAB_LIB, ! 162: OPTAB_WIDEN, ! 163: OPTAB_LIB_WIDEN, ! 164: }; ! 165: ! 166: typedef rtx (*rtxfun) (); ! 167: ! 168: /* Expand a binary operation given optab and rtx operands. */ ! 169: rtx expand_binop (); ! 170: ! 171: /* Expand a unary arithmetic operation given optab rtx operand. */ ! 172: rtx expand_unop (); ! 173: ! 174: /* Initialize the tables that control conversion between fixed and ! 175: floating values. */ ! 176: void init_fixtab (); ! 177: void init_floattab (); ! 178: ! 179: /* Say whether a certain floating machine mode can be converted to a certain ! 180: fixed machine mode. */ ! 181: rtxfun can_fix_p (); ! 182: /* Similar for converting a fixed machine mode to a floating one. */ ! 183: rtxfun can_float_p (); ! 184: ! 185: /* Generate code for a FIX_EXPR. */ ! 186: void expand_fix (); ! 187: ! 188: /* Generate code for a FLOAT_EXPR. */ ! 189: void expand_float (); ! 190: ! 191: /* Create but don't emit one rtl instruction to add one rtx into another. ! 192: Modes must match. ! 193: Likewise for subtraction and for just copying. ! 194: These do not call protect_from_queue; caller must do so. */ ! 195: rtx gen_add2_insn (); ! 196: rtx gen_sub2_insn (); ! 197: rtx gen_move_insn (); ! 198: ! 199: /* Emit one rtl instruction to store zero in specified rtx. */ ! 200: void emit_clr_insn (); ! 201: ! 202: /* Emit one rtl insn to store 1 in specified rtx assuming it contains 0. */ ! 203: void emit_0_to_1_insn (); ! 204: ! 205: /* Emit one rtl insn to compare two rtx's. */ ! 206: void emit_cmp_insn (); ! 207: ! 208: /* Emit some rtl insns to move data between rtx's, converting machine modes. ! 209: Both modes must be floating or both fixed. */ ! 210: void convert_move (); ! 211: ! 212: /* Convert an rtx to specified machine mode and return the result. */ ! 213: rtx convert_to_mode (); ! 214: ! 215: /* Emit code to push some arguments and call a library routine, ! 216: storing the value in a specified place. Calling sequence is ! 217: complicated. */ ! 218: void emit_library_call (); ! 219: ! 220: /* Given an rtx that may include add and multiply operations, ! 221: generate them as insns and return a pseudo-reg containing the value. ! 222: Useful after calling expand_expr with 1 as sum_ok. */ ! 223: rtx force_operand (); ! 224: ! 225: /* Return an rtx for the size in bytes of the value of an expr. */ ! 226: rtx expr_size (); ! 227: ! 228: /* Return an rtx for the sum of an rtx and an integer. */ ! 229: rtx plus_constant (); ! 230: ! 231: rtx lookup_static_chain (); ! 232: ! 233: /* Return an rtx like arg but sans any constant terms. ! 234: Returns the original rtx if it has no constant terms. ! 235: The constant terms are added and stored via a second arg. */ ! 236: rtx eliminate_constant_term (); ! 237: ! 238: /* Convert arg to a valid memory address for specified machine mode, ! 239: by emitting insns to perform arithmetic if nec. */ ! 240: rtx memory_address (); ! 241: ! 242: /* Return a memory reference like MEMREF, but with its mode changed ! 243: to MODE and its address changed to ADDR. ! 244: (VOIDmode means don't change the mode. ! 245: NULL for ADDR means don't change the address.) */ ! 246: rtx change_address (); ! 247: ! 248: /* Return 1 if two rtx's are equivalent in structure and elements. */ ! 249: int rtx_equal_p (); ! 250: ! 251: /* Given rtx, return new rtx whose address won't be affected by ! 252: any side effects. It has been copied to a new temporary reg. */ ! 253: rtx stabilize (); ! 254: ! 255: /* Given an rtx, copy all regs it refers to into new temps ! 256: and return a modified copy that refers to the new temps. */ ! 257: rtx copy_all_regs (); ! 258: ! 259: /* Copy given rtx to a new temp reg and return that. */ ! 260: rtx copy_to_reg (); ! 261: ! 262: /* Like copy_to_reg but always make the reg Pmode. */ ! 263: rtx copy_addr_to_reg (); ! 264: ! 265: /* Like copy_to_reg but always make the reg the specified mode MODE. */ ! 266: rtx copy_to_mode_reg (); ! 267: ! 268: /* Copy given rtx to given temp reg and return that. */ ! 269: rtx copy_to_suggested_reg (); ! 270: ! 271: /* Copy a value to a register if it isn't already a register. ! 272: Args are mode (in case value is a constant) and the value. */ ! 273: rtx force_reg (); ! 274: ! 275: /* Return given rtx, copied into a new temp reg if it was in memory. */ ! 276: rtx force_not_mem (); ! 277: ! 278: /* Remove some bytes from the stack. An rtx says how many. */ ! 279: void adjust_stack (); ! 280: ! 281: /* Add some bytes to the stack. An rtx says how many. */ ! 282: void anti_adjust_stack (); ! 283: ! 284: /* Emit code to copy function value to a new temp reg and return that reg. */ ! 285: rtx function_value (); ! 286: ! 287: /* Return an rtx that refers to the value returned by a function ! 288: in its original home. This becomes invalid if any more code is emitted. */ ! 289: rtx hard_function_value (); ! 290: ! 291: /* Return an rtx that refers to the value returned by a library call ! 292: in its original home. This becomes invalid if any more code is emitted. */ ! 293: rtx hard_libcall_value (); ! 294: ! 295: /* Emit code to copy function value to a specified place. */ ! 296: void copy_function_value (); ! 297: ! 298: /* Given an rtx, return an rtx for a value rounded up to a multiple ! 299: of STACK_BOUNDARY / BITS_PER_UNIT. */ ! 300: rtx round_push (); ! 301: ! 302: rtx store_bit_field (); ! 303: rtx extract_bit_field (); ! 304: rtx expand_shift (); ! 305: rtx expand_bit_and (); ! 306: rtx expand_mult (); ! 307: rtx expand_divmod (); ! 308: rtx get_structure_value_addr (); ! 309: rtx expand_stmt_expr (); ! 310: ! 311: void jumpifnot (); ! 312: void jumpif (); ! 313: void do_jump ();
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.