Annotation of 43BSDReno/contrib/emacs-18.55/gdb/m68k-pinsn.c, revision 1.1.1.1

1.1       root        1: /* Print m68k instructions for GDB, the GNU debugger.
                      2:    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
                      3: 
                      4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
                      5: WARRANTY.  No author or distributor accepts responsibility to anyone
                      6: for the consequences of using it or for whether it serves any
                      7: particular purpose or works at all, unless he says so in writing.
                      8: Refer to the GDB General Public License for full details.
                      9: 
                     10: Everyone is granted permission to copy, modify and redistribute GDB,
                     11: but only under the conditions described in the GDB General Public
                     12: License.  A copy of this license is supposed to have been given to you
                     13: along with GDB so you can know your rights and responsibilities.  It
                     14: should be in a file named COPYING.  Among other things, the copyright
                     15: notice and this notice must be preserved on all copies.
                     16: 
                     17: In other words, go ahead and share GDB, but don't try to stop
                     18: anyone else from sharing it farther.  Help stamp out software hoarding!
                     19: */
                     20: 
                     21: #include <stdio.h>
                     22: 
                     23: #include "defs.h"
                     24: #include "param.h"
                     25: #include "symtab.h"
                     26: #include "opcode.h"
                     27: 
                     28: /* 68k instructions are never longer than this many bytes.  */
                     29: #define MAXLEN 22
                     30: 
                     31: /* Number of elements in the opcode table.  */
                     32: #define NOPCODES (sizeof m68k_opcodes / sizeof m68k_opcodes[0])
                     33: 
                     34: extern char *reg_names[];
                     35: char *fpcr_names[] = { "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",
                     36:                     "fpiar/fpcr", "fpsr/fpcr", "fpiar-fpcr"};
                     37: 
                     38: static unsigned char *print_insn_arg ();
                     39: static unsigned char *print_indexed ();
                     40: static void print_base ();
                     41: static int fetch_arg ();
                     42: 
                     43: #define NEXTBYTE(p)  (p += 2, ((char *)p)[-1])
                     44: 
                     45: #define NEXTWORD(p)  \
                     46:   (p += 2, ((((char *)p)[-2]) << 8) + p[-1])
                     47: 
                     48: #define NEXTLONG(p)  \
                     49:   (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
                     50: 
                     51: #define NEXTSINGLE(p) \
                     52:   (p += 4, *((float *)(p - 4)))
                     53: 
                     54: #define NEXTDOUBLE(p) \
                     55:   (p += 8, *((double *)(p - 8)))
                     56: 
                     57: #define NEXTEXTEND(p) \
                     58:   (p += 12, 0.0)       /* Need a function to convert from extended to double
                     59:                           precision... */
                     60: 
                     61: #define NEXTPACKED(p) \
                     62:   (p += 12, 0.0)       /* Need a function to convert from packed to double
                     63:                           precision.   Actually, it's easier to print a
                     64:                           packed number than a double anyway, so maybe
                     65:                           there should be a special case to handle this... */
                     66: 
                     67: /* Print the m68k instruction at address MEMADDR in debugged memory,
                     68:    on STREAM.  Returns length of the instruction, in bytes.  */
                     69: 
                     70: int
                     71: print_insn (memaddr, stream)
                     72:      CORE_ADDR memaddr;
                     73:      FILE *stream;
                     74: {
                     75:   unsigned char buffer[MAXLEN];
                     76:   register int i;
                     77:   register unsigned char *p;
                     78:   register char *d;
                     79:   register int bestmask;
                     80:   int best;
                     81: 
                     82:   read_memory (memaddr, buffer, MAXLEN);
                     83: 
                     84:   bestmask = 0;
                     85:   best = -1;
                     86:   for (i = 0; i < NOPCODES; i++)
                     87:     {
                     88:       register unsigned int opcode = m68k_opcodes[i].opcode;
                     89:       register unsigned int match = m68k_opcodes[i].match;
                     90:       if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
                     91:          && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
                     92:          && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
                     93:          && ((0xff & buffer[3] & match) == (0xff & opcode)))
                     94:        {
                     95:          /* Don't use for printout the variants of divul and divsl
                     96:             that have the same register number in two places.
                     97:             The more general variants will match instead.  */
                     98:          for (d = m68k_opcodes[i].args; *d; d += 2)
                     99:            if (d[1] == 'D')
                    100:              break;
                    101: 
                    102:          /* Don't use for printout the variants of most floating
                    103:             point coprocessor instructions which use the same
                    104:             register number in two places, as above. */
                    105:          if (*d == 0)
                    106:            for (d = m68k_opcodes[i].args; *d; d += 2)
                    107:              if (d[1] == 't')
                    108:                break;
                    109: 
                    110:          if (*d == 0 && match > bestmask)
                    111:            {
                    112:              best = i;
                    113:              bestmask = match;
                    114:            }
                    115:        }
                    116:     }
                    117: 
                    118:   /* Handle undefined instructions.  */
                    119:   if (best < 0)
                    120:     {
                    121:       fprintf (stream, "0%o", (buffer[0] << 8) + buffer[1]);
                    122:       return 2;
                    123:     }
                    124: 
                    125:   fprintf (stream, "%s", m68k_opcodes[best].name);
                    126: 
                    127:   /* Point at first word of argument data,
                    128:      and at descriptor for first argument.  */
                    129:   p = buffer + 2;
                    130:   
                    131:   /* Why do this this way? -MelloN */
                    132:   for (d = m68k_opcodes[best].args; *d; d += 2)
                    133:     {
                    134:       if (d[0] == '#')
                    135:        {
                    136:          if (d[1] == 'l' && p - buffer < 6)
                    137:            p = buffer + 6;
                    138:          else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
                    139:            p = buffer + 4;
                    140:        }
                    141:       if (d[1] >= '1' && d[1] <= '3' && p - buffer < 4)
                    142:        p = buffer + 4;
                    143:       if (d[1] >= '4' && d[1] <= '6' && p - buffer < 6)
                    144:        p = buffer + 6;
                    145:     }
                    146: 
                    147:   d = m68k_opcodes[best].args;
                    148: 
                    149:   if (*d)
                    150:     fputc (' ', stream);
                    151: 
                    152:   while (*d)
                    153:     {
                    154:       p = print_insn_arg (d, buffer, p, memaddr + p - buffer, stream);
                    155:       d += 2;
                    156:       if (*d && *(d - 2) != 'I' && *d != 'k')
                    157:        fprintf (stream, ",");
                    158:     }
                    159:   return p - buffer;
                    160: }
                    161: 
                    162: static unsigned char *
                    163: print_insn_arg (d, buffer, p, addr, stream)
                    164:      char *d;
                    165:      unsigned char *buffer;
                    166:      register unsigned char *p;
                    167:      CORE_ADDR addr;           /* PC for this arg to be relative to */
                    168:      FILE *stream;
                    169: {
                    170:   register int val;
                    171:   register int place = d[1];
                    172:   int regno;
                    173:   register char *regname;
                    174:   register unsigned char *p1;
                    175:   register double flval;
                    176:   int flt_p;
                    177: 
                    178:   switch (*d)
                    179:     {
                    180:     case 'C':
                    181:       fprintf (stream, "ccr");
                    182:       break;
                    183: 
                    184:     case 'S':
                    185:       fprintf (stream, "sr");
                    186:       break;
                    187: 
                    188:     case 'U':
                    189:       fprintf (stream, "usp");
                    190:       break;
                    191: 
                    192:     case 'J':
                    193:       {
                    194:        static struct { char *name; int value; } names[]
                    195:          = {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002},
                    196:             {"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802},
                    197:             {"msp", 0x803}, {"isp", 0x804}};
                    198: 
                    199:        val = fetch_arg (buffer, place, 12);
                    200:        for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
                    201:          if (names[regno].value == val)
                    202:            {
                    203:              fprintf (stream, names[regno].name);
                    204:              break;
                    205:            }
                    206:        if (regno < 0)
                    207:          fprintf (stream, "%d", val);
                    208:       }
                    209:       break;
                    210: 
                    211:     case 'Q':
                    212:       val = fetch_arg (buffer, place, 3);
                    213:       if (val == 0) val = 8;
                    214:       fprintf (stream, "#%d", val);
                    215:       break;
                    216: 
                    217:     case 'M':
                    218:       val = fetch_arg (buffer, place, 8);
                    219:       if (val & 0x80)
                    220:        val = val - 0x100;
                    221:       fprintf (stream, "#%d", val);
                    222:       break;
                    223: 
                    224:     case 'T':
                    225:       val = fetch_arg (buffer, place, 4);
                    226:       fprintf (stream, "#%d", val);
                    227:       break;
                    228: 
                    229:     case 'D':
                    230:       fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]);
                    231:       break;
                    232: 
                    233:     case 'A':
                    234:       fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3) + 010]);
                    235:       break;
                    236: 
                    237:     case 'R':
                    238:       fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]);
                    239:       break;
                    240: 
                    241:     case 'F':
                    242:       fprintf (stream, "fp%d", fetch_arg (buffer, place, 3));
                    243:       break;
                    244: 
                    245:     case 'O':
                    246:       val = fetch_arg (buffer, place, 6);
                    247:       if (val & 0x20)
                    248:        fprintf (stream, "%s", reg_names [val & 7]);
                    249:       else
                    250:        fprintf (stream, "%d", val);
                    251:       break;
                    252: 
                    253:     case '+':
                    254:       fprintf (stream, "(%s)+", reg_names[fetch_arg (buffer, place, 3) + 8]);
                    255:       break;
                    256: 
                    257:     case '-':
                    258:       fprintf (stream, "-(%s)", reg_names[fetch_arg (buffer, place, 3) + 8]);
                    259:       break;
                    260: 
                    261:     case 'k':
                    262:       if (place == 'k')
                    263:        fprintf (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]);
                    264:       else if (place == 'C')
                    265:        {
                    266:          val = fetch_arg (buffer, place, 7);
                    267:          if ( val > 63 )               /* This is a signed constant. */
                    268:            val -= 128;
                    269:          fprintf (stream, "{#%d}", val);
                    270:        }
                    271:       else
                    272:        error ("Invalid arg format in opcode table: \"%c%c\".",
                    273:               *d, place);
                    274:       break;
                    275: 
                    276:     case '#':
                    277:       p1 = buffer + 2;
                    278:       if (place == 's')
                    279:        val = fetch_arg (buffer, place, 4);
                    280:       else if (place == 'C')
                    281:        val = fetch_arg (buffer, place, 7);
                    282:       else if (place == '8')
                    283:        val = fetch_arg (buffer, place, 3);
                    284:       else if (place == '3')
                    285:        val = fetch_arg (buffer, place, 8);
                    286:       else if (place == 'b')
                    287:        val = NEXTBYTE (p1);
                    288:       else if (place == 'w')
                    289:        val = NEXTWORD (p1);
                    290:       else if (place == 'l')
                    291:        val = NEXTLONG (p1);
                    292:       else
                    293:        error ("Invalid arg format in opcode table: \"%c%c\".",
                    294:               *d, place);
                    295:       fprintf (stream, "#%d", val);
                    296:       break;
                    297: 
                    298:     case '^':
                    299:       if (place == 's')
                    300:        val = fetch_arg (buffer, place, 4);
                    301:       else if (place == 'C')
                    302:        val = fetch_arg (buffer, place, 7);
                    303:       else if (place == '8')
                    304:        val = fetch_arg (buffer, place, 3);
                    305:       else if (place == 'b')
                    306:        val = NEXTBYTE (p);
                    307:       else if (place == 'w')
                    308:        val = NEXTWORD (p);
                    309:       else if (place == 'l')
                    310:        val = NEXTLONG (p);
                    311:       else
                    312:        error ("Invalid arg format in opcode table: \"%c%c\".",
                    313:               *d, place);
                    314:       fprintf (stream, "#%d", val);
                    315:       break;
                    316: 
                    317:     case 'B':
                    318:       if (place == 'b')
                    319:        val = NEXTBYTE (p);
                    320:       else if (place == 'w')
                    321:        val = NEXTWORD (p);
                    322:       else if (place == 'l')
                    323:        val = NEXTLONG (p);
                    324:       else if (place == 'g')
                    325:        {
                    326:          val = ((char *)buffer)[1];
                    327:          if (val == 0)
                    328:            val = NEXTWORD (p);
                    329:          else if (val == -1)
                    330:            val = NEXTLONG (p);
                    331:        }
                    332:       else if (place == 'c')
                    333:        {
                    334:          if (buffer[1] & 0x40)         /* If bit six is one, long offset */
                    335:            val = NEXTLONG (p);
                    336:          else
                    337:            val = NEXTWORD (p);
                    338:        }
                    339:       else
                    340:        error ("Invalid arg format in opcode table: \"%c%c\".",
                    341:               *d, place);
                    342: 
                    343:       print_address (addr + val, stream);
                    344:       break;
                    345: 
                    346:     case 'd':
                    347:       val = NEXTWORD (p);
                    348:       fprintf (stream, "%d(%s)", val, reg_names[fetch_arg (buffer, place, 3)]);
                    349:       break;
                    350: 
                    351:     case 's':
                    352:       fprintf (stream, "%s", fpcr_names[fetch_arg (buffer, place, 3)]);
                    353:       break;
                    354: 
                    355:     case 'I':
                    356:       val = fetch_arg (buffer, 'd', 3);                  /* Get coprocessor ID... */
                    357:       if (val != 1)                            /* Unusual coprocessor ID? */
                    358:        fprintf (stream, "(cpid=%d) ", val);
                    359:       if (place == 'i')
                    360:        p += 2;                      /* Skip coprocessor extended operands */
                    361:       break;
                    362: 
                    363:     case '*':
                    364:     case '~':
                    365:     case '%':
                    366:     case ';':
                    367:     case '@':
                    368:     case '!':
                    369:     case '$':
                    370:     case '?':
                    371:     case '/':
                    372:     case '&':
                    373: 
                    374:       if (place == 'd')
                    375:        {
                    376:          val = fetch_arg (buffer, 'x', 6);
                    377:          val = ((val & 7) << 3) + ((val >> 3) & 7);
                    378:        }
                    379:       else
                    380:        val = fetch_arg (buffer, 's', 6);
                    381: 
                    382:       /* Get register number assuming address register.  */
                    383:       regno = (val & 7) + 8;
                    384:       regname = reg_names[regno];
                    385:       switch (val >> 3)
                    386:        {
                    387:        case 0:
                    388:          fprintf (stream, "%s", reg_names[val]);
                    389:          break;
                    390: 
                    391:        case 1:
                    392:          fprintf (stream, "%s", regname);
                    393:          break;
                    394: 
                    395:        case 2:
                    396:          fprintf (stream, "(%s)", regname);
                    397:          break;
                    398: 
                    399:        case 3:
                    400:          fprintf (stream, "(%s)+", regname);
                    401:          break;
                    402: 
                    403:        case 4:
                    404:          fprintf (stream, "-(%s)", regname);
                    405:          break;
                    406: 
                    407:        case 5:
                    408:          val = NEXTWORD (p);
                    409:          fprintf (stream, "%d(%s)", val, regname);
                    410:          break;
                    411: 
                    412:        case 6:
                    413:          p = print_indexed (regno, p, addr, stream);
                    414:          break;
                    415: 
                    416:        case 7:
                    417:          switch (val & 7)
                    418:            {
                    419:            case 0:
                    420:              val = NEXTWORD (p);
                    421:              fprintf (stream, "@#");
                    422:              print_address (val, stream);
                    423:              break;
                    424: 
                    425:            case 1:
                    426:              val = NEXTLONG (p);
                    427:              fprintf (stream, "@#");
                    428:              print_address (val, stream);
                    429:              break;
                    430: 
                    431:            case 2:
                    432:              val = NEXTWORD (p);
                    433:              print_address (addr + val, stream);
                    434:              break;
                    435: 
                    436:            case 3:
                    437:              p = print_indexed (-1, p, addr, stream);
                    438:              break;
                    439: 
                    440:            case 4:
                    441:              flt_p = 1;        /* Assume it's a float... */
                    442:              switch( place )
                    443:              {
                    444:                case 'b':
                    445:                  val = NEXTBYTE (p);
                    446:                  flt_p = 0;
                    447:                  break;
                    448: 
                    449:                case 'w':
                    450:                  val = NEXTWORD (p);
                    451:                  flt_p = 0;
                    452:                  break;
                    453: 
                    454:                case 'l':
                    455:                  val = NEXTLONG (p);
                    456:                  flt_p = 0;
                    457:                  break;
                    458: 
                    459:                case 'f':
                    460:                  flval = NEXTSINGLE(p);
                    461:                  break;
                    462: 
                    463:                case 'F':
                    464:                  flval = NEXTDOUBLE(p);
                    465:                  break;
                    466: 
                    467:                case 'x':
                    468:                  flval = NEXTEXTEND(p);
                    469:                  break;
                    470: 
                    471:                case 'p':
                    472:                  flval = NEXTPACKED(p);
                    473:                  break;
                    474: 
                    475:                default:
                    476:                  error ("Invalid arg format in opcode table: \"%c%c\".",
                    477:                       *d, place);
                    478:              }
                    479:              if ( flt_p )      /* Print a float? */
                    480:                fprintf (stream, "#%g", flval);
                    481:              else
                    482:                fprintf (stream, "#%d", val);
                    483:              break;
                    484: 
                    485:            default:
                    486:              fprintf (stream, "<invalid address mode 0%o>", val);
                    487:            }
                    488:        }
                    489:       break;
                    490: 
                    491:     default:
                    492:       error ("Invalid arg format in opcode table: \"%c\".", *d);
                    493:     }
                    494: 
                    495:   return (unsigned char *) p;
                    496: }
                    497: 
                    498: /* Fetch BITS bits from a position in the instruction specified by CODE.
                    499:    CODE is a "place to put an argument", or 'x' for a destination
                    500:    that is a general address (mode and register).
                    501:    BUFFER contains the instruction.  */
                    502: 
                    503: static int
                    504: fetch_arg (buffer, code, bits)
                    505:      unsigned char *buffer;
                    506:      char code;
                    507:      int bits;
                    508: {
                    509:   register int val;
                    510:   switch (code)
                    511:     {
                    512:     case 's':
                    513:       val = buffer[1];
                    514:       break;
                    515: 
                    516:     case 'd':                  /* Destination, for register or quick.  */
                    517:       val = (buffer[0] << 8) + buffer[1];
                    518:       val >>= 9;
                    519:       break;
                    520: 
                    521:     case 'x':                  /* Destination, for general arg */
                    522:       val = (buffer[0] << 8) + buffer[1];
                    523:       val >>= 6;
                    524:       break;
                    525: 
                    526:     case 'k':
                    527:       val = (buffer[3] >> 4);
                    528:       break;
                    529: 
                    530:     case 'C':
                    531:       val = buffer[3];
                    532:       break;
                    533: 
                    534:     case '1':
                    535:       val = (buffer[2] << 8) + buffer[3];
                    536:       val >>= 12;
                    537:       break;
                    538: 
                    539:     case '2':
                    540:       val = (buffer[2] << 8) + buffer[3];
                    541:       val >>= 6;
                    542:       break;
                    543: 
                    544:     case '3':
                    545:     case 'j':
                    546:       val = (buffer[2] << 8) + buffer[3];
                    547:       break;
                    548: 
                    549:     case '4':
                    550:       val = (buffer[4] << 8) + buffer[5];
                    551:       val >>= 12;
                    552:       break;
                    553: 
                    554:     case '5':
                    555:       val = (buffer[4] << 8) + buffer[5];
                    556:       val >>= 6;
                    557:       break;
                    558: 
                    559:     case '6':
                    560:       val = (buffer[4] << 8) + buffer[5];
                    561:       break;
                    562: 
                    563:     case '7':
                    564:       val = (buffer[2] << 8) + buffer[3];
                    565:       val >>= 7;
                    566:       break;
                    567:       
                    568:     case '8':
                    569:       val = (buffer[2] << 8) + buffer[3];
                    570:       val >>= 10;
                    571:       break;
                    572: 
                    573:     default:
                    574:       abort ();
                    575:     }
                    576: 
                    577:   switch (bits)
                    578:     {
                    579:     case 3:
                    580:       return val & 7;
                    581:     case 4:
                    582:       return val & 017;
                    583:     case 5:
                    584:       return val & 037;
                    585:     case 6:
                    586:       return val & 077;
                    587:     case 7:
                    588:       return val & 0177;
                    589:     case 8:
                    590:       return val & 0377;
                    591:     case 12:
                    592:       return val & 07777;
                    593:     default:
                    594:       abort ();
                    595:     }
                    596: }
                    597: 
                    598: /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
                    599:    P points to extension word, in buffer.
                    600:    ADDR is the nominal core address of that extension word.  */
                    601: 
                    602: static unsigned char *
                    603: print_indexed (basereg, p, addr, stream)
                    604:      int basereg;
                    605:      unsigned char *p;
                    606:      FILE *stream;
                    607:      CORE_ADDR addr;
                    608: {
                    609:   register int word;
                    610:   static char *scales[] = {"", "*2", "*4", "*8"};
                    611:   register int base_disp;
                    612:   register int outer_disp;
                    613:   char buf[40];
                    614: 
                    615:   word = NEXTWORD (p);
                    616: 
                    617:   /* Generate the text for the index register.
                    618:      Where this will be output is not yet determined.  */
                    619:   sprintf (buf, "[%s.%c%s]",
                    620:           reg_names[(word >> 12) & 0xf],
                    621:           (word & 0x800) ? 'l' : 'w',
                    622:           scales[(word >> 9) & 3]);
                    623: 
                    624:   /* Handle the 68000 style of indexing.  */
                    625: 
                    626:   if ((word & 0x100) == 0)
                    627:     {
                    628:       print_base (basereg,
                    629:                  ((word & 0x80) ? word | 0xff00 : word & 0xff)
                    630:                  + ((basereg == -1) ? addr : 0),
                    631:                  stream);
                    632:       fprintf (stream, "%s", buf);
                    633:       return p;
                    634:     }
                    635: 
                    636:   /* Handle the generalized kind.  */
                    637:   /* First, compute the displacement to add to the base register.  */
                    638: 
                    639:   if (word & 0200)
                    640:     basereg = -2;
                    641:   if (word & 0100)
                    642:     buf[0] = 0;
                    643:   base_disp = 0;
                    644:   switch ((word >> 4) & 3)
                    645:     {
                    646:     case 2:
                    647:       base_disp = NEXTWORD (p);
                    648:       break;
                    649:     case 3:
                    650:       base_disp = NEXTLONG (p);
                    651:     }
                    652:   if (basereg == -1)
                    653:     base_disp += addr;
                    654: 
                    655:   /* Handle single-level case (not indirect) */
                    656: 
                    657:   if ((word & 7) == 0)
                    658:     {
                    659:       print_base (basereg, base_disp, stream);
                    660:       fprintf (stream, "%s", buf);
                    661:       return p;
                    662:     }
                    663: 
                    664:   /* Two level.  Compute displacement to add after indirection.  */
                    665: 
                    666:   outer_disp = 0;
                    667:   switch (word & 3)
                    668:     {
                    669:     case 2:
                    670:       outer_disp = NEXTWORD (p);
                    671:       break;
                    672:     case 3:
                    673:       outer_disp = NEXTLONG (p);
                    674:     }
                    675: 
                    676:   fprintf (stream, "%d(", outer_disp);
                    677:   print_base (basereg, base_disp, stream);
                    678: 
                    679:   /* If postindexed, print the closeparen before the index.  */
                    680:   if (word & 4)
                    681:     fprintf (stream, ")%s", buf);
                    682:   /* If preindexed, print the closeparen after the index.  */
                    683:   else
                    684:     fprintf (stream, "%s)", buf);
                    685: 
                    686:   return p;
                    687: }
                    688: 
                    689: /* Print a base register REGNO and displacement DISP, on STREAM.
                    690:    REGNO = -1 for pc, -2 for none (suppressed).  */
                    691: 
                    692: static void
                    693: print_base (regno, disp, stream)
                    694:      int regno;
                    695:      int disp;
                    696:      FILE *stream;
                    697: {
                    698:   if (regno == -2)
                    699:     fprintf (stream, "%d", disp);
                    700:   else if (regno == -1)
                    701:     fprintf (stream, "0x%x", disp);
                    702:   else
                    703:     fprintf (stream, "%d(%s)", disp, reg_names[regno]);
                    704: }
                    705: 
                    706: /* This is not part of insn printing, but it is machine-specific,
                    707:    so this is a convenient place to put it.
                    708: 
                    709:    Convert a 68881 extended float to a double.
                    710:    FROM is the address of the extended float.
                    711:    Store the double in *TO.  */
                    712: 
                    713: convert_from_68881 (from, to)
                    714:      char *from;
                    715:      double *to;
                    716: {
                    717: #ifdef HPUX_ASM
                    718:   asm ("mov.l 8(%a6),%a0");
                    719:   asm ("mov.l 12(%a6),%a1");
                    720:   asm ("fmove.x (%a0),%fp0");
                    721:   asm ("fmove.d %fp0,(%a1)");
                    722: #else /* not HPUX_ASM */
                    723: #if 0
                    724:   asm ("movl a6@(8),a0");
                    725:   asm ("movl a6@(12),a1");
                    726:   asm ("fmovex a0@,fp0");
                    727:   asm ("fmoved fp0,a1@");
                    728: #else
                    729:   /* Hand-assemble those insns since some assemblers lose
                    730:      and some have different syntax.  */
                    731:   asm (".word 020156");
                    732:   asm (".word 8");
                    733:   asm (".word 021156");
                    734:   asm (".word 12");
                    735:   asm (".long 0xf2104800");
                    736:   asm (".long 0xf2117400");
                    737: #endif
                    738: #endif /* not HPUX_ASM */
                    739: }
                    740: 
                    741: /* The converse: convert the double *FROM to an extended float
                    742:    and store where TO points.  */
                    743: 
                    744: convert_to_68881 (from, to)
                    745:      double *from;
                    746:      char *to;
                    747: {
                    748: #ifdef HPUX_ASM
                    749:   asm ("mov.l 8(%a6),%a0");
                    750:   asm ("mov.l 12(%a6),%a1");
                    751:   asm ("fmove.d (%a0),%fp0");
                    752:   asm ("fmove.x %fp0,(%a1)");
                    753: #else /* not HPUX_ASM */
                    754: #if 0
                    755:   asm ("movl a6@(8),a0");
                    756:   asm ("movl a6@(12),a1");
                    757:   asm ("fmoved a0@,fp0");
                    758:   asm ("fmovex fp0,a1@");
                    759: #else
                    760:   /* Hand-assemble those insns since some assemblers lose.  */
                    761:   asm (".word 020156");
                    762:   asm (".word 8");
                    763:   asm (".word 021156");
                    764:   asm (".word 12");
                    765:   asm (".long 0xf2105400");
                    766:   asm (".long 0xf2116800");
                    767: #endif
                    768: #endif /* not HPUX_ASM */
                    769: }

unix.superglobalmegacorp.com

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