|
|
1.1 ! root 1: /* Subroutines for insn-output.c for MIPS ! 2: Contributed by A. Lichnewsky, [email protected]. ! 3: Copyright (C) 1989 Free Software Foundation, Inc. ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 1, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: ! 22: #include <stdio.h> ! 23: extern void my_print_rtx (); ! 24: extern void abort_with_insn (); ! 25: ! 26: ! 27: /* Global variables for machine-dependent things. */ ! 28: ! 29: char *reg_numchar[] = REGISTER_NUMCHAR; ! 30: ! 31: ! 32: /* Return truth value of whether OP can be used as an operands ! 33: where a 16 bit integer is needed */ ! 34: ! 35: int ! 36: arith_operand (op, mode) ! 37: rtx op; ! 38: enum machine_mode mode; ! 39: { ! 40: return (register_operand (op, mode) ! 41: || (GET_CODE (op) == CONST_INT && SMALL_INT (op))); ! 42: } ! 43: ! 44: /* Return truth value of whether OP can be used as an operand in a two ! 45: address arithmetic insn (such as set 123456,%o4) of mode MODE. */ ! 46: ! 47: int ! 48: arith32_operand (op, mode) ! 49: rtx op; ! 50: enum machine_mode mode; ! 51: { ! 52: return (register_operand (op, mode) || GET_CODE (op) == CONST_INT); ! 53: } ! 54: ! 55: /* Return truth value of whether OP is a integer which fits in 16 bits */ ! 56: ! 57: int ! 58: small_int (op, mode) ! 59: rtx op; ! 60: enum machine_mode mode; ! 61: { ! 62: return (GET_CODE (op) == CONST_INT && SMALL_INT (op)); ! 63: } ! 64: ! 65: ! 66: #if 0 ! 67: /* Used to allow constant expression known ! 68: ** only at assembly time ! 69: */ ! 70: int ! 71: legitimize_constant_expr(expr) ! 72: rtx expr; ! 73: { ! 74: if (GET_CODE (expr) == PLUS ! 75: || ! 76: GET_CODE (expr) == MINUS) ! 77: return (BASIC_CONSTANT_P (XEXP (expr, 0)) ! 78: && BASIC_CONSTANT_P (XEXP (expr, 1))); ! 79: return 0; ! 80: } ! 81: #endif ! 82: ! 83: char * ! 84: output_load_immediate (operands) ! 85: rtx *operands; ! 86: { ! 87: rtx xops[3]; ! 88: xops[0] = operands[0]; ! 89: xops[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1])); ! 90: ! 91: if ((INTVAL (operands[1]) >> 16) ! 92: && (INTVAL (operands[1]) & 0xffff)) ! 93: { ! 94: if (!((-INTVAL (operands[1])) >> 16)) ! 95: { ! 96: xops[1] = gen_rtx (CONST_INT, VOIDmode, ! 97: (INTVAL (operands[1])) & 0xffff); ! 98: output_asm_insn ("addi%:\t%0,$0,%x1\t#movsi low part of %2", ! 99: xops); ! 100: } ! 101: else ! 102: { ! 103: xops[1] = gen_rtx (CONST_INT, VOIDmode, ! 104: (INTVAL (operands[1]))>>16); ! 105: output_asm_insn ("lui\t%0,%x1\t#movsi high part of %2", xops); ! 106: xops[1] = gen_rtx (CONST_INT, VOIDmode, ! 107: (INTVAL (operands[1])) & 0xffff); ! 108: output_asm_insn ("ori\t%0,%x1\t#movsi low part of %2", xops); ! 109: } ! 110: } ! 111: else if (INTVAL (operands[1]) >> 16) ! 112: { ! 113: xops[1] = gen_rtx (CONST_INT, VOIDmode, ! 114: (INTVAL (operands[1]))>>16); ! 115: output_asm_insn ("lui\t%0,%x1\t#movsi high part of %2", xops); ! 116: xops[1] = gen_rtx (CONST_INT, VOIDmode, ! 117: (INTVAL (operands[1])) & 0xffff); ! 118: } ! 119: else ! 120: { ! 121: xops[1] = gen_rtx (CONST_INT, VOIDmode, ! 122: (INTVAL (operands[1])) & 0xffff); ! 123: output_asm_insn ("ori\t%0,$0,%x1\t#movsi low part of %2", ! 124: xops); ! 125: } ! 126: return ""; ! 127: } ! 128: ! 129: /* Used to obtain address of subregs */ ! 130: /* when in memory. This takes mode and */ ! 131: /* subreg number into account */ ! 132: ! 133: rtx ! 134: addr_compensate (addr, submode, origmode, subnum) ! 135: rtx addr; ! 136: enum machine_mode submode; ! 137: enum machine_mode origmode; ! 138: int subnum; ! 139: { ! 140: extern rtx change_address (); ! 141: extern rtx plus_constant (); ! 142: ! 143: if (submode == QImode && origmode == SImode) ! 144: { ! 145: #ifdef BYTES_BIG_ENDIAN ! 146: return change_address (addr, QImode, ! 147: plus_constant (XEXP (addr, 0), 3 - subnum)); ! 148: #else ! 149: return change_address (addr, QImode, ! 150: plus_constant (XEXP (addr, 0), subnum)); ! 151: #endif ! 152: } ! 153: else if (submode == HImode && origmode == SImode) ! 154: { ! 155: #ifdef BYTES_BIG_ENDIAN ! 156: return change_address (addr, HImode, ! 157: plus_constant (XEXP (addr, 0), 2 - 2*subnum)); ! 158: #else ! 159: return change_address (addr, HImode, ! 160: plus_constant (XEXP (addr, 0), subnum)); ! 161: #endif ! 162: } ! 163: else ! 164: abort_with_insn (addr, "addr_compensate does not support mode"); ! 165: } ! 166: ! 167: ! 168: ! 169: ! 170: /* VARARGS */ ! 171: int function_suspect; ! 172: int varargs_suspect = 0; ! 173: int this_varargs_suspect; ! 174: ! 175: /* PARAMETER LIST CONSTRUCTION */ ! 176: ! 177: ! 178: static struct ! 179: { ! 180: enum arg_state nxs_if_f, nxs_if_g; ! 181: short reg_if_f, reg_if_g; ! 182: } ! 183: arg_state_table[(int) (ARG_STA_GGGG + 1)] = ARG_STA_AUTOMA; ! 184: ! 185: ! 186: ! 187: /* For use in Frame/ Stack pointer management*/ ! 188: char * current_function_name; ! 189: int current_function_total_framesize; ! 190: ! 191: ! 192: enum arg_state ! 193: function_arg_advance (cum, mode, type) ! 194: CUMULATIVE_ARGS *cum; ! 195: enum machine_mode mode; ! 196: int type; ! 197: { ! 198: cum->arg_rec_state ! 199: = (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS) ! 200: ? arg_state_table[(int)((cum->arg_rec_state))].nxs_if_f ! 201: : arg_state_table[(int)((cum->arg_rec_state))].nxs_if_g); ! 202: ! 203: (cum->arg_num)++; ! 204: } ! 205: ! 206: rtx ! 207: function_arg (cum, mode, type, named) ! 208: CUMULATIVE_ARGS *cum; ! 209: enum machine_mode mode; ! 210: int type; ! 211: int named; ! 212: { ! 213: int regnum; ! 214: ! 215: regnum ! 216: = (FP_REGS == PREFERRED_RELOAD_CLASS_FM (mode, GR_REGS) ! 217: ? arg_state_table[(int)((cum->arg_rec_state))].reg_if_f ! 218: : arg_state_table[(int)((cum->arg_rec_state))].reg_if_g); ! 219: ! 220: if (mode == BLKmode) ! 221: return 0; ! 222: else ! 223: return (regnum >= 0 ? gen_rtx (REG, mode, regnum) ! 224: : regnum == -2 ? gen_rtx (REG, DFmode, 6) ! 225: : 0); ! 226: } ! 227: ! 228: ! 229: ! 230: static rtx branch_cmp_op[2]; ! 231: static enum machine_mode branch_cmp_mode; ! 232: ! 233: compare_collect (mode, op0, op1) ! 234: enum machine_mode mode; ! 235: rtx op0; ! 236: rtx op1; ! 237: { ! 238: if (TARGET_DEBUGD_MODE) ! 239: { ! 240: fprintf (stderr, "compare_collect mode = %d, operands::", mode); ! 241: my_print_rtx (op0); ! 242: my_print_rtx (op1); ! 243: } ! 244: branch_cmp_op[0] = op0; ! 245: branch_cmp_op[1] = op1; ! 246: branch_cmp_mode = mode; ! 247: } ! 248: ! 249: ! 250: compare_restore (operands, mode, insn) ! 251: rtx *operands; ! 252: enum machine_mode *mode; ! 253: rtx insn; ! 254: { ! 255: rtx previous; ! 256: rtx prev_par; ! 257: if (TARGET_DEBUGD_MODE) ! 258: { ! 259: fprintf (stderr, "compare_restore returning mode = %d, operands:%X,%X:", ! 260: branch_cmp_mode, branch_cmp_op[0], branch_cmp_op[1]); ! 261: my_print_rtx (branch_cmp_op[0]); ! 262: my_print_rtx (branch_cmp_op[1]); ! 263: } ! 264: ! 265: if ((! branch_cmp_op[0]) && (! branch_cmp_op[1])) ! 266: { ! 267: /* Signal that multiple branches following */ ! 268: /* a comparison have been found */ ! 269: if (TARGET_DEBUGD_MODE) ! 270: { ! 271: fprintf (stderr, "Not at ease in compare_restore\n"); ! 272: my_print_rtx (insn); ! 273: my_print_rtx (PREV_INSN (insn)); ! 274: } ! 275: /* Find the previous comparison */ ! 276: while ((GET_CODE (PREV_INSN (insn))) == JUMP_INSN) ! 277: { ! 278: insn = PREV_INSN (insn); ! 279: if (TARGET_DEBUGD_MODE) ! 280: my_print_rtx (PREV_INSN (insn)); ! 281: } ! 282: ! 283: previous = PATTERN (PREV_INSN (insn)); ! 284: ! 285: if ((GET_CODE (previous)) == PARALLEL) ! 286: { ! 287: /* Signal that we have a very strange */ ! 288: /* RTL construct,... usually generated */ ! 289: /* by the optimizer, that seems to */ ! 290: /* contradict the documentation */ ! 291: ! 292: /* However, this construct holds the */ ! 293: /* correct information in a very reliable */ ! 294: /* way */ ! 295: ! 296: branch_cmp_op[0] = XVECEXP (previous, 0, 0); ! 297: branch_cmp_op[1] = XVECEXP (previous, 0, 1); ! 298: /* warning ("Check branch optimization with -mdebugd"); ! 299: */ ! 300: } ! 301: else ! 302: if (((GET_CODE (previous)) == SET) ! 303: && ! 304: ((GET_CODE (XEXP (previous, 0))) == CC0) ! 305: && ! 306: ((GET_CODE (XEXP (previous, 1))) == COMPARE)) ! 307: { /* Here we find the comparison info */ ! 308: /* in a more classical format */ ! 309: ! 310: previous = XEXP (previous, 1); ! 311: branch_cmp_op[0] = XEXP (previous, 0); ! 312: branch_cmp_op[1] = XEXP (previous, 1); ! 313: } ! 314: else ! 315: { /* Be prepared for other things popping out */ ! 316: abort (); ! 317: } ! 318: } ! 319: ! 320: ! 321: ! 322: if (! branch_cmp_op[0]) ! 323: operands[0] = gen_rtx (REG, VOIDmode, 0); ! 324: else ! 325: operands[0] = branch_cmp_op[0]; ! 326: if (! branch_cmp_op[1]) ! 327: operands[1] = gen_rtx (REG, VOIDmode, 0); ! 328: else ! 329: operands[1] = branch_cmp_op[1]; ! 330: *mode = branch_cmp_mode; ! 331: ! 332: branch_cmp_op[0] = NULL; ! 333: branch_cmp_op[1] = NULL; ! 334: ! 335: } ! 336: ! 337: #if 0 ! 338: /* See flags.h and toplev.c */ ! 339: extern int optimize; ! 340: extern int flag_combine_regs; ! 341: extern int flag_strength_reduce; ! 342: extern int flag_no_peephole; ! 343: extern int flag_inline_functions; ! 344: extern int flag_omit_frame_pointer; ! 345: extern char *main_input_filename; ! 346: extern char *asm_file_name; ! 347: /* See c-tree.h and c-decl.c */ ! 348: extern int flag_signed_char; ! 349: ! 350: #include <time.h> ! 351: #include <sys/types.h> ! 352: #include <sys/timeb.h> ! 353: ! 354: void ! 355: print_options (out) ! 356: FILE *out; ! 357: { ! 358: char *a_time; ! 359: long c_time; ! 360: ! 361: fprintf (out, " #OPTIONS:\t%s%s%s%s%s%s%s\n", ! 362: (TARGET_NOFIXED_OVFL ? " -dnofixed-ovfl":" -dfixed-ovfl"), ! 363: (optimize ? " optimize" : ""), ! 364: (flag_combine_regs ? " -fcombine-regs" : " !combine-regs"), ! 365: (flag_strength_reduce ? "" : " !strength_reduce"), ! 366: (flag_omit_frame_pointer ?"" :" !omit_frame_pointer"), ! 367: (flag_no_peephole ? "" : " peephole"), ! 368: (flag_inline_functions ?" inline-functions":"")); ! 369: fprintf (out, " #OPTIONS:\t%s%s\n", ! 370: (flag_signed_char ? " signed-char" : " !signed-char"), ! 371: (TARGET_GP_OPT ? " gpOPT" : " !gpOPT")); ! 372: fprintf (out, " #Source:\t%s\n", main_input_filename); ! 373: fprintf (out, " #Destination:\t%s\n", asm_file_name); ! 374: c_time = time (0); ! 375: a_time = ctime (&c_time); ! 376: fprintf (out, " #Compiled:\t%s", a_time); ! 377: #ifdef __GNUC__ ! 378: #ifndef __VERSION__ ! 379: #define __VERSION__ "[unknown]" ! 380: #endif ! 381: fprintf (out, " # (META)compiled by GNU C version %s.\n", __VERSION__); ! 382: #else ! 383: fprintf (out, " # (META)compiled by CC.\n"); ! 384: #endif ! 385: } ! 386: ! 387: /* DEBUGGING UTILITIES */ ! 388: rtx al_log_insn_debug; ! 389: ! 390: abort_show_logged () ! 391: { ! 392: if (al_log_insn_debug) ! 393: my_print_rtx (al_log_insn_debug); ! 394: abort (); ! 395: } ! 396: ! 397: extern FILE *outfile; ! 398: ! 399: void ! 400: my_print_rtx (in_rtx) ! 401: register rtx in_rtx; ! 402: { ! 403: FILE *old; ! 404: old = outfile; ! 405: ! 406: outfile = stderr; ! 407: print_rtx (in_rtx); ! 408: fprintf (outfile, "\n"); ! 409: ! 410: outfile = old; ! 411: } ! 412: ! 413: void ! 414: my_print_insncode (insn) ! 415: rtx insn; ! 416: { ! 417: FILE *old; ! 418: old = outfile; ! 419: ! 420: outfile = stderr; ! 421: print_rtx (insn); ! 422: fprintf (outfile, "\n"); ! 423: fprintf (outfile, "INSN_CODE (insn) = %X\n", INSN_CODE (insn)); ! 424: ! 425: outfile = old; ! 426: } ! 427: ! 428: void ! 429: abort_with_insn (insn, reason) ! 430: rtx insn; ! 431: char *reason; ! 432: { ! 433: fprintf (stderr, "About to Abort::%s\n", reason); ! 434: my_print_rtx (insn); ! 435: abort (); ! 436: } ! 437: #endif ! 438: ! 439: void ! 440: abort_with_insn () ! 441: { ! 442: abort (); ! 443: } ! 444: ! 445: void ! 446: my_print_rtx (in_rtx) ! 447: register rtx in_rtx; ! 448: ! 449: { ! 450: abort(); ! 451: } ! 452: ! 453: #include "tree.h" ! 454: /* GET SECTION (DATA/SDATA) THRESHOLD */ ! 455: int mips_section_threshold = -1; ! 456: ! 457: extern char *tree_code_name[]; ! 458: ! 459: int ! 460: mips_section_get () ! 461: { ! 462: register int i; ! 463: if (mips_section_threshold == -1) ! 464: { ! 465: i = TARGET_GVALUE; ! 466: if (i >= 6) i += 3; ! 467: if ((1 << i) != MIPS_GVALUE_DEFAULT) ! 468: warning ("G value this run == %d\n", 1 << i); ! 469: mips_section_threshold = 1 << i; ! 470: } ! 471: ! 472: return mips_section_threshold; ! 473: } ! 474: ! 475: int ! 476: mips_output_external (file, tree_exp, name) ! 477: FILE *file; ! 478: tree tree_exp; ! 479: char *name; ! 480: { ! 481: register int i; ! 482: if (TARGET_GP_OPT ! 483: && ((TREE_CODE (tree_exp)) != FUNCTION_DECL) ! 484: && ! 485: ((i = int_size_in_bytes (TREE_TYPE (tree_exp))) > 0)) ! 486: { ! 487: fputs ("\n#ifndef _gccx__", file); ! 488: assemble_name (file, name); ! 489: fputs ("\n.extern\t", (file)); ! 490: assemble_name ((file), (name)); ! 491: fprintf ((file), ", %d", i, (TREE_TYPE (tree_exp))); ! 492: fputs ("\n#define _gccx__", file); ! 493: assemble_name (file, name); ! 494: fputs ("\n#endif\n ", file); ! 495: } ! 496: return 0; ! 497: } ! 498: ! 499: extern char *asm_file_name; ! 500: ! 501: int ! 502: mips_asm_file_end (file) ! 503: FILE *file; ! 504: { ! 505: if (TARGET_GP_OPT) ! 506: { ! 507: fprintf (file, "\n#else\n#ifndef %sRESCAN_GCC", "__x_"); ! 508: fprintf (file, "\n#define %sRESCAN_GCC\n#include \"%s\"", "__x_", ! 509: asm_file_name); ! 510: fprintf (file, "\n#endif\n#endif\n"); ! 511: } ! 512: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.