Annotation of 43BSDReno/contrib/emacs-18.55/gdb/m68k-pinsn.c, revision 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.