Annotation of GNUtools/cctools/as/sparc.c, revision 1.1

1.1     ! root        1: /* tc-sparc.c -- Assemble for the SPARC
        !             2:    Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
        !             3: 
        !             4:    This file is part of GAS, the GNU Assembler.
        !             5: 
        !             6:    GAS is free software; you can redistribute it and/or modify
        !             7:    it under the terms of the GNU General Public License as published by
        !             8:    the Free Software Foundation; either version 2, or (at your option)
        !             9:    any later version.
        !            10: 
        !            11:    GAS is distributed in the hope that it will be useful,
        !            12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14:    GNU General Public License for more details.
        !            15: 
        !            16:    You should have received a copy of the GNU General Public License
        !            17:    along with GAS; see the file COPYING.  If not, write to
        !            18:    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
        !            19: 
        !            20: /* relocation type for internal assembler use only */
        !            21: #define SPARC_RELOC_13 (127)
        !            22: #define SPARC_RELOC_22 (126)
        !            23: 
        !            24: #define cypress 1234
        !            25: 
        !            26: #undef DEBUGINSN
        !            27: 
        !            28: #include <stdio.h>
        !            29: #include <ctype.h>
        !            30: #include "as.h"
        !            31: #include "libc.h"
        !            32: #include "md.h"
        !            33: #include "messages.h"
        !            34: #include "symbols.h"
        !            35: 
        !            36: /* careful, this file includes data *declarations* */
        !            37: #include "sparc-opcode.h"
        !            38: #include <mach-o/sparc/reloc.h>
        !            39: 
        !            40: /* From GNU ansidecl.h */
        !            41: #define PARAMS(paramlist)              paramlist
        !            42: 
        !            43: typedef long   offsetT;
        !            44: 
        !            45: /*
        !            46:  * These are the default cputype and cpusubtype for the Sparc architecture.
        !            47:  */
        !            48: const cpu_type_t md_cputype = CPU_TYPE_SPARC;
        !            49: cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_SPARC_ALL;
        !            50: 
        !            51: /* This is the byte sex for the Sparc architecture */
        !            52: const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
        !            53: 
        !            54: /* These characters start a comment anywhere on the line */
        !            55: const char md_comment_chars[] = ";!";
        !            56: 
        !            57: /* These characters only start a comment at the beginning of a line */
        !            58: const char md_line_comment_chars[] = "#";
        !            59: 
        !            60: /*
        !            61:  * These characters can be used to separate mantissa decimal digits from 
        !            62:  * exponent decimal digits in floating point numbers.
        !            63:  */
        !            64: const char md_EXP_CHARS[] = "eE";
        !            65: 
        !            66: /*
        !            67:  * The characters after a leading 0 that means this number is a floating point
        !            68:  * constant as in 0f123.456 or 0d1.234E-12 (see md_EXP_CHARS above).
        !            69:  */
        !            70: const char md_FLT_CHARS[] = "dDfF";
        !            71: 
        !            72: static void sparc_ip PARAMS ((char *));
        !            73: 
        !            74: static enum sparc_architecture current_architecture = v6;
        !            75: static int architecture_requested;
        !            76: static int warn_on_bump;
        !            77: 
        !            78: const relax_typeS md_relax_table[1];
        !            79: 
        !            80: /* handle of the OPCODE hash table */
        !            81: static struct hash_control *op_hash = NULL;
        !            82: 
        !            83: #ifdef NeXT
        !            84: static void s_proc PARAMS ((int));
        !            85: static void s_ignore PARAMS ((int));
        !            86: extern void s_seg PARAMS ((int));
        !            87: #else  NeXT
        !            88: static void s_data1 PARAMS ((void));
        !            89: static void s_seg PARAMS ((int));
        !            90: static void s_proc PARAMS ((int));
        !            91: static void s_reserve PARAMS ((int));
        !            92: static void s_common PARAMS ((int));
        !            93: #endif NeXT
        !            94: 
        !            95: const pseudo_typeS md_pseudo_table[] =
        !            96: {
        !            97: #ifdef NeXT
        !            98:   {"global", s_globl, 0},      /* Maybe we should fix compiler to use globl */
        !            99:   {"proc", s_proc, 0},         /* nop??? */
        !           100:   /* This are to handle SUN assembler files and point to existing handlers */
        !           101:   {"empty", s_ignore, 0},
        !           102:   {"ident", s_ignore, 0},
        !           103:   {"optim", s_ignore, 0},
        !           104:   {"skip", s_space, 0},
        !           105:   {"type", s_ignore, 0},
        !           106:   {"word", cons, 4},
        !           107:   {"half", cons, 2},
        !           108:   /* these are custom handlers for SUN SPARC assembler only */
        !           109: 
        !           110: #else  NeXT
        !           111:   {"seg", s_seg, 0},
        !           112:   {"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
        !           113:   {"common", s_common, 0},
        !           114:   {"global", s_globl, 0},
        !           115:   {"half", cons, 2},
        !           116:   {"optim", s_ignore, 0},
        !           117:   {"proc", s_proc, 0},
        !           118:   {"reserve", s_reserve, 0},
        !           119:   {"seg", s_seg, 0},
        !           120:   {"skip", s_space, 0},
        !           121:   {"word", cons, 4},
        !           122: #endif NeXT
        !           123:   {NULL, 0, 0},
        !           124: };
        !           125: 
        !           126: const int md_short_jump_size = 4;
        !           127: const int md_long_jump_size = 4;
        !           128: const int md_reloc_size = 12;  /* Size of relocation record */
        !           129: 
        !           130: /* This array holds the chars that always start a comment.  If the
        !           131:    pre-processor is disabled, these aren't very useful */
        !           132: const char comment_chars[] = "!";      /* JF removed '|' from comment_chars */
        !           133: 
        !           134: /* This array holds the chars that only start a comment at the beginning of
        !           135:    a line.  If the line seems to have the form '# 123 filename'
        !           136:    .line and .file directives will appear in the pre-processed output */
        !           137: /* Note that input_file.c hand checks for '#' at the beginning of the
        !           138:    first line of the input file.  This is because the compiler outputs
        !           139:    #NO_APP at the beginning of its output. */
        !           140: /* Also note that comments started like this one will always
        !           141:    work if '/' isn't otherwise defined. */
        !           142: const char line_comment_chars[] = "#";
        !           143: 
        !           144: const char line_separator_chars[] = "";
        !           145: 
        !           146: /* Chars that can be used to separate mant from exp in floating point nums */
        !           147: const char EXP_CHARS[] = "eE";
        !           148: 
        !           149: /* Chars that mean this number is a floating point constant */
        !           150: /* As in 0f12.456 */
        !           151: /* or    0d1.2345e12 */
        !           152: const char FLT_CHARS[] = "rRsSfFdDxXpP";
        !           153: 
        !           154: /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
        !           155:    changed in read.c.  Ideally it shouldn't have to know about it at all,
        !           156:    but nothing is ideal around here.  */
        !           157: 
        !           158: static unsigned char octal[256];
        !           159: #define isoctal(c)  octal[(unsigned char) (c)]
        !           160: static unsigned char toHex[256];
        !           161: 
        !           162: struct sparc_it
        !           163:   {
        !           164:     char *error;
        !           165:     unsigned long opcode;
        !           166:     struct nlist *nlistp;
        !           167:     expressionS exp;
        !           168:     int pcrel;
        !           169:     char pcrel_reloc;  /* do relocation? */
        !           170:     enum reloc_type_sparc reloc;
        !           171:   };
        !           172: 
        !           173: struct sparc_it the_insn;
        !           174: 
        !           175: #ifdef DEBUGINSN
        !           176: static void print_insn PARAMS ((struct sparc_it *insn));
        !           177: #endif
        !           178: static int getExpression PARAMS ((char *str));
        !           179: 
        !           180: static char *expr_end;
        !           181: 
        !           182: 
        !           183: /*
        !           184:  * Indicates a 'set' instruction which may require a either
        !           185:  * of the following instructions depending on the size of the 
        !           186:  * value argument:
        !           187:  *
        !           188:  * sethi %hi(value),reg
        !           189:  *
        !           190:  * or    %g0,value,reg
        !           191:  *
        !           192:  * sethi %hi(value),reg
        !           193:  * or    reg,%lo(value),reg
        !           194:  *
        !           195:  */
        !           196: static int special_case_set = 0;
        !           197: 
        !           198: /* s_proc and s_ignore are included for rudimentary 
        !           199:    compatibility with the Sun assembler only */
        !           200: 
        !           201: static void
        !           202: s_proc (ignore)
        !           203:      int ignore;
        !           204: {
        !           205:   totally_ignore_line();
        !           206: }
        !           207: 
        !           208: /* we simply ignore the rest of this statement */
        !           209: static void
        !           210: s_ignore (ignore)
        !           211:      int ignore;
        !           212: {
        !           213:   totally_ignore_line();
        !           214: }
        !           215: 
        !           216: /* This function is called once, at assembler startup time.  It should
        !           217:    set up all the tables, etc. that the MD part of the assembler will need. */
        !           218: void
        !           219: md_begin ()
        !           220: {
        !           221:   register const char *retval = NULL;
        !           222:   int lose = 0;
        !           223:   register unsigned int i = 0;
        !           224: 
        !           225:   op_hash = hash_new ();
        !           226: 
        !           227:   while (i < NUMOPCODES)
        !           228:     {
        !           229:       const char *name = sparc_opcodes[i].name;
        !           230:       retval = hash_insert (op_hash, (char *)name, (char *)&sparc_opcodes[i]);
        !           231: 
        !           232:       if(retval != NULL && *retval != '\0') {
        !           233:        fprintf (stderr, "internal error: can't hash `%s': %s\n",
        !           234:                 sparc_opcodes[i].name, retval);
        !           235:        lose = 1;
        !           236:       } do {
        !           237:        if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
        !           238:          {
        !           239:            fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
        !           240:                     sparc_opcodes[i].name, sparc_opcodes[i].args);
        !           241:            lose = 1;
        !           242:          }
        !           243:        ++i;
        !           244:       }
        !           245:       while (i < NUMOPCODES
        !           246:             && !strcmp (sparc_opcodes[i].name, name));
        !           247:     }
        !           248: 
        !           249:   if (lose)
        !           250:     as_fatal ("Broken assembler.  No assembly attempted.");
        !           251: 
        !           252:   for (i = '0'; i < '8'; ++i)
        !           253:     octal[i] = 1;
        !           254:   for (i = '0'; i <= '9'; ++i)
        !           255:     toHex[i] = i - '0';
        !           256:   for (i = 'a'; i <= 'f'; ++i)
        !           257:     toHex[i] = i + 10 - 'a';
        !           258:   for (i = 'A'; i <= 'F'; ++i)
        !           259:     toHex[i] = i + 10 - 'A';
        !           260: }
        !           261: 
        !           262: void
        !           263: md_end(
        !           264: void)
        !           265: {
        !           266:        return;
        !           267: }
        !           268: 
        !           269: void
        !           270: md_assemble (str)
        !           271:      char *str;
        !           272: {
        !           273:   char *toP;
        !           274:   int rsd;
        !           275: 
        !           276:   know (str);
        !           277:   sparc_ip (str);
        !           278: 
        !           279: #ifdef DEBUGINSN
        !           280:   print_insn(&the_insn);
        !           281: #endif
        !           282: 
        !           283:   /* See if "set" operand is absolute and small; skip sethi if so. */
        !           284:   if (special_case_set && the_insn.exp.X_seg == SEG_ABSOLUTE)
        !           285:     {
        !           286:       if (the_insn.exp.X_add_number >= -(1 << 12)
        !           287:          && the_insn.exp.X_add_number < (1 << 12))
        !           288:        {
        !           289:          the_insn.opcode = 0x80102000  /* or %g0,imm,... */
        !           290:            | (the_insn.opcode & 0x3E000000)    /* dest reg */
        !           291:            | (the_insn.exp.X_add_number & 0x1FFF);     /* imm */
        !           292:          special_case_set = 0; /* No longer special */
        !           293:          the_insn.reloc = SPARC_RELOC_NONE;    /* No longer relocated */
        !           294:        }
        !           295:     }
        !           296: 
        !           297:   toP = frag_more (4);
        !           298:   /* put out the opcode */
        !           299:   md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
        !           300: 
        !           301:   /* put out the symbol-dependent stuff */
        !           302:   if (the_insn.reloc != SPARC_RELOC_NONE)
        !           303:     {
        !           304:        fix_new(frag_now,
        !           305:                (toP - frag_now->fr_literal),
        !           306:                4,
        !           307:                the_insn.exp.X_add_symbol,
        !           308:                the_insn.exp.X_subtract_symbol,
        !           309:                the_insn.exp.X_add_number,
        !           310:                the_insn.pcrel,
        !           311:                the_insn.pcrel_reloc,   /* 1 for local labels due to scatter loading */
        !           312:                the_insn.reloc);
        !           313:     }
        !           314: 
        !           315:   if (special_case_set) {
        !           316:     special_case_set = 0;
        !           317:     assert (the_insn.reloc == SPARC_RELOC_HI22);
        !           318:     /* See if "set" operand has no low-order bits; skip OR if so. */
        !           319:     if ((the_insn.exp.X_seg == SEG_ABSOLUTE) && 
        !           320:        ((the_insn.exp.X_add_number & 0x3FF) == 0))
        !           321:       return;
        !           322: 
        !           323:     toP = frag_more (4);
        !           324:     rsd = (the_insn.opcode >> 25) & 0x1f;
        !           325:     the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
        !           326:     md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
        !           327:     the_insn.pcrel_reloc = 0;
        !           328: 
        !           329:     fix_new(frag_now,
        !           330:        (toP - frag_now->fr_literal),
        !           331:        4,
        !           332:        the_insn.exp.X_add_symbol,
        !           333:        the_insn.exp.X_subtract_symbol,
        !           334:        the_insn.exp.X_add_number,
        !           335:        the_insn.pcrel,
        !           336:        the_insn.pcrel_reloc,
        !           337:        SPARC_RELOC_LO10);
        !           338:     return;
        !           339:   }
        !           340: }
        !           341: 
        !           342: static void
        !           343: sparc_ip (str)
        !           344:      char *str;
        !           345: {
        !           346:   char *error_message = "";
        !           347:   char *s;
        !           348:   const char *args;
        !           349:   char c;
        !           350:   struct sparc_opcode *insn;
        !           351:   char *argsStart;
        !           352:   unsigned long opcode;
        !           353:   unsigned int mask = 0;
        !           354:   int match = 0;
        !           355:   int comma = 0;
        !           356:   long immediate_max = 0;
        !           357: 
        !           358:   for (s = str; islower (*s) || (*s >= '0' && *s <= '3'); ++s)
        !           359:     ;
        !           360:   switch (*s)
        !           361:     {
        !           362: 
        !           363:     case '\0':
        !           364:       break;
        !           365: 
        !           366:     case ',':
        !           367:       comma = 1;
        !           368: 
        !           369:       /*FALLTHROUGH */
        !           370: 
        !           371:     case ' ':
        !           372:       *s++ = '\0';
        !           373:       break;
        !           374: 
        !           375:     default:
        !           376:       as_bad ("Unknown opcode: `%s'", str);
        !           377:       exit (1);
        !           378:     }
        !           379:   if ((insn = (struct sparc_opcode *) hash_find (op_hash, str)) == NULL)
        !           380:     {
        !           381:       as_bad ("Unknown opcode: `%s'", str);
        !           382:       return;
        !           383:     }
        !           384:   if (comma)
        !           385:     {
        !           386:       *--s = ',';
        !           387:     }
        !           388:   argsStart = s;
        !           389:   for (;;)
        !           390:     {
        !           391:       opcode = insn->match;
        !           392:       memset (&the_insn, '\0', sizeof (the_insn));
        !           393:       the_insn.reloc = SPARC_RELOC_NONE;
        !           394:       the_insn.pcrel_reloc = 1; /* default, reloc, for scatter loading */
        !           395: 
        !           396:       /*
        !           397:        * Build the opcode, checking as we go to make
        !           398:        * sure that the operands match
        !           399:        */
        !           400:       for (args = insn->args;; ++args)
        !           401:        {
        !           402:          switch (*args)
        !           403:            {
        !           404:            case 'M':
        !           405:            case 'm':
        !           406:              if (strncmp (s, "%asr", 4) == 0)
        !           407:                {
        !           408:                  s += 4;
        !           409: 
        !           410:                  if (isdigit (*s))
        !           411:                    {
        !           412:                      long num = 0;
        !           413: 
        !           414:                      while (isdigit (*s))
        !           415:                        {
        !           416:                          num = num * 10 + *s - '0';
        !           417:                          ++s;
        !           418:                        }
        !           419: 
        !           420:                      if (num < 16 || 31 < num)
        !           421:                        {
        !           422:                          error_message = ": asr number must be between 15 and 31";
        !           423:                          goto error;
        !           424:                        }       /* out of range */
        !           425: 
        !           426:                      opcode |= (*args == 'M' ? RS1 (num) : RD (num));
        !           427:                      continue;
        !           428:                    }
        !           429:                  else
        !           430:                    {
        !           431:                      error_message = ": expecting %asrN";
        !           432:                      goto error;
        !           433:                    }           /* if %asr followed by a number. */
        !           434: 
        !           435:                }               /* if %asr */
        !           436:              break;
        !           437: 
        !           438: 
        !           439:            case '\0':          /* end of args */
        !           440:              if (*s == '\0')
        !           441:                {
        !           442:                  match = 1;
        !           443:                }
        !           444:              break;
        !           445: 
        !           446:            case '+':
        !           447:              if (*s == '+')
        !           448:                {
        !           449:                  ++s;
        !           450:                  continue;
        !           451:                }
        !           452:              if (*s == '-')
        !           453:                {
        !           454:                  continue;
        !           455:                }
        !           456:              break;
        !           457: 
        !           458:            case '[':           /* these must match exactly */
        !           459:            case ']':
        !           460:            case ',':
        !           461:            case ' ':
        !           462:              if (*s++ == *args)
        !           463:                continue;
        !           464:              break;
        !           465: 
        !           466:            case '#':           /* must be at least one digit */
        !           467:              if (isdigit (*s++))
        !           468:                {
        !           469:                  while (isdigit (*s))
        !           470:                    {
        !           471:                      ++s;
        !           472:                    }
        !           473:                  continue;
        !           474:                }
        !           475:              break;
        !           476: 
        !           477:            case 'C':           /* coprocessor state register */
        !           478:              if (strncmp (s, "%csr", 4) == 0)
        !           479:                {
        !           480:                  s += 4;
        !           481:                  continue;
        !           482:                }
        !           483:              break;
        !           484: 
        !           485:            case 'b':           /* next operand is a coprocessor register */
        !           486:            case 'c':
        !           487:            case 'D':
        !           488:              if (*s++ == '%' && *s++ == 'c' && isdigit (*s))
        !           489:                {
        !           490:                  mask = *s++;
        !           491:                  if (isdigit (*s))
        !           492:                    {
        !           493:                      mask = 10 * (mask - '0') + (*s++ - '0');
        !           494:                      if (mask >= 32)
        !           495:                        {
        !           496:                          break;
        !           497:                        }
        !           498:                    }
        !           499:                  else
        !           500:                    {
        !           501:                      mask -= '0';
        !           502:                    }
        !           503:                  switch (*args)
        !           504:                    {
        !           505: 
        !           506:                    case 'b':
        !           507:                      opcode |= mask << 14;
        !           508:                      continue;
        !           509: 
        !           510:                    case 'c':
        !           511:                      opcode |= mask;
        !           512:                      continue;
        !           513: 
        !           514:                    case 'D':
        !           515:                      opcode |= mask << 25;
        !           516:                      continue;
        !           517:                    }
        !           518:                }
        !           519:              break;
        !           520: 
        !           521:            case 'r':           /* next operand must be a register */
        !           522:            case 'u':
        !           523:            case '1':
        !           524:            case '2':
        !           525:            case 'd':
        !           526:              if (*s++ == '%')
        !           527:                {
        !           528:                  switch (c = *s++)
        !           529:                    {
        !           530: 
        !           531:                    case 'f':   /* frame pointer */
        !           532:                      if (*s++ == 'p')
        !           533:                        {
        !           534:                          mask = 0x1e;
        !           535:                          break;
        !           536:                        }
        !           537:                      error_message = ": register not fp";
        !           538:                      goto error;
        !           539: 
        !           540:                    case 'g':   /* global register */
        !           541:                      if (isoctal (c = *s++))
        !           542:                        {
        !           543:                          mask = c - '0';
        !           544:                          break;
        !           545:                        }
        !           546:                      error_message = ": invalid global register";
        !           547:                      goto error;
        !           548: 
        !           549:                    case 'i':   /* in register */
        !           550:                      if (isoctal (c = *s++))
        !           551:                        {
        !           552:                          mask = c - '0' + 24;
        !           553:                          break;
        !           554:                        }
        !           555:                      error_message = ": invalid in register";
        !           556:                      goto error;
        !           557: 
        !           558:                    case 'l':   /* local register */
        !           559:                      if (isoctal (c = *s++))
        !           560:                        {
        !           561:                          mask = (c - '0' + 16);
        !           562:                          break;
        !           563:                        }
        !           564:                      error_message = ": invalid local register";
        !           565:                      goto error;
        !           566: 
        !           567:                    case 'o':   /* out register */
        !           568:                      if (isoctal (c = *s++))
        !           569:                        {
        !           570:                          mask = (c - '0' + 8);
        !           571:                          break;
        !           572:                        }
        !           573:                      error_message = ": invalid out register";
        !           574:                      goto error;
        !           575: 
        !           576:                    case 's':   /* stack pointer */
        !           577:                      if (*s++ == 'p')
        !           578:                        {
        !           579:                          mask = 0xe;
        !           580:                          break;
        !           581:                        }
        !           582:                      error_message = ": register is not sp";
        !           583:                      goto error;
        !           584: 
        !           585:                    case 'r':   /* any register */
        !           586:                      if (!isdigit (c = *s++))
        !           587:                        {
        !           588:                          error_message = ": invalid register";
        !           589:                          goto error;
        !           590:                        }
        !           591:                      /* FALLTHROUGH */
        !           592:                    case '0':
        !           593:                    case '1':
        !           594:                    case '2':
        !           595:                    case '3':
        !           596:                    case '4':
        !           597:                    case '5':
        !           598:                    case '6':
        !           599:                    case '7':
        !           600:                    case '8':
        !           601:                    case '9':
        !           602:                      if (isdigit (*s))
        !           603:                        {
        !           604:                          if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
        !           605:                            {
        !           606:                              error_message = ": register # out of range";
        !           607:                              goto error;
        !           608:                            }
        !           609:                        }
        !           610:                      else
        !           611:                        {
        !           612:                          c -= '0';
        !           613:                        }
        !           614:                      mask = c;
        !           615:                      break;
        !           616: 
        !           617:                    default:
        !           618:                      error_message = ": invalid resgiter #";
        !           619:                      goto error;
        !           620:                    }
        !           621:                 /*
        !           622:                 * Got the register, now figure out where
        !           623:                 * it goes in the opcode.
        !           624:                 */
        !           625:                  switch (*args)
        !           626:                    {
        !           627: 
        !           628:                    case '1':
        !           629:                      opcode |= mask << 14;
        !           630:                      continue;
        !           631: 
        !           632:                    case '2':
        !           633:                      opcode |= mask;
        !           634:                      continue;
        !           635: 
        !           636:                    case 'd':
        !           637:                      opcode |= mask << 25;
        !           638:                      continue;
        !           639: 
        !           640:                    case 'r':
        !           641:                      opcode |= (mask << 25) | (mask << 14);
        !           642:                      continue;
        !           643: 
        !           644:                    case 'u':
        !           645:                      opcode |= (mask << 25) | mask;
        !           646:                      continue;
        !           647:                    }
        !           648:                }
        !           649:              break;
        !           650: 
        !           651:            case 'e':           /* next operand is a floating point register */
        !           652:            case 'v':
        !           653:            case 'V':
        !           654: 
        !           655:            case 'f':
        !           656:            case 'B':
        !           657:            case 'R':
        !           658: 
        !           659:            case 'g':
        !           660:            case 'H':
        !           661:            case 'J':
        !           662:              {
        !           663:                char format;
        !           664: 
        !           665:                if (*s++ == '%'
        !           666:                    && ((format = *s) == 'f')
        !           667:                    && isdigit (*++s))
        !           668:                  {
        !           669:                    for (mask = 0; isdigit (*s); ++s)
        !           670:                      {
        !           671:                        mask = 10 * mask + (*s - '0');
        !           672:                      }         /* read the number */
        !           673: 
        !           674:                    if ((*args == 'v'
        !           675:                         || *args == 'B'
        !           676:                         || *args == 'H')
        !           677:                        && (mask & 1))
        !           678:                      {
        !           679:                        break;
        !           680:                      }         /* register must be even numbered */
        !           681: 
        !           682:                    if ((*args == 'V'
        !           683:                         || *args == 'R'
        !           684:                         || *args == 'J')
        !           685:                        && (mask & 3))
        !           686:                      {
        !           687:                        break;
        !           688:                      }         /* register must be multiple of 4 */
        !           689: 
        !           690:                    if (mask >= 32)
        !           691:                      {
        !           692:                        error_message = ": There are only 32 f registers; [0-31]";
        !           693:                        goto error;
        !           694:                      } /* on error */
        !           695:                  }
        !           696:                else
        !           697:                  {
        !           698:                    break;
        !           699:                  }     /* if not an 'f' register. */
        !           700: 
        !           701:                switch (*args)
        !           702:                  {
        !           703: 
        !           704:                  case 'v':
        !           705:                  case 'V':
        !           706:                  case 'e':
        !           707:                    opcode |= RS1 (mask);
        !           708:                    continue;
        !           709: 
        !           710: 
        !           711:                  case 'f':
        !           712:                  case 'B':
        !           713:                  case 'R':
        !           714:                    opcode |= RS2 (mask);
        !           715:                    continue;
        !           716: 
        !           717:                  case 'g':
        !           718:                  case 'H':
        !           719:                  case 'J':
        !           720:                    opcode |= RD (mask);
        !           721:                    continue;
        !           722:                  }             /* pack it in. */
        !           723: 
        !           724:                know (0);
        !           725:                break;
        !           726:              }                 /* float arg */
        !           727: 
        !           728:            case 'F':
        !           729:              if (strncmp (s, "%fsr", 4) == 0)
        !           730:                {
        !           731:                  s += 4;
        !           732:                  continue;
        !           733:                }
        !           734:              break;
        !           735: 
        !           736:            case 'h':           /* high 22 bits */
        !           737:              the_insn.reloc = SPARC_RELOC_HI22;
        !           738:              goto immediate;
        !           739: 
        !           740:            case 'l':           /* 22 bit PC relative immediate */
        !           741:              the_insn.reloc = SPARC_RELOC_WDISP22;
        !           742:              the_insn.pcrel = 1;
        !           743:              goto immediate;
        !           744: 
        !           745:            case 'L':           /* 30 bit immediate for call insn */
        !           746:              the_insn.reloc = SPARC_RELOC_WDISP30;
        !           747:              the_insn.pcrel = 1;
        !           748:              goto immediate;
        !           749: 
        !           750:            case 'n':           /* 22 bit immediate */
        !           751:              the_insn.reloc = SPARC_RELOC_22;
        !           752:              goto immediate;
        !           753: 
        !           754:            case 'i':           /* 13 bit immediate */
        !           755:              /* What's the difference between base13 and 13?  
        !           756:                 13-bit immediate and 13-bit immediate+register */
        !           757:              the_insn.reloc = SPARC_RELOC_13;
        !           758:              immediate_max = 0x1FFF;
        !           759: 
        !           760:              /*FALLTHROUGH */
        !           761: 
        !           762:            immediate:
        !           763:              if (*s == ' ')
        !           764:                s++;
        !           765:              if (*s == '%')
        !           766:                {
        !           767:                  if ((c = s[1]) == 'h' && s[2] == 'i')
        !           768:                    {
        !           769:                      the_insn.reloc = SPARC_RELOC_HI22;
        !           770:                      s += 3;
        !           771:                    }
        !           772:                  else if (c == 'l' && s[2] == 'o')
        !           773:                    {
        !           774:                      the_insn.reloc = SPARC_RELOC_LO10;
        !           775:                      s += 3;
        !           776:                    }
        !           777:                  else
        !           778:                    break;
        !           779:                }
        !           780:              /* Note that if the getExpression() fails, we will still
        !           781:                 have created U entries in the symbol table for the
        !           782:                 'symbols' in the input string.  Try not to create U
        !           783:                 symbols for registers, etc.  */
        !           784:              {
        !           785:                /* This stuff checks to see if the expression ends in
        !           786:                   +%reg.  If it does, it removes the register from
        !           787:                   the expression, and re-sets 's' to point to the
        !           788:                   right place.  */
        !           789: 
        !           790:                char *s1;
        !           791: 
        !           792:                for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++);
        !           793: 
        !           794:                if (s1 != s && isdigit (s1[-1]))
        !           795:                  {
        !           796:                    if (s1[-2] == '%' && s1[-3] == '+')
        !           797:                      {
        !           798:                        s1 -= 3;
        !           799:                        *s1 = '\0';
        !           800:                        (void) getExpression (s);
        !           801:                        *s1 = '+';
        !           802:                        s = s1;
        !           803:                        continue;
        !           804:                      }
        !           805:                    else if (strchr ("goli0123456789", 
        !           806:                                     s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
        !           807:                      {
        !           808:                        s1 -= 4;
        !           809:                        *s1 = '\0';
        !           810:                        (void) getExpression (s);
        !           811:                        *s1 = '+';
        !           812:                        s = s1;
        !           813:                        continue;
        !           814:                      }
        !           815:                  }
        !           816:              }
        !           817:              (void) getExpression (s);
        !           818:              s = expr_end;
        !           819:        /* The Next linker has the ability to scatter blocks of sections between
        !           820:         * labels.  This requires that branches to labels that survive to the
        !           821:         * link phase be relocatable.  These labels are those that are not L*
        !           822:         */
        !           823:             if (the_insn.exp.X_add_symbol != NULL && !flagseen['L']
        !           824:                && the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name[0] == 'L') {
        !           825:                /* local symbol which will be thrown away.  Don't bother
        !           826:                 * to reloc it.
        !           827:                 */
        !           828:                the_insn.pcrel_reloc = 0;
        !           829:             }
        !           830: 
        !           831:              if ((the_insn.exp.X_seg == SEG_ABSOLUTE || 
        !           832:                   the_insn.exp.X_seg == SEG_BIG)
        !           833:                  && the_insn.exp.X_add_symbol == 0)
        !           834:                {
        !           835: 
        !           836:                  /* Check for invalid constant values.  Don't warn if
        !           837:                     constant was inside %hi or %lo, since these
        !           838:                     truncate the constant to fit.  */
        !           839:                  if (immediate_max != 0
        !           840:                      && the_insn.reloc != SPARC_RELOC_LO10
        !           841:                      && the_insn.reloc != SPARC_RELOC_HI22
        !           842:                      && (the_insn.exp.X_add_number > immediate_max
        !           843:                          || the_insn.exp.X_add_number < ~immediate_max))
        !           844:                    as_bad ("constant value must be between %ld and %ld",
        !           845:                            ~immediate_max, immediate_max);
        !           846: 
        !           847:                  if ((the_insn.reloc == SPARC_RELOC_WDISP22 ||
        !           848:                      the_insn.reloc == SPARC_RELOC_WDISP30) &&
        !           849:                      the_insn.exp.X_add_number & 3) 
        !           850:                    as_bad ("displacement is not long aligned");
        !           851: 
        !           852:                  /* plug absolutes directly into opcode */
        !           853: 
        !           854:                  switch(the_insn.reloc) {
        !           855:                  case SPARC_RELOC_13:
        !           856:                    if (the_insn.exp.X_seg == SEG_BIG)
        !           857:                      opcode |= (*(int *) generic_bignum) & 0x1fff;
        !           858:                    else
        !           859:                      opcode |= the_insn.exp.X_add_number & 0x1fff;
        !           860:                    the_insn.reloc = SPARC_RELOC_NONE;
        !           861:                    break;
        !           862:                  case SPARC_RELOC_22:
        !           863:                    if (the_insn.exp.X_seg == SEG_BIG)
        !           864:                      opcode |= (*(int *) generic_bignum) & 0x3fffff;
        !           865:                    else
        !           866:                      opcode |= the_insn.exp.X_add_number & 0x3fffff;
        !           867:                    the_insn.reloc = SPARC_RELOC_NONE;
        !           868:                    break;
        !           869:                  case SPARC_RELOC_HI22:
        !           870:                    /* extract upper 22 bits from constant */
        !           871:                    opcode |= (the_insn.exp.X_add_number >> 10) & 0x3fffff;
        !           872:                    the_insn.reloc = SPARC_RELOC_NONE;
        !           873:                    break;
        !           874:                  case SPARC_RELOC_LO10:
        !           875:                    opcode |= the_insn.exp.X_add_number & 0x3ff;
        !           876:                    break;
        !           877:              
        !           878:                    /* the PC relative displacements are plugged in
        !           879:                       if the argument is absolute, but retain
        !           880:                       relocatability */
        !           881:                  case SPARC_RELOC_WDISP22:
        !           882:                    opcode |= (the_insn.exp.X_add_number >> 2) & 0x3fffff;
        !           883:                    break;
        !           884:                  case SPARC_RELOC_WDISP30:
        !           885:                    opcode |= (the_insn.exp.X_add_number >> 2) & 0x3fffffff;
        !           886:                    break;
        !           887:                  default:
        !           888:                    printf("Unknown reloc entry\n");
        !           889:                  }
        !           890:                }
        !           891: 
        !           892:              /* Reset to prevent extraneous range check.  */
        !           893:              immediate_max = 0;
        !           894: 
        !           895:              continue;
        !           896: 
        !           897:            case 'a':
        !           898:              if (*s++ == 'a')
        !           899:                {
        !           900:                  opcode |= ANNUL;
        !           901:                  continue;
        !           902:                }
        !           903:              break;
        !           904: 
        !           905:            case 'A':
        !           906:              {
        !           907:                char *push = input_line_pointer;
        !           908:                expressionS e;
        !           909: 
        !           910:                input_line_pointer = s;
        !           911: 
        !           912:                expression (&e);
        !           913: 
        !           914:                if (e.X_seg == SEG_ABSOLUTE)
        !           915:                  {
        !           916:                    opcode |= e.X_add_number << 5;
        !           917:                    s = input_line_pointer;
        !           918:                    input_line_pointer = push;
        !           919:                    continue;
        !           920:                  }             /* if absolute */
        !           921: 
        !           922:                break;
        !           923:              }                 /* alternate space */
        !           924: 
        !           925:            case 'p':
        !           926:              if (strncmp (s, "%psr", 4) == 0)
        !           927:                {
        !           928:                  s += 4;
        !           929:                  continue;
        !           930:                }
        !           931:              break;
        !           932: 
        !           933:            case 'q':           /* floating point queue */
        !           934:              if (strncmp (s, "%fq", 3) == 0)
        !           935:                {
        !           936:                  s += 3;
        !           937:                  continue;
        !           938:                }
        !           939:              break;
        !           940: 
        !           941:            case 'Q':           /* coprocessor queue */
        !           942:              if (strncmp (s, "%cq", 3) == 0)
        !           943:                {
        !           944:                  s += 3;
        !           945:                  continue;
        !           946:                }
        !           947:              break;
        !           948: 
        !           949:            case 'S':
        !           950:              if (strcmp (str, "set") == 0)
        !           951:                {
        !           952:                  special_case_set = 1;
        !           953:                  continue;
        !           954:                }
        !           955:              break;
        !           956: 
        !           957: 
        !           958:            case 't':
        !           959:              if (strncmp (s, "%tbr", 4) != 0)
        !           960:                break;
        !           961:              s += 4;
        !           962:              continue;
        !           963: 
        !           964:            case 'w':
        !           965:              if (strncmp (s, "%wim", 4) != 0)
        !           966:                break;
        !           967:              s += 4;
        !           968:              continue;
        !           969: 
        !           970:            case 'y':
        !           971:              if (strncmp (s, "%y", 2) != 0)
        !           972:                break;
        !           973:              s += 2;
        !           974:              continue;
        !           975: 
        !           976:            default:
        !           977:              as_fatal ("failed sanity check.");
        !           978:            }                   /* switch on arg code */
        !           979:          break;
        !           980:        }                       /* for each arg that we expect */
        !           981:     error:
        !           982:       if (match == 0)
        !           983:        {
        !           984:          /* Args don't match. */
        !           985:          if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
        !           986:              && !strcmp (insn->name, insn[1].name))
        !           987:            {
        !           988:              ++insn;
        !           989:              s = argsStart;
        !           990:              continue;
        !           991:            }
        !           992:          else
        !           993:            {
        !           994:              as_bad ("Illegal operands%s", error_message);
        !           995:              return;
        !           996:            }
        !           997:        }
        !           998:       else
        !           999:        {
        !          1000:          if (insn->architecture > current_architecture)
        !          1001:            {
        !          1002:              if ((!architecture_requested || warn_on_bump)
        !          1003:                  &&
        !          1004:                  1
        !          1005:                )
        !          1006:                {
        !          1007:                  if (warn_on_bump)
        !          1008:                    {
        !          1009:                      as_warn ("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
        !          1010:                               architecture_pname[current_architecture],
        !          1011:                               architecture_pname[insn->architecture],
        !          1012:                               str);
        !          1013:                    }           /* if warning */
        !          1014: 
        !          1015:                  current_architecture = insn->architecture;
        !          1016:                }
        !          1017:              else
        !          1018:                {
        !          1019:                  as_bad ("architecture mismatch on \"%s\" (\"%s\").  current architecture is \"%s\"",
        !          1020:                          str,
        !          1021:                          architecture_pname[insn->architecture],
        !          1022:                          architecture_pname[current_architecture]);
        !          1023:                  return;
        !          1024:                }               /* if bump ok else error */
        !          1025:            }                   /* if architecture higher */
        !          1026:        }                       /* if no match */
        !          1027: 
        !          1028:       break;
        !          1029:     }                          /* forever looking for a match */
        !          1030: 
        !          1031:   the_insn.opcode = opcode;
        !          1032: }
        !          1033: 
        !          1034: static int
        !          1035: getExpression (str)
        !          1036:      char *str;
        !          1037: {
        !          1038:   char *save_in;
        !          1039:   segT seg;
        !          1040: 
        !          1041:   save_in = input_line_pointer;
        !          1042:   input_line_pointer = str;
        !          1043:   seg = expression (&the_insn.exp);
        !          1044: 
        !          1045:   if (seg != SEG_ABSOLUTE
        !          1046:       && seg != SEG_SECT
        !          1047:       && seg != SEG_DIFFSECT
        !          1048:       && seg != SEG_UNKNOWN
        !          1049:       && seg != SEG_NONE
        !          1050:       && seg != SEG_BIG) {
        !          1051:     the_insn.error = "bad segment";
        !          1052:     expr_end = input_line_pointer;
        !          1053:     input_line_pointer = save_in;
        !          1054:     return 1;
        !          1055:   }
        !          1056:   expr_end = input_line_pointer;
        !          1057:   input_line_pointer = save_in;
        !          1058:   return 0;
        !          1059: }                              /* getExpression() */
        !          1060: 
        !          1061: 
        !          1062: /*
        !          1063:   This is identical to the md_atof in m68k.c.  I think this is right,
        !          1064:   but I'm not sure.
        !          1065: 
        !          1066:   Turn a string in input_line_pointer into a floating point constant of type
        !          1067:   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
        !          1068:   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
        !          1069:   */
        !          1070: 
        !          1071: /* Equal to MAX_PRECISION in atof-ieee.c */
        !          1072: #define MAX_LITTLENUMS 6
        !          1073: 
        !          1074: char *
        !          1075: md_atof (type, litP, sizeP)
        !          1076:      char type;
        !          1077:      char *litP;
        !          1078:      int *sizeP;
        !          1079: {
        !          1080:   int prec;
        !          1081:   LITTLENUM_TYPE words[MAX_LITTLENUMS];
        !          1082:   LITTLENUM_TYPE *wordP;
        !          1083:   char *t;
        !          1084:   char *atof_ieee ();
        !          1085: 
        !          1086:   switch (type)
        !          1087:     {
        !          1088:     case 'f':
        !          1089:     case 'F':
        !          1090:     case 's':
        !          1091:     case 'S':
        !          1092:       prec = 2;
        !          1093:       break;
        !          1094: 
        !          1095:     case 'd':
        !          1096:     case 'D':
        !          1097:     case 'r':
        !          1098:     case 'R':
        !          1099:       prec = 4;
        !          1100:       break;
        !          1101: 
        !          1102:     case 'x':
        !          1103:     case 'X':
        !          1104:       prec = 6;
        !          1105:       break;
        !          1106: 
        !          1107:     case 'p':
        !          1108:     case 'P':
        !          1109:       prec = 6;
        !          1110:       break;
        !          1111: 
        !          1112:     default:
        !          1113:       *sizeP = 0;
        !          1114:       return "Bad call to MD_ATOF()";
        !          1115:     }
        !          1116:   t = atof_ieee (input_line_pointer, type, words);
        !          1117:   if (t)
        !          1118:     input_line_pointer = t;
        !          1119:   *sizeP = prec * sizeof (LITTLENUM_TYPE);
        !          1120:   for (wordP = words; prec--;)
        !          1121:     {
        !          1122:       md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
        !          1123:       litP += sizeof (LITTLENUM_TYPE);
        !          1124:     }
        !          1125:   return "";
        !          1126: }
        !          1127: 
        !          1128: /*
        !          1129:  * Write out big-endian.
        !          1130:  */
        !          1131: void
        !          1132: md_number_to_chars (buf, val, n)
        !          1133:      char *buf;
        !          1134:      long val;
        !          1135:      int n;
        !          1136: {
        !          1137:   // sigh, all architectures do this..,
        !          1138:   switch(n) {
        !          1139:     
        !          1140:   case 4:
        !          1141:     *buf++ = val >> 24;
        !          1142:     *buf++ = val >> 16;
        !          1143:   case 2:
        !          1144:     *buf++ = val >> 8;
        !          1145:   case 1:
        !          1146:     *buf = val;
        !          1147:     break;
        !          1148:     
        !          1149:   default:
        !          1150:     abort();
        !          1151:   }
        !          1152: }
        !          1153: 
        !          1154: /* Apply a fixS to the frags, now that we know the value it ought to
        !          1155:    hold. */
        !          1156: 
        !          1157: 
        !          1158: void
        !          1159: md_number_to_imm(unsigned char *buf, long val, int size, fixS *fixP, int nsect)
        !          1160: {
        !          1161: 
        !          1162:   /* handle the most common case quickly */
        !          1163:   if ((fixP->fx_r_type == NO_RELOC) ||
        !          1164:       (fixP->fx_r_type == SPARC_RELOC_NONE) ||
        !          1165:       (fixP->fx_r_type == SPARC_RELOC_VANILLA)) {
        !          1166:     switch(size){
        !          1167:     case 4:
        !          1168:       *buf++ = val >> 24;
        !          1169:       *buf++ = val >> 16;
        !          1170:     case 2:
        !          1171:       *buf++ = val >> 8;
        !          1172:     case 1:
        !          1173:       *buf = val;
        !          1174:       break;
        !          1175:     default:
        !          1176:       abort();
        !          1177:     }
        !          1178:     return;
        !          1179:   }
        !          1180: 
        !          1181:   switch (fixP->fx_r_type) {
        !          1182:   case SPARC_RELOC_WDISP30:
        !          1183:     val = (val >> 2) + 1;      /* adjust for word displacement */
        !          1184:     buf[0] |= (val >> 24) & 0x3f;
        !          1185:     buf[1] = (val >> 16);
        !          1186:     buf[2] = val >> 8;
        !          1187:     buf[3] = val;
        !          1188:     break;
        !          1189:   case SPARC_RELOC_WDISP22:
        !          1190:     val = (val >>= 2) + 1;
        !          1191:     buf[1] |= (val >> 16) & 0x3f;
        !          1192:     buf[2] = val >> 8;
        !          1193:     buf[3] = val;
        !          1194:     break;
        !          1195:   case SPARC_RELOC_HI22:
        !          1196:     buf[1] |= (val >> 26) & 0x3f;
        !          1197:     buf[2] = val >> 18;
        !          1198:     buf[3] = val >> 10;
        !          1199:     break;
        !          1200:   case SPARC_RELOC_LO10:
        !          1201:     buf[2] |= (val >> 8) & 0x03;
        !          1202:     buf[3] = val;
        !          1203:     break;
        !          1204: 
        !          1205:   /* special cases that need to be handled internally by the as */
        !          1206:   case SPARC_RELOC_22:
        !          1207:     if (!fixP->fx_addsy) {
        !          1208:       if (val & ~0x003fffff) {
        !          1209:        as_bad ("relocation overflow");
        !          1210:       }                        /* on overflow */
        !          1211:       buf[1] |= (val >> 16) & 0x3f;
        !          1212:       buf[2] = val >> 8;
        !          1213:       buf[3] = val & 0xff;
        !          1214:     } else
        !          1215:       as_bad ("Undefined symbolic 22-bit immediate reference: %s", 
        !          1216:              fixP->fx_addsy->sy_name);
        !          1217:     break;
        !          1218:   case SPARC_RELOC_13:
        !          1219:     if (!fixP->fx_addsy) {
        !          1220:       if (((val > 0) && (val & ~(offsetT)0x00001fff))
        !          1221:          || ((val < 0) && (~(val - 1) & ~(offsetT)0x00001fff))) {
        !          1222:        as_bad ("relocation overflow");
        !          1223:       }
        !          1224:       buf[2] |= (val >> 8) & 0x1f;
        !          1225:       buf[3] = val;
        !          1226:     } else
        !          1227:       as_bad ("Undefined symbolic 13-bit immediate reference: %s", 
        !          1228:              fixP->fx_addsy->sy_name);
        !          1229:     break;
        !          1230:   case SPARC_RELOC_NONE:
        !          1231:   default:
        !          1232:     as_bad ("bad or unhandled relocation type: 0x%02x", fixP->fx_r_type);
        !          1233:     break;
        !          1234:   }
        !          1235: }
        !          1236: 
        !          1237: 
        !          1238: /*
        !          1239:  * md_parse_option
        !          1240:  *     Invocation line includes a switch not recognized by the base assembler.
        !          1241:  *     See if it's a processor-specific option.  These are:
        !          1242:  *
        !          1243:  *     -bump
        !          1244:  *             Warn on architecture bumps.  See also -A.
        !          1245:  *
        !          1246:  *     -Av6, -Av7, -Av8, -Asparclite
        !          1247:  *             Select the architecture.  Instructions or features not
        !          1248:  *             supported by the selected architecture cause fatal errors.
        !          1249:  *
        !          1250:  *             The default is to start at v6, and bump the architecture up
        !          1251:  *             whenever an instruction is seen at a higher level.
        !          1252:  *
        !          1253:  *             If -bump is specified, a warning is printing when bumping to
        !          1254:  *             higher levels.
        !          1255:  *
        !          1256:  *             If an architecture is specified, all instructions must match
        !          1257:  *             that architecture.  Any higher level instructions are flagged
        !          1258:  *             as errors.
        !          1259:  *
        !          1260:  *             if both an architecture and -bump are specified, the
        !          1261:  *             architecture starts at the specified level, but bumps are
        !          1262:  *             warnings.
        !          1263:  *
        !          1264:  */
        !          1265: 
        !          1266: int 
        !          1267: md_parse_option (argP, cntP, vecP)
        !          1268:      char **argP;
        !          1269:      int *cntP;
        !          1270:      char ***vecP;
        !          1271: {
        !          1272:   char *p;
        !          1273:   const char **arch;
        !          1274: 
        !          1275:   if (!strcmp (*argP, "bump"))
        !          1276:     {
        !          1277:       warn_on_bump = 1;
        !          1278:     }
        !          1279:   else if (**argP == 'A')
        !          1280:     {
        !          1281:       p = (*argP) + 1;
        !          1282: 
        !          1283:       for (arch = architecture_pname; *arch != NULL; ++arch)
        !          1284:        {
        !          1285:          if (strcmp (p, *arch) == 0)
        !          1286:            {
        !          1287:              break;
        !          1288:            }                   /* found a match */
        !          1289:        }                       /* walk the pname table */
        !          1290: 
        !          1291:       if (*arch == NULL)
        !          1292:        {
        !          1293:          as_bad ("unknown architecture: %s", p);
        !          1294:        }
        !          1295:       else
        !          1296:        {
        !          1297:          current_architecture = (enum sparc_architecture) (arch - architecture_pname);
        !          1298:          architecture_requested = 1;
        !          1299:        }
        !          1300:     }
        !          1301: #ifndef NeXT
        !          1302: #ifdef OBJ_ELF
        !          1303:   else if (**argP == 'V')
        !          1304:     {
        !          1305:       print_version_id ();
        !          1306:     }
        !          1307:   else if (**argP == 'Q')
        !          1308:     {
        !          1309:       /* Qy - do emit .comment
        !          1310:         Qn - do not emit .comment */
        !          1311:     }
        !          1312:   else if (**argP == 's')
        !          1313:     {
        !          1314:       /* use .stab instead of .stab.excl */
        !          1315:     }
        !          1316: #endif
        !          1317:   else if (strcmp (*argP, "sparc") == 0)
        !          1318:     {
        !          1319:       /* Ignore -sparc, used by SunOS make default .s.o rule.  */
        !          1320:     }
        !          1321: #endif /* NeXT */
        !          1322:   else
        !          1323:     {
        !          1324:       /* Unknown option */
        !          1325:       (*argP)++;
        !          1326:       return 0;
        !          1327:     }
        !          1328:   **argP = '\0';               /* Done parsing this switch */
        !          1329:   return 1;
        !          1330: }                              /* md_parse_option() */
        !          1331: 
        !          1332: 
        !          1333: int
        !          1334: md_estimate_size_before_relax(
        !          1335: fragS *fragP,
        !          1336: int segment_type)
        !          1337: {
        !          1338:        as_fatal("internal error: Relaxation should never occur");
        !          1339:        return(0);
        !          1340: }
        !          1341: 
        !          1342: void
        !          1343: md_convert_frag(
        !          1344: fragS *fragP)
        !          1345: {
        !          1346:        as_fatal("internal error: Relaxation should never occur");
        !          1347: }
        !          1348: 
        !          1349: 
        !          1350: #ifdef DEBUGINSN
        !          1351: 
        !          1352: char *
        !          1353: S_GET_NAME(sym)
        !          1354:      symbolS *sym;
        !          1355: {
        !          1356:   return (sym->sy_nlist.n_un.n_name);
        !          1357: }
        !          1358: 
        !          1359: /* for debugging only */
        !          1360: static void
        !          1361: print_insn (insn)
        !          1362:      struct sparc_it *insn;
        !          1363: {
        !          1364:   const char *const Reloc[] = {
        !          1365:     "VANILLA",
        !          1366:     "PAIR",
        !          1367:     "HI22",
        !          1368:     "LO10",
        !          1369:     "DISP22",
        !          1370:     "PCREL",
        !          1371:     "22",
        !          1372:     "13",
        !          1373:     "SECTDIFF",
        !          1374:     "HI22_SECTDIFF",
        !          1375:     "LO10_SECTDIFF",
        !          1376:     "NONE",
        !          1377:     "UNUSED"
        !          1378: 
        !          1379: };
        !          1380: 
        !          1381:   if (insn->error)
        !          1382:     fprintf (stderr, "ERROR: %s\n", insn->error);
        !          1383:   fprintf (stderr, "opcode=0x%08x\n", (unsigned int)insn->opcode);
        !          1384:   fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
        !          1385:   fprintf (stderr, "X_add_number = 0x%x\n",
        !          1386:           insn->exp.X_add_number);
        !          1387: 
        !          1388:   if (insn->exp.X_add_symbol != NULL)
        !          1389:     fprintf(stderr, "Add symbol: %s\n", S_GET_NAME(insn->exp.X_add_symbol));
        !          1390:   if (insn->exp.X_subtract_symbol != NULL)
        !          1391:     fprintf(stderr, "Subtract symbol: %s\n", S_GET_NAME(insn->exp.X_subtract_symbol));
        !          1392: }
        !          1393: #endif

unix.superglobalmegacorp.com

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