Annotation of gcc/config/1750a/1750a.c, revision 1.1.1.1

1.1       root        1: /* Subroutines for insn-output.c for MIL-STD-1750.
                      2:    Copyright (C) 1994 Free Software Foundation, Inc.
                      3:    Contributed by O.M.Kellogg, DASA ([email protected]).
                      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: #ifndef FILE
                     22: #include <stdio.h>
                     23: #endif
                     24: 
                     25: #define __datalbl
                     26: #include "config.h"
                     27: #include "rtl.h"
                     28: #include "tree.h"
                     29: #include "expr.h"
                     30: #define HAVE_cc0
                     31: #include "conditions.h"
                     32: #include "real.h"
                     33: 
                     34: struct datalabel_array datalbl[DATALBL_ARRSIZ];
                     35: int datalbl_ndx = -1;
                     36: struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];
                     37: int jmplbl_ndx = -1;
                     38: int label_pending = 0, program_counter = 0;
                     39: enum section current_section = Normal;
                     40: char *sectname[4] =
                     41: {"Normal", "Init", "Konst", "Static"};
                     42: 
                     43: int
                     44: notice_update_cc (exp)
                     45:      rtx exp;
                     46: {
                     47:   if (GET_CODE (exp) == SET)
                     48:     {
                     49:       enum rtx_code src_code = GET_CODE (SET_SRC (exp));
                     50:       /* Jumps do not alter the cc's.  */
                     51:       if (SET_DEST (exp) == pc_rtx)
                     52:        return;
                     53:       /* Moving register into memory doesn't alter the cc's.
                     54:         It may invalidate the RTX's which we remember the cc's came from.  */
                     55:       if (GET_CODE (SET_DEST (exp)) == MEM)
                     56:        {
                     57:          if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
                     58:            cc_status.value1 = 0;
                     59:          if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
                     60:            cc_status.value2 = 0;
                     61:          return;
                     62:        }
                     63:       /* Function calls clobber the cc's.  */
                     64:       else if (src_code == CALL)
                     65:        {
                     66:          CC_STATUS_INIT;
                     67:          return;
                     68:        }
                     69:       /* Emulated longword bit-ops leave cc's incorrect */
                     70:       else if (GET_MODE (SET_DEST (exp)) == HImode ?
                     71:               src_code == AND || src_code == IOR ||
                     72:               src_code == XOR || src_code == NOT : 0)
                     73:        {
                     74:          CC_STATUS_INIT;
                     75:          return;
                     76:        }
                     77:       /* Tests and compares set the cc's in predictable ways.  */
                     78:       else if (SET_DEST (exp) == cc0_rtx)
                     79:        {
                     80:          CC_STATUS_INIT;
                     81:          cc_status.value1 = SET_SRC (exp);
                     82:          return;
                     83:        }
                     84:       /* Anything that lands in a reg will set cc_status. */
                     85:       else if (REG_P (SET_DEST (exp)))
                     86:        {
                     87:          cc_status.flags = CC_NO_OVERFLOW;
                     88:          cc_status.value1 = SET_SRC (exp);
                     89:          cc_status.value2 = SET_DEST (exp);
                     90:          return;
                     91:        }
                     92:       else
                     93:        {
                     94:          CC_STATUS_INIT;
                     95:        }
                     96:     }
                     97:   else if (GET_CODE (exp) == PARALLEL
                     98:           && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
                     99:     {
                    100:       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
                    101:        return;
                    102:       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
                    103:        {
                    104:          CC_STATUS_INIT;
                    105:          cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
                    106:          return;
                    107:        }
                    108:       CC_STATUS_INIT;
                    109:     }
                    110:   else
                    111:     {
                    112:       CC_STATUS_INIT;
                    113:     }
                    114: }
                    115: 
                    116: 
                    117: rtx
                    118: function_arg (cum, mode, type, named)
                    119:      int cum;
                    120:      enum machine_mode mode;
                    121:      tree type;
                    122:      int named;
                    123: {
                    124:   int size;
                    125:   rtx result;
                    126: 
                    127:   if (MUST_PASS_IN_STACK (mode, type))
                    128:     return (rtx) 0;
                    129:   if (mode == BLKmode)
                    130:     size = int_size_in_bytes (type);
                    131:   else
                    132:     size = GET_MODE_SIZE (mode);
                    133:   if (cum + size < 12)
                    134:     return gen_rtx (REG, mode, cum);
                    135:   else
                    136:     return (rtx) 0;
                    137: }
                    138: 
                    139: 
                    140: #ifndef STRDUP
                    141: char *
                    142: strdup (str)
                    143:      char *str;
                    144: {
                    145:   char *p;
                    146:   if (str == NULL)
                    147:     return NULL;
                    148:   if ((p = (char *) malloc (strlen (str) + 1)) == NULL)
                    149:     {
                    150:       fprintf (stderr, "dynamic memory exhausted");
                    151:       abort ();
                    152:     }
                    153:   return strcpy (p, str);
                    154: }
                    155: 
                    156: #endif
                    157: 
                    158: 
                    159: double
                    160: get_double (x)
                    161:      rtx x;
                    162: {
                    163:   union
                    164:     {
                    165:       double d;
                    166:       long i[2];
                    167:     }
                    168:   du;
                    169: 
                    170:   du.i[0] = CONST_DOUBLE_LOW (x);
                    171:   du.i[1] = CONST_DOUBLE_HIGH (x);
                    172:   return du.d;
                    173: }
                    174: 
                    175: char *
                    176: float_label (code, value)
                    177:      char code;
                    178:      double value;
                    179: {
                    180:   int i = 1;
                    181:   static char label[32];
                    182:   char *p;
                    183: 
                    184:   label[0] = code;
                    185:   p = label + 1;
                    186:   sprintf (p, "%lf", value);
                    187:   while (*p)
                    188:     {
                    189:       *p = (*p == '+') ? 'p' :
                    190:        (*p == '-') ? 'm' : *p;
                    191:       p++;
                    192:     }
                    193:   return strdup (label);
                    194: }
                    195: 
                    196: 
                    197: char *
                    198: movcnt_regno_adjust (rtx * op)
                    199: {
                    200:   static char outstr[40];
                    201:   int cntreg = REGNO (op[2]), cntreg_1750 = REGNO (op[0]) + 1;
                    202:   int dstreg = REGNO (op[0]), srcreg = REGNO (op[1]);
                    203: 
                    204:   if (cntreg == cntreg_1750)
                    205:     sprintf (outstr, "mov r%%0,r%%1");
                    206:   else if (dstreg + 1 == srcreg && srcreg == cntreg + 2)
                    207:     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", cntreg, dstreg);
                    208:   else if (dstreg + 1 == srcreg && srcreg < cntreg)
                    209:     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", srcreg, cntreg);
                    210:   else if (srcreg + 1 == cntreg && dstreg > cntreg)
                    211:     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,r%%1", srcreg, dstreg);
                    212:   else
                    213:     sprintf (outstr, "xwr r%d,r%d\n\tmov r%%0,%%1\n\txwr r%d,r%d",
                    214:             cntreg, cntreg_1750, cntreg_1750, cntreg);
                    215:   return outstr;
                    216: }
                    217: 
                    218: char *
                    219: mod_regno_adjust (char *instr, rtx * op)
                    220: {
                    221:   static char outstr[40];
                    222:   char *r = (!strncmp (instr, "dvr", 3) ? "r" : "");
                    223:   int modregno_gcc = REGNO (op[3]), modregno_1750 = REGNO (op[0]) + 1;
                    224: 
                    225:   if (modregno_gcc == modregno_1750)
                    226:     sprintf (outstr, "%s r%%0,%s%%2", instr, r);
                    227:   else
                    228:     sprintf (outstr, "lr r%d,r%d\n\t%s r%%0,%s%%2\n\txwr r%d,r%d",
                    229:        modregno_gcc, modregno_1750, instr, r, modregno_1750, modregno_gcc);
                    230:   return outstr;
                    231: }
                    232: 
                    233: 
                    234: /* Auxiliary to `nonindirect_operand':
                    235:    Check if op is a valid memory operand for 1750A arith./logic (non-move)
                    236:    instructions. */
                    237: int
                    238: memop_valid (register rtx op)
                    239: {
                    240:   if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode)
                    241:     return 0;
                    242:   switch (GET_CODE (op))
                    243:     {
                    244:     case MEM:
                    245:     case MINUS:
                    246:     case MULT:
                    247:     case DIV:
                    248:       return 0;
                    249:     case PLUS:
                    250:       if (!memop_valid (XEXP (op, 0)))
                    251:        return 0;
                    252:       return memop_valid (XEXP (op, 1));
                    253:     case REG:
                    254:       if (REGNO (op) > 0)
                    255:        return 1;
                    256:       return 0;
                    257:     case CONST:
                    258:     case CONST_INT:
                    259:     case SYMBOL_REF:
                    260:     case SUBREG:
                    261:       return 1;
                    262:     default:
                    263:       printf ("memop_valid: code=%d\n", (int) GET_CODE (op));
                    264:       return 1;
                    265:     }
                    266: }
                    267: 
                    268: /* extra predicate for recog: */
                    269: int
                    270: nonindirect_operand (register rtx op, enum machine_mode mode)
                    271: {
                    272:   int retval;
                    273: 
                    274:   switch (GET_CODE (op))
                    275:     {
                    276:     case MEM:
                    277:       retval = memop_valid (XEXP (op, 0));
                    278:       return retval;
                    279:     case REG:
                    280:       return 1;
                    281:     default:
                    282:       if (!CONSTANT_P (op))
                    283:        return 0;
                    284:     }
                    285:   return 1;
                    286: }
                    287: 
                    288: /* predicate for the STC instruction: */
                    289: int
                    290: small_nonneg_const (register rtx op, enum machine_mode mode)
                    291: {
                    292:   if (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) <= 15)
                    293:     return 1;
                    294:   return 0;
                    295: }
                    296: 
                    297: /* Decide whether to output a conditional jump as a "Jump Conditional"
                    298:    or as a "Branch Conditional": */
                    299: 
                    300: int
                    301: find_jmplbl (int labelnum)
                    302: {
                    303:   int i, found = 0;
                    304: 
                    305:   for (i = 0; i <= jmplbl_ndx; i++)
                    306:     if (labelnum == jmplbl[i].num)
                    307:       {
                    308:        found = 1;
                    309:        break;
                    310:       }
                    311:   if (found)
                    312:     return i;
                    313:   return -1;
                    314: }
                    315: 
                    316: char *
                    317: branch_or_jump (char *condition, int targetlabel_number)
                    318: {
                    319:   static char buf[30];
                    320:   int index;
                    321: 
                    322:   if ((index = find_jmplbl (targetlabel_number)) >= 0)
                    323:     if (program_counter - jmplbl[index].pc < 128)
                    324:       {
                    325:        sprintf (buf, "b%s %%l0", condition);
                    326:        return buf;
                    327:       }
                    328:   sprintf (buf, "jc %s,%%l0", condition);
                    329:   return buf;
                    330: }
                    331: 
                    332: 
                    333: 
                    334: /* The PRINT_OPERAND and PRINT_OPERAND_ADDRESS macros have been
                    335:    made functions: */
                    336: 
                    337: print_operand (file, x, kode)
                    338:      FILE *file;
                    339:      rtx x;
                    340:      enum rtx_code kode;
                    341: {
                    342:   switch (GET_CODE (x))
                    343:     {
                    344:     case REG:
                    345:       fprintf (file, "%d", REGNO (x));
                    346:       break;
                    347:     case SYMBOL_REF:
                    348:       fprintf (file, "%s", XSTR (x, 0));
                    349:       break;
                    350:     case LABEL_REF:
                    351:     case CONST:
                    352:     case MEM:
                    353:       output_address (XEXP (x, 0));
                    354:       break;
                    355:     case CONST_DOUBLE:
                    356: /*    {
                    357:        double value = get_double (x);
                    358:        char fltstr[32];
                    359:        sprintf (fltstr, "%lf", value);
                    360: 
                    361:        if (kode == 'D' || kode == 'E')
                    362:          {
                    363:            int i, found = 0;
                    364:            for (i = 0; i <= datalbl_ndx; i++)
                    365:              if (strcmp (fltstr, datalbl[i].value) == 0)
                    366:                {
                    367:                  found = 1;
                    368:                  break;
                    369:                }
                    370:            if (!found)
                    371:              {
                    372:                strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
                    373:                datalbl[i].name = float_label (kode, value);
                    374:                datalbl[i].size = (kode == 'E') ? 3 : 2;
                    375:                check_section (Konst);
                    376:                fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
                    377:                        (kode == 'E' ? "ef" : "f"), fltstr);
                    378:                check_section (Normal);
                    379:              }
                    380:          }
                    381:        else if (kode == 'F' || kode == 'G')
                    382:          {
                    383:            int i, found = 0;
                    384:            for (i = 0; i <= datalbl_ndx; i++)
                    385:              if (strcmp (fltstr, datalbl[i].value) == 0)
                    386:                {
                    387:                  found = 1;
                    388:                  break;
                    389:                }
                    390:            if (!found)
                    391:              {
                    392:                fprintf (stderr,
                    393:                   "float value %lfnot found upon label reference\n", value);
                    394:                strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
                    395:                datalbl[i].name = float_label (kode, value);
                    396:                datalbl[i].size = (kode == 'G') ? 3 : 2;
                    397:                check_section (Konst);
                    398:                fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
                    399:                        (kode == 'G' ? "ef" : "f"), fltstr);
                    400:                check_section (Normal);
                    401:              }
                    402:            fprintf (file, "%s ;P_O 'F'", datalbl[i].name);
                    403:          }
                    404:        else
                    405:          fprintf (file, " %s  ;P_O cst_dbl ", fltstr);
                    406:       }
                    407:  */
                    408:       fprintf (file, "%lf", get_double (x));
                    409:       break;
                    410:     case CONST_INT:
                    411:       if (kode == 'J')
                    412:        fprintf (file, "%d", -INTVAL (x));
                    413:       else if (INTVAL (x) > 0x7FFF)
                    414:        fprintf (file, "%d  ; range correction (val>0x7FFF) applied",
                    415:                 INTVAL (x) - 0x10000);
                    416:       else
                    417:        fprintf (file, "%d", INTVAL (x));
                    418:       break;
                    419:     case CODE_LABEL:
                    420:       fprintf (file, "L%d", XINT (x, 3));
                    421:       break;
                    422:     case CALL:
                    423:       fprintf (file, "CALL nargs=%d, func is either '%s' or '%s'",
                    424:        XEXP (x, 1), XSTR (XEXP (XEXP (x, 0), 1), 0), XSTR (XEXP (x, 0), 1));
                    425:       break;
                    426:     case PLUS:
                    427:       {
                    428:        rtx op0 = XEXP (x, 0), op1 = XEXP (x, 1);
                    429:        int op0code = GET_CODE (op0), op1code = GET_CODE (op1);
                    430:        if (op1code == CONST_INT)
                    431:          switch (op0code)
                    432:            {
                    433:            case REG:
                    434:              fprintf (file, "%d,r%d  ; p_o_PLUS for REG and CONST",
                    435:                       INTVAL (op1), REGNO (op0));
                    436:              break;
                    437:            case SYMBOL_REF:
                    438:              fprintf (file, "%d+%s", INTVAL (op1), XSTR (op0, 0));
                    439:              break;
                    440:            case MEM:
                    441:              fprintf (file, "%d,[mem:", INTVAL (op1));
                    442:              output_address (XEXP (op0, 0));
                    443:              fprintf (file, "] ;P_O plus");
                    444:              break;
                    445:            default:
                    446:              fprintf (file, "p_o_PLUS UFO, code=%d, with CONST=%d",
                    447:                       (int) op0code, INTVAL (op1));
                    448:            }
                    449:        else if (op1code == SYMBOL_REF && op0code == REG)
                    450:          fprintf (file, "%s,r%d  ; P_O: (plus reg sym)",
                    451:                   XSTR (op1, 0), REGNO (op0));
                    452:        else
                    453:          fprintf (file, "p_o_+: op0code=%d, op1code=%d", op0code, op1code);
                    454:       }
                    455:       break;
                    456:     default:
                    457:       fprintf (file, "p_o_UFO code=%d", GET_CODE (x));
                    458:     }
                    459: }
                    460: 
                    461: print_operand_address (file, addr)
                    462:      FILE *file;
                    463:      rtx addr;
                    464: {
                    465:   switch (GET_CODE (addr))
                    466:     {
                    467:     case REG:
                    468:       fprintf (file, "0,r%d ; P_O_A", REGNO (addr));
                    469:       break;
                    470:     case PLUS:
                    471:       {
                    472:        register rtx x = XEXP (addr, 0), y = XEXP (addr, 1);
                    473:        switch (GET_CODE (x))
                    474:          {
                    475:          case REG:
                    476:            switch (GET_CODE (y))
                    477:              {
                    478:              case CONST:
                    479:                output_address (XEXP (y, 0));
                    480:                fprintf (file, ",r%d ;P_O_A reg + const expr", REGNO (x));
                    481:                break;
                    482:              case CONST_INT:
                    483:                fprintf (file, "%d,r%d", INTVAL (y), REGNO (x));
                    484:                break;
                    485:              case SYMBOL_REF:
                    486:                fprintf (file, "%s,r%d  ; P_O_A reg + sym",
                    487:                         XSTR (y, 0), REGNO (x));
                    488:                break;
                    489:              default:
                    490:                fprintf (file, "[P_O_A reg%d+UFO code=%d]",
                    491:                         REGNO (x), GET_CODE (y));
                    492:              }
                    493:            break;
                    494:          case LABEL_REF:
                    495:          case SYMBOL_REF:
                    496:            switch (GET_CODE (y))
                    497:              {
                    498:              case CONST_INT:
                    499:                fprintf (file, "%d+%s", INTVAL (y), XSTR (x, 0));
                    500:                break;
                    501:              case REG:
                    502:                fprintf (file, "%s,r%d ;P_O_A sym + reg",
                    503:                         XSTR (x, 0), REGNO (y));
                    504:                break;
                    505:              default:
                    506:                fprintf (file, "P_O_A sym/lab+UFO[sym=%s,code(y)=%d]",
                    507:                         XSTR (x, 0), GET_CODE (y));
                    508:              }
                    509:            break;
                    510:          case CONST:
                    511:            output_address (XEXP (x, 0));
                    512:            if (GET_CODE (y) == REG)
                    513:              fprintf (file, ",r%d ;P_O_A const + reg", REGNO (x));
                    514:            else
                    515:              fprintf (file, "P_O_A const+UFO code(y)=%d]", GET_CODE (y));
                    516:            break;
                    517:          case MEM:
                    518:            output_address (y);
                    519:            fprintf (file, ",[mem:");
                    520:            output_address (XEXP (x, 0));
                    521:            fprintf (file, "] ;P_O_A plus");
                    522:            break;
                    523:          default:
                    524:            fprintf (file, "P_O_A plus op1_UFO[code1=%d,code2=%d]",
                    525:                     GET_CODE (x), GET_CODE (y));
                    526:          }
                    527:       }
                    528:       break;
                    529:     case CONST_INT:
                    530:       if (INTVAL (addr) < 0x10000 && INTVAL (addr) >= -0x10000)
                    531:        fprintf (file, "%d ; p_o_a const addr?!", INTVAL (addr));
                    532:       else
                    533:        {
                    534:          fprintf (file, "[p_o_a=ILLEGAL_CONST]");
                    535:          output_addr_const (file, addr);
                    536:        }
                    537:       break;
                    538:     case LABEL_REF:
                    539:     case SYMBOL_REF:
                    540:       fprintf (file, "%s", XSTR (addr, 0));
                    541:       break;
                    542:     case MEM:
                    543:       fprintf (file, "[memUFO:");
                    544:       output_address (XEXP (addr, 0));
                    545:       fprintf (file, "]");
                    546:       break;
                    547:     case CONST:
                    548:       output_address (XEXP (addr, 0));
                    549:       fprintf (file, " ;P_O_A const");
                    550:       break;
                    551:     default:
                    552:       fprintf (file, " p_o_a UFO, code=%d val=0x%x",
                    553:               (int) GET_CODE (addr), INTVAL (addr));
                    554:       break;
                    555:     }
                    556: }
                    557: 
                    558: 
                    559: /*
                    560: ASM_FILE_END(file)
                    561:   FILE *file;
                    562: {
                    563:       if (datalbl_ndx >= 0) {
                    564:          int i, cum_size=0;
                    565:          fprintf(file,"\n\tstatic\ninit_srel\n");
                    566:          for (i = 0; i <= datalbl_ndx; i++) {
                    567:           if (datalbl[i].name == NULL) 
                    568:           {
                    569:             fprintf (stderr, "asm_file_end intern err (datalbl)\n");
                    570:             exit (0);
                    571:           }
                    572:            fprintf(file,"%s\t block %d\n",
                    573:                  datalbl[i].name,datalbl[i].size);
                    574:            cum_size += datalbl[i].size;
                    575:         }
                    576:          fprintf(file,"\n\tinit\n");
                    577:          fprintf(file,"\tLIM  R0,init_srel ;dst\n");
                    578:          fprintf(file,"\tLIM  R1,%d ;cnt\n",cum_size);
                    579:          fprintf(file,"\tLIM  R2,K%s ;src\n",datalbl[0].name);
                    580:          fprintf(file,"\tMOV  R0,R2\n");
                    581:          fprintf(file,"\n\tnormal\n");
                    582:          datalbl_ndx = -1;
                    583:          for (i = 0; i < DATALBL_ARRSIZ; i++)
                    584:             datalbl[i].size = 0;
                    585:       }        
                    586:       fprintf(file,"\n\tend\n");
                    587: }
                    588:  */

unix.superglobalmegacorp.com

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