Annotation of gcc/config/out-mips.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.