Annotation of GNUtools/cctools/as/hppa.c, revision 1.1.1.1

1.1       root        1: /* hppa.c -- Assemble for the HP-PA
                      2:    Copyright (C) 1989 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 1, 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: 
                     21: /*
                     22:    HP PA-RISC support was contributed by the Center for Software Science
                     23:    at the University of Utah.
                     24: */
                     25: 
                     26: /* HP-PA support for Mach-O ... USV */
                     27: 
                     28: #include <stdio.h>
                     29: #include <ctype.h>
                     30: #include <string.h>
                     31: #include <mach-o/hppa/reloc.h>
                     32: #define HPPA_RELOC_12BRANCH (127) /* only used internal in here */
                     33: 
                     34: #include "obstack.h"
                     35: #include "hppa-opcode.h"
                     36: #include "as.h"
                     37: #include "frags.h"
                     38: #include "flonum.h"
                     39: #include "hash.h"
                     40: #include "md.h"
                     41: #include "symbols.h"
                     42: #include "hppa-aux.h"
                     43: #include "messages.h"
                     44: #include "stuff/hppa.h"
                     45: 
                     46: /*
                     47:  * These are the default cputype and cpusubtype for the hppa architecture.
                     48:  */
                     49: const cpu_type_t md_cputype = CPU_TYPE_HPPA;
                     50: cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_HPPA_ALL;
                     51: 
                     52: /* This is the byte sex for the hppa architecture */
                     53: const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
                     54: 
                     55: /* These characters start a comment anywhere on the line */
                     56: const char md_comment_chars[] = ";";
                     57: 
                     58: /* These characters only start a comment at the beginning of a line */
                     59: const char md_line_comment_chars[] = "#";
                     60: 
                     61: /*
                     62:  * These characters can be used to separate mantissa decimal digits from 
                     63:  * exponent decimal digits in floating point numbers.
                     64:  */
                     65: const char md_EXP_CHARS[] = "eE";
                     66: 
                     67: /*
                     68:  * The characters after a leading 0 that means this number is a floating point
                     69:  * constant as in 0f123.456 or 0d1.234E-12 (see md_EXP_CHARS above).
                     70:  */
                     71: const char md_FLT_CHARS[] = "dDfF";
                     72: 
                     73: /*
                     74:  * This is the machine dependent pseudo opcode table for this target machine.
                     75:  */
                     76: const pseudo_typeS md_pseudo_table[] =
                     77: {
                     78:     {0} /* end of table marker */
                     79: };
                     80: 
                     81: 
                     82: static int found_jbsr = 0;
                     83: static char *toP;
                     84: 
                     85: const relax_typeS md_relax_table[] = { 0 };
                     86: 
                     87: /* handle of the OPCODE hash table */
                     88: static struct hash_control *op_hash = NULL;
                     89: 
                     90: struct pa_it the_insn;   /* this structure is defined in pa-aux.h */
                     91: 
                     92: char *expr_end;
                     93: 
                     94: static void pa_ip(
                     95:     char *str);
                     96: static int parse_L_or_R(
                     97:     char *str);
                     98: static unsigned long parse_completer_with_cache_control_hint(
                     99:        char    **s,       /* Note : the function changes '*s' */
                    100:        int     option,    /* option = 0 for store instruction */
                    101:                        /* option = 1 for load and clear instruction */
                    102:        char    completer);/* 'c' or 'C' */
                    103: static unsigned long parse_cache_control_hint(
                    104:        char    **s,       /* Note : the function changes '*s' */
                    105:        int     option);   /* option = 0 for store instruction */
                    106:                        /* option = 1 for load and clear instruction */
                    107: 
                    108: /* This function is called once, at assembler startup time.  It should
                    109:    set up all the tables, etc. that the MD part of the assembler will need.  */
                    110: void
                    111: md_begin(
                    112: void)
                    113: {
                    114:        register char *retval = NULL;
                    115:        int lose = 0;
                    116:        register unsigned int i = 0;
                    117: 
                    118:        op_hash = hash_new();
                    119:        if (op_hash == NULL)
                    120:        as_fatal("Virtual memory exhausted");
                    121: 
                    122:        while (i < NUMOPCODES) {
                    123:                const char *name = pa_opcodes[i].name;
                    124:                retval = hash_insert(op_hash, (char *)name,
                    125:                                     (char *)&pa_opcodes[i]);
                    126:                if(retval != NULL && *retval != '\0')  {
                    127:                        as_fatal("Internal error: can't hash `%s': %s\n",
                    128:                        pa_opcodes[i].name, retval);
                    129:                        lose = 1;
                    130:                }
                    131:                ++i;
                    132:        }
                    133: 
                    134:        if (lose)
                    135:                as_fatal ("Broken assembler.  No assembly attempted.");
                    136: }
                    137: 
                    138: void
                    139: md_end(
                    140: void)
                    141: {
                    142:        return;
                    143: }
                    144: 
                    145: void
                    146: md_assemble(
                    147: char *str)
                    148: {
                    149: 
                    150:        assert(str);
                    151:        pa_ip(str);
                    152:        if (!found_jbsr)
                    153:                toP = frag_more(4);
                    154:        else
                    155:                found_jbsr = 0;
                    156: 
                    157:     /* put out the opcode */
                    158:     md_number_to_chars(toP, the_insn.opcode, 4);
                    159: 
                    160:     /* put out the symbol-dependent stuff */
                    161:     if (the_insn.reloc != NO_RELOC) {
                    162:            fix_new(frag_now,                     /* which frag */
                    163:                    (toP - frag_now->fr_literal), /* where */
                    164:                    4,                            /* size */
                    165:                    the_insn.exp.X_add_symbol,
                    166:                    the_insn.exp.X_subtract_symbol,
                    167:                    the_insn.exp.X_add_number,    /* offset */
                    168:                    the_insn.pcrel,
                    169:                    the_insn.pcrel_reloc,
                    170:                    the_insn.reloc);
                    171:     }
                    172: }
                    173: 
                    174: static
                    175: void
                    176: pa_ip(
                    177: char *str)
                    178: {
                    179:        char *s;
                    180:        const char *args;
                    181:        char c;
                    182:        unsigned long i;
                    183:        struct pa_opcode *insn;
                    184:        char *argsStart;
                    185:        unsigned long   opcode;
                    186:        int match = FALSE;
                    187:        int comma = 0;
                    188: 
                    189:        int reg,reg1,reg2,s2,s3;
                    190:        unsigned int im21,im14,im11,im5;
                    191:        int m,a,u,f;
                    192:        int cmpltr,nullif, flag;
                    193:        int sfu, cond;
                    194:        char *name;
                    195:        char *save_s;
                    196: 
                    197: #ifdef PA_DEBUG
                    198:        fprintf(stderr,"STATEMENT: \"%s\"\n",str);
                    199: #endif
                    200:        for (s = str; isupper(*s) || islower(*s) || (*s >= '0' && *s <= '3'); ++s)
                    201:                ;
                    202:        switch (*s) {
                    203: 
                    204:        case '\0':
                    205:                break;
                    206: 
                    207:        case ',':
                    208:                comma = 1;
                    209: 
                    210:        /*FALLTHROUGH*/
                    211: 
                    212:        case ' ':
                    213:                *s++ = '\0';
                    214:                break;
                    215: 
                    216:        default:
                    217:                as_bad("Unknown opcode: `%s'", str);
                    218:                exit(1);
                    219:        }
                    220: 
                    221:        save_s = str;
                    222: 
                    223:        while ( *save_s ) {
                    224:                if ( isupper(*save_s) )
                    225:                        *save_s = tolower(*save_s);
                    226:                save_s++;
                    227:        }
                    228: 
                    229:        if ((insn = (struct pa_opcode *) hash_find(op_hash, str)) == NULL) {
                    230:                as_bad("Unknown opcode: `%s'", str);
                    231:                return;
                    232:        }
                    233:        if (comma) {
                    234:                *--s = ',';
                    235:        }
                    236:        argsStart = s;
                    237:        for (;;) {
                    238:                opcode = insn->match;
                    239:                memset(&the_insn, '\0', sizeof(the_insn));
                    240:                the_insn.reloc = NO_RELOC;    /* USV */
                    241: 
                    242: /*
                    243: * Build the opcode, checking as we go to make
                    244: * sure that the operands match
                    245: */
                    246:                for (args = insn->args; ; ++args) {
                    247: 
                    248:                        switch (*args) {
                    249: 
                    250:                        case '\0':  /* end of args */
                    251:                                if (*s == '\0') {
                    252:                                        match = TRUE;
                    253:                                }
                    254:                                break;
                    255: 
                    256:                        case '(':   /* these must match exactly */
                    257:                        case ')':
                    258:                        case ',':
                    259:                        case ' ':
                    260:                                if (*s++ == *args)
                    261:                                        continue;
                    262:                                break;
                    263: 
                    264:                        case 'b':   /* 5 bit register field at 10 */
                    265:                                reg = pa_parse_number(&s);
                    266:                                if ( reg < 32 && reg >= 0 ) {
                    267:                                        opcode |= reg << 21;
                    268:                                        continue;
                    269:                                }
                    270:                                break;
                    271:                        case 'x':   /* 5 bit register field at 15 */
                    272:                                reg = pa_parse_number(&s);
                    273:                                if ( reg < 32 && reg >= 0 ) {
                    274:                                        opcode |= reg << 16;
                    275:                                        continue;
                    276:                                }
                    277:                                break;
                    278:                        case 't':   /* 5 bit register field at 31 */
                    279:                                reg = pa_parse_number(&s);
                    280:                                if ( reg < 32 && reg >= 0 ) {
                    281:                                        opcode |= reg;
                    282:                                        continue;
                    283:                                }
                    284:                                break;
                    285:                        case 'T':   /* 5 bit field length at 31 (encoded as 32-T) */
                    286:   /*
                    287: reg = pa_parse_number(&s);
                    288:    */
                    289:                                getAbsoluteExpression(s);
                    290:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                    291:                                        reg = the_insn.exp.X_add_number;
                    292:                                        if ( reg <= 32 && reg > 0 ) {
                    293:                                                opcode |= 32 - reg;
                    294:                                                s = expr_end;
                    295:                                                continue;
                    296:                                        }
                    297:                                }
                    298:                                break;
                    299:                        case '5':   /* 5 bit immediate at 15 */
                    300:                                getAbsoluteExpression(s);
                    301: /** PJH: The following 2 calls to as_bad() might eventually **/
                    302: /**      want to end up as as_warn().  **/
                    303:                                if (   the_insn.exp.X_add_number > 15 ) {
                    304:                                        as_bad("5 bit immediate: %ld > 15. Set to 15",
                    305:                                                the_insn.exp.X_add_number);
                    306:                                        the_insn.exp.X_add_number = 15;
                    307:                                }
                    308:                                else if ( the_insn.exp.X_add_number < -16 ) {
                    309:                                                as_bad("5 bit immediate: %ld < -16. Set to -16",
                    310:                                                        the_insn.exp.X_add_number);
                    311:                                                the_insn.exp.X_add_number = -16;
                    312:                                        }
                    313: 
                    314:                                im5 = low_sign_unext(evaluateAbsolute(
                    315:                                                     the_insn.exp,0),5);
                    316:                                opcode |= ( im5 << 16 );
                    317:                                s = expr_end;
                    318:                                continue;
                    319: 
                    320:                        case 's':   /* 2 bit space identifier at 17 */
                    321:                                s2 = pa_parse_number(&s);
                    322:                                if ( s2 < 4 && s2 >= 0 ) {
                    323:                                        opcode |= s2 << 14;
                    324:                                        continue;
                    325:                                }
                    326:                                break;
                    327:                        case 'S':   /* 3 bit space identifier at 18 */
                    328:                                s3 = pa_parse_number(&s);
                    329:                                if ( s3 < 8 && s3 >= 0 ) {
                    330:                                        s3 = dis_assemble_3(s3);
                    331:                                        opcode |= s3 << 13;
                    332:                                        continue;
                    333:                                }
                    334:                                break;
                    335:                        case 'c':   /* indexed load completer. */
                    336:                                i = m = u = 0;
                    337:                                while ( *s == ',' && i < 2 ) {
                    338:                                        s++;
                    339:                                        if ( strncasecmp(s,"sm",2) == 0 ) {
                    340:                                                m = u = 1;
                    341:                                                s++;
                    342:                                                i++;
                    343:                                        }
                    344:                                        else if ( strncasecmp(s,"m",1) == 0 )
                    345:                                                        m = 1;
                    346:                                                else if ( strncasecmp(s,"s",1) == 0 )
                    347:                                                                u = 1;
                    348:                                                        else
                    349:                                                                as_bad("Unrecognized Indexed Load"
                    350:                                                                        "Completer...assuming 0");
                    351:                                        s++;
                    352:                                        i++;
                    353:                                }
                    354:                                if ( i > 2 )
                    355:                                        as_bad("Illegal Indexed Load Completer Syntax..."
                    356:                                                "extras ignored");
                    357:                                while ( *s == ' ' || *s == '\t' )
                    358:                                        s++;
                    359:   
                    360:                                opcode |= m << 5;
                    361:                                opcode |= u << 13;
                    362:                                continue;
                    363:                        case 'C':   /* short load and store completer */
                    364:                                m = a = 0;
                    365:                                if ( *s == ',' ) {
                    366:                                        s++;
                    367:                                        if ( strncasecmp(s,"ma",2) == 0 ) {
                    368:                                                a = 0;
                    369:                                                m = 1;
                    370:                                        }
                    371:                                        else if ( strncasecmp(s,"mb",2) == 0 ) {
                    372:                                                        m = a = 1;
                    373:                                                }
                    374:                                                else
                    375:                                                        as_bad("Unrecognized Indexed Load Completer"
                    376:                                                                "...assuming 0");
                    377:                                        s += 2;
                    378:                                }
                    379:                                while ( *s == ' ' || *s == '\t' )
                    380:                                        s++;
                    381:                                opcode |= m << 5;
                    382:                                opcode |= a << 13;
                    383:                                continue;
                    384: 
                    385:                        /* bug #41317 .... [email protected]
                    386:                         * Fri Jul 22 09:43:46 PDT 1994
                    387:                         *
                    388:                         * Modified to parse 'cache control hints'
                    389:                         *
                    390:                         * These parse ",cc" and encode "cc" in 2 bits at 20,
                    391:                         * where "cc" encoding is as given in Tables 5-8, 5-9.
                    392:                         * Refer to 'PA-RISC 1.1 Architecture and Instruction Set
                    393:                         * Reference Manual, Second Edition' for the tables.
                    394:                         */
                    395:                        case 'Y':   /* Store Bytes Short completer */
                    396:                                                /* with cache control hints    */
                    397:                        {
                    398:                                unsigned long result = (unsigned long)0UL;
                    399:                                
                    400:                                i = m = a = 0;
                    401:                                while ( *s == ',' && i < 3 ) {
                    402:                                        s++;
                    403:                                        if ( strncasecmp(s,"m",1) == 0 )
                    404:                                                m = 1;
                    405:                                        else if ( strncasecmp(s,"b",1) == 0 &&
                    406:                                                          (strncasecmp((s+1),"c",1) != 0) )
                    407:                                                        a = 0;
                    408:                                                else if ( strncasecmp(s,"e",1) == 0 )
                    409:                                                                a = 1;
                    410:                                                        else if ( strncmp(s,",",1) == 0 ) /* no completer */
                    411:                                                                result |= parse_cache_control_hint(&s, 0);
                    412:                                                        else if ( (strncasecmp(s,"c",1) == 0) ||
                    413:                                                                (strncasecmp(s,"b",1) == 0) ) {/* just 1 completer */
                    414:                                                                s--;
                    415:                                                                result |= parse_cache_control_hint(&s, 0);
                    416:                                                        }
                    417:                                                        else
                    418:                                                                as_bad("Unrecognized Store Bytes Short"
                    419:                                                                        "Completer with cache control hints"
                    420:                                                                        " ...assuming 0");
                    421:                                        if (result == (unsigned long)0UL)
                    422:                                                s++;
                    423:                                        i++;
                    424:                                }
                    425: /**            if ( i >= 2 ) **/
                    426:                                if ( i > 3 )
                    427:                                        as_bad("Illegal Store Bytes Short Completer "
                    428:                                                "with cache control hints ...  extras ignored");
                    429:                                while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
                    430:                                        s++;
                    431:                                opcode |= result;
                    432:                                opcode |= m << 5;
                    433:                                opcode |= a << 13;
                    434:                                continue;
                    435:                        }
                    436:                        case '<':   /* non-negated compare/subtract conditions. */
                    437:                                cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
                    438:                                if ( cmpltr < 0 ) {
                    439:                                        as_bad("Unrecognized Compare/Subtract Condition: %c",*s);
                    440:                                        cmpltr = 0;
                    441:                                }
                    442:                                opcode |= cmpltr << 13;
                    443:                                continue;
                    444:                        case '?':   /* negated or non-negated cmp/sub conditions. */
                    445:                                        /* used only by ``comb'' and ``comib'' pseudo-ops */
                    446:                                save_s = s;
                    447:                                cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
                    448:                                if ( cmpltr < 0 ) {
                    449:                                        s = save_s;
                    450:                                        cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
                    451:                                        if ( cmpltr < 0 ) {
                    452:                                                as_bad("Unrecognized Compare/Subtract Condition: %c"
                    453:                                                        ,*s);
                    454:                                                cmpltr = 0;
                    455:                                        }
                    456:                                        else {
                    457:                                                opcode |= 1 << 27; /* required opcode change to make
                    458:                                                                                        COMIBT into a COMIBF or a
                    459:                                                                                        COMBT into a COMBF or a
                    460:                                                                                        ADDBT into a ADDBF or a
                    461:                                                                                        ADDIBT into a ADDIBF */
                    462:                                        }
                    463:                                }
                    464:                                opcode |= cmpltr << 13;
                    465:                                continue;
                    466:                        case '!':   /* negated or non-negated add conditions. */
                    467:                                /* used only by ``addb'' and ``addib'' pseudo-ops */
                    468:                                save_s = s;
                    469:                                cmpltr = pa_parse_nonneg_add_cmpltr(&s);
                    470:                                if ( cmpltr < 0 ) {
                    471:                                        s = save_s;
                    472:                                        cmpltr = pa_parse_neg_add_cmpltr(&s);
                    473:                                        if ( cmpltr < 0 ) {
                    474:                                                as_bad("Unrecognized Compare/Subtract Condition: %c",
                    475:                                                        *s);
                    476:                                                cmpltr = 0;
                    477:                                        }
                    478:                                        else {
                    479:                                                opcode |= 1 << 27; /* required opcode change to make
                    480:                                                                                        COMIBT into a COMIBF or a
                    481:                                                                                        COMBT into a COMBF or a
                    482:                                                                                        ADDBT into a ADDBF or a
                    483:                                                                                        ADDIBT into a ADDIBF */
                    484:                                        }
                    485:                                }
                    486:                                opcode |= cmpltr << 13;
                    487:                                continue;
                    488:                        case '-':   /* compare/subtract conditions */
                    489:                                f = cmpltr = 0;
                    490:                                save_s = s;
                    491:                                if ( *s == ',' ) {
                    492:                                        cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
                    493:                                        if ( cmpltr < 0 ) {
                    494:                                                f = 1;
                    495:                                                s = save_s;
                    496:                                                cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
                    497:                                                if ( cmpltr < 0 ) {
                    498:                                                        as_bad("Unrecognized Compare/Subtract Condition");
                    499:                                                }
                    500:                                        }
                    501:                                }
                    502:                                opcode |= cmpltr << 13;
                    503:                                opcode |= f << 12;
                    504:                                continue;
                    505:                        case '+':   /* non-negated add conditions */
                    506:                                flag = nullif = cmpltr = 0;
                    507:                                if ( *s == ',' ) {
                    508:                                        s++;
                    509:                                        name = s;
                    510:                                        while ( *s != ',' && *s != ' ' && *s != '\t' )
                    511:                                                s += 1;
                    512:                                        c = *s;
                    513:                                        *s = 0x00;
                    514:                                        if ( strcmp(name,"=") == 0 ) {
                    515:                                                cmpltr = 1;
                    516:                                                }
                    517:                                                else if ( strcmp(name,"<") == 0 ) {
                    518:                                                cmpltr = 2;
                    519:                                                }
                    520:                                                else if ( strcmp(name,"<=") == 0 ) {
                    521:                                                cmpltr = 3;
                    522:                                                }
                    523:                                                else if ( strcasecmp(name,"nuv") == 0 ) {
                    524:                                                cmpltr = 4;
                    525:                                                }
                    526:                                                else if ( strcasecmp(name,"znv") == 0 ) {
                    527:                                                cmpltr = 5;
                    528:                                                }
                    529:                                                else if ( strcasecmp(name,"sv") == 0 ) {
                    530:                                                cmpltr = 6;
                    531:                                                }
                    532:                                                else if ( strcasecmp(name,"od") == 0 ) {
                    533:                                                cmpltr = 7;
                    534:                                                }
                    535:                                                else if ( strcasecmp(name,"n") == 0 ) {
                    536:                                                nullif = 1;
                    537:                                                }
                    538:                                                else if ( strcasecmp(name,"tr") == 0 ) {
                    539:                                                cmpltr = 0;
                    540:                                                flag   = 1;
                    541:                                                }
                    542:                                                else if ( strcasecmp(name,"<>") == 0 ) {
                    543:                                                flag = cmpltr = 1;
                    544:                                                }
                    545:                                                else if ( strcasecmp(name,">=") == 0 ) {
                    546:                                                cmpltr = 2;
                    547:                                                flag   = 1;
                    548:                                                }
                    549:                                                else if ( strcasecmp(name,">") == 0 ) {
                    550:                                                cmpltr = 3;
                    551:                                                flag   = 1;
                    552:                                                }
                    553:                                                else if ( strcasecmp(name,"uv") == 0 ) {
                    554:                                                cmpltr = 4;
                    555:                                                flag   = 1;
                    556:                                                }
                    557:                                                else if ( strcasecmp(name,"vnz") == 0 ) {
                    558:                                                cmpltr = 5;
                    559:                                                flag   = 1;
                    560:                                                }
                    561:                                                else if ( strcasecmp(name,"nsv") == 0 ) {
                    562:                                                cmpltr = 6;
                    563:                                                flag   = 1;
                    564:                                                }
                    565:                                                else if ( strcasecmp(name,"ev") == 0 ) {
                    566:                                                cmpltr = 7;
                    567:                                                flag   = 1;
                    568:                                                }
                    569:                                                else
                    570:                                                as_bad("Unrecognized Add Condition: %s",name);
                    571:                                        *s = c;
                    572:                                }
                    573:                                nullif = pa_parse_nullif(&s);
                    574:                                opcode |= nullif << 1;
                    575:                                opcode |= cmpltr << 13;
                    576:                                opcode |= flag << 12;
                    577:                                continue;               
                    578:                        case '&':   /* logical instruction conditions */
                    579:                                f = cmpltr = 0;
                    580:                                if ( *s == ',' ) {
                    581:                                        s++;
                    582:                                        name = s;
                    583:                                        while ( *s != ',' && *s != ' ' && *s != '\t' )
                    584:                                                s += 1;
                    585:                                        c = *s;
                    586:                                        *s = 0x00;
                    587:                                        if ( strcmp(name,"=") == 0 ) {
                    588:                                                cmpltr = 1;
                    589:                                                }
                    590:                                                else if ( strcmp(name,"<") == 0 ) {
                    591:                                                cmpltr = 2;
                    592:                                                }
                    593:                                                else if ( strcmp(name,"<=") == 0 ) {
                    594:                                                cmpltr = 3;
                    595:                                                }
                    596:                                                else if ( strcasecmp(name,"od") == 0 ) {
                    597:                                                cmpltr = 7;
                    598:                                                }
                    599:                                                else if ( strcasecmp(name,"tr") == 0 ) {
                    600:                                                cmpltr = 0;
                    601:                                                f = 1;
                    602:                                                }
                    603:                                                else if ( strcmp(name,"<>") == 0 ) {
                    604:                                                f = cmpltr = 1;
                    605:                                                }
                    606:                                                else if ( strcmp(name,">=") == 0 ) {
                    607:                                                cmpltr = 2;
                    608:                                                f = 1;
                    609:                                                }
                    610:                                                else if ( strcmp(name,">") == 0 ) {
                    611:                                                cmpltr = 3;
                    612:                                                f = 1;
                    613:                                                }
                    614:                                                else if ( strcasecmp(name,"ev") == 0 ) {
                    615:                                                cmpltr = 7;
                    616:                                                f = 1;
                    617:                                                }
                    618:                                                else
                    619:                                                as_bad("Unrecognized Logical Instruction Condition:"
                    620:                                                        " %s",name);
                    621:                                        *s = c;
                    622:                                }
                    623:                                opcode |= cmpltr << 13;
                    624:                                opcode |= f << 12;              
                    625:                                continue;
                    626:                        case 'U':   /* unit instruction conditions */
                    627:                                cmpltr = 0;
                    628:                                f = 0;
                    629:                                if ( *s == ',' ) {
                    630:                                        s++;
                    631:                                        if ( strncasecmp(s,"sbz",3) == 0 ) {
                    632:                                                cmpltr = 2;
                    633:                                                s += 3;
                    634:                                                }
                    635:                                                else if ( strncasecmp(s,"shz",3) == 0 ) {
                    636:                                                cmpltr = 3;
                    637:                                                s += 3;
                    638:                                                }
                    639:                                                else if ( strncasecmp(s,"sdc",3) == 0 ) {
                    640:                                                cmpltr = 4;
                    641:                                                s += 3;
                    642:                                                }
                    643:                                                else if ( strncasecmp(s,"sbc",3) == 0 ) {
                    644:                                                cmpltr = 6;
                    645:                                                s += 3;
                    646:                                                }
                    647:                                                else if ( strncasecmp(s,"shc",3) == 0 ) {
                    648:                                                cmpltr = 7;
                    649:                                                s += 3;
                    650:                                                }
                    651:                                                else if ( strncasecmp(s,"tr",2) == 0 ) {
                    652:                                                cmpltr = 0;
                    653:                                                f = 1;
                    654:                                                s += 2;
                    655:                                                }
                    656:                                                else if ( strncasecmp(s,"nbz",3) == 0 ) {
                    657:                                                cmpltr = 2;
                    658:                                                f = 1;
                    659:                                                s += 3;
                    660:                                                }
                    661:                                                else if ( strncasecmp(s,"nhz",3) == 0 ) {
                    662:                                                cmpltr = 3;
                    663:                                                f = 1;
                    664:                                                s += 3;
                    665:                                                }
                    666:                                                else if ( strncasecmp(s,"ndc",3) == 0 ) {
                    667:                                                cmpltr = 4;
                    668:                                                f = 1;
                    669:                                                s += 3;
                    670:                                                }
                    671:                                                else if ( strncasecmp(s,"nbc",3) == 0 ) {
                    672:                                                cmpltr = 6;
                    673:                                                f = 1;
                    674:                                                s += 3;
                    675:                                                }
                    676:                                                else if ( strncasecmp(s,"nhc",3) == 0 ) {
                    677:                                                cmpltr = 7;
                    678:                                                f = 1;
                    679:                                                s += 3;
                    680:                                                }
                    681:                                                else
                    682:                                                as_bad("Unrecognized Logical Instruction Condition:"
                    683:                                                        " %c",*s);
                    684:                                }
                    685:                                opcode |= cmpltr << 13;
                    686:                                opcode |= f << 12;              
                    687:                                continue;
                    688:                        case '>':   /* shift/extract/deposit conditions. */
                    689:                                cmpltr = 0;
                    690:                                if ( *s == ',' ) {
                    691:                                        s++;
                    692:                                        name = s;
                    693:                                        while ( *s != ',' && *s != ' ' && *s != '\t' )
                    694:                                                s += 1;
                    695:                                        c = *s;
                    696:                                        *s = 0x00;
                    697:                                        if ( strcmp(name,"=") == 0 ) {
                    698:                                                cmpltr = 1;
                    699:                                                }
                    700:                                                else if ( strcmp(name,"<") == 0 ) {
                    701:                                                cmpltr = 2;
                    702:                                                }
                    703:                                                else if ( strcasecmp(name,"od") == 0 ) {
                    704:                                                cmpltr = 3;
                    705:                                                }
                    706:                                                else if ( strcasecmp(name,"tr") == 0 ) {
                    707:                                                cmpltr = 4;
                    708:                                                }
                    709:                                                else if ( strcmp(name,"<>") == 0 ) {
                    710:                                                cmpltr = 5;
                    711:                                                }
                    712:                                                else if ( strcmp(name,">=") == 0 ) {
                    713:                                                cmpltr = 6;
                    714:                                                }
                    715:                                                else if ( strcasecmp(name,"ev") == 0 ) {
                    716:                                                cmpltr = 7;
                    717:                                                }
                    718:                                                else
                    719:                                                as_bad("Unrecognized Shift/Extract/Deposit"
                    720:                                                        "Condition: %s",name);
                    721:                                        *s = c;
                    722:                                }
                    723:                                opcode |= cmpltr << 13;
                    724:                                continue;
                    725:                        case '~':   /* bvb,bb conditions */
                    726:                                cmpltr = 0;
                    727:                                if ( *s == ',' ) {
                    728:                                        s++;
                    729:                                        if ( strncmp(s,"<",1) == 0 ) {
                    730:                                                cmpltr = 2;
                    731:                                                s++;
                    732:                                                }
                    733:                                                else if ( strncmp(s,">=",2) == 0 ) {
                    734:                                                cmpltr = 6;
                    735:                                                s += 2;
                    736:                                                }
                    737:                                                else
                    738:                                                as_bad("Unrecognized Bit Branch Condition: %c",*s);
                    739:                                }
                    740:                                opcode |= cmpltr << 13;
                    741:                                continue;
                    742:                        case 'V':   /* 5  bit immediate at 31 */
                    743:                                getExpression(s);
                    744:                                im5 = low_sign_unext(evaluateAbsolute(
                    745:                                                     the_insn.exp,0),5);
                    746:                                opcode |= im5;
                    747:                                s = expr_end;
                    748:                                continue;
                    749:                        case 'r':   /* 5  bit immediate at 31 */
                    750:                                                /* (unsigned value for the break instruction) */
                    751:                                getExpression(s);
                    752:                                im5 = evaluateAbsolute(the_insn.exp,0);
                    753:                                if ( im5 > 31 ) {
                    754:                                        as_bad("Operand out of range. Was: %d. Should be"
                    755:                                                "[0..31]. Assuming %d.\n",im5,im5&0x1f);
                    756:                                        im5 = im5 & 0x1f;
                    757:                                }
                    758:                                opcode |= im5;
                    759:                                s = expr_end;
                    760:                                continue;
                    761:                        case 'R':   /* 5  bit immediate at 15 */
                    762: /* (unsigned value for the ssm and rsm instruction) */
                    763:                                getExpression(s);
                    764:                                im5 = evaluateAbsolute(the_insn.exp,0);
                    765:                                if ( im5 > 31 ) {
                    766:                                        as_bad("Operand out of range. Was: %d. Should be"
                    767:                                                "[0..31]. Assuming %d.\n",im5,im5&0x1f);
                    768:                                        im5 = im5 & 0x1f;
                    769:                                }
                    770:                                opcode |= im5 << 16;
                    771:                                s = expr_end;
                    772:                                continue;
                    773:                        case 'i':   /* 11 bit immediate at 31 */
                    774:                                getExpression(s);
                    775:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                    776:                                        im11 = low_sign_unext(evaluateAbsolute(
                    777:                                                        the_insn.exp,0),11);
                    778:                                        opcode |= im11;
                    779:                                }
                    780:                                else {
                    781:                                        the_insn.code = 'i';
                    782:                                }
                    783:                                s = expr_end;
                    784:                                continue;
                    785:                        case 'j':   /* 14 bit immediate at 31 --- LO14 */
                    786:                        {
                    787:                                int field_selector = parse_L_or_R(s);
                    788:                                switch (field_selector) {
                    789:                                case 2: /* found the field selector R`*/
                    790:                                case 1: /* found the field selector L`*/
                    791:                                        s += 2;  /* eat up L` or R` */
                    792:                                case 0: /* not found */
                    793:                                        getExpression(s);
                    794:                                        break;
                    795:                                default:
                    796:                                        as_bad("Bad field selector. Was: %.2s. Should be either L` or R`\n",s);
                    797:                                        break;
                    798:                                }
                    799:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                    800:                                        im14 = low_sign_unext(
                    801: evaluateAbsolute(the_insn.exp,field_selector), 14);
                    802: 
                    803: /* I donot think the mask is necessary here  low_sign_unext() takes */
                    804: /* care of putting only 14 bits in im14 ! ...       090993 ... USV  */
                    805: /*                                     if (field_selector)
                    806:                                                opcode |= (im14 & 0x7ff);
                    807:                                        else
                    808: */
                    809:                                        opcode |= im14;
                    810:                                }
                    811:                                else {
                    812:                                        the_insn.reloc = HPPA_RELOC_LO14;
                    813:                                        the_insn.code = 'j';
                    814:                                }
                    815:                                s = expr_end;
                    816:                                continue;
                    817:                        }  
                    818:                        case 'z':       /* 17 bit branch displacement (non-pc-relative) */
                    819:                                /* for be, ble --- BR17*/
                    820:                                /* bl, ble  in absence of L` or R` can have */
                    821:                                /* a 17 bit immmidiate number */
                    822:                        {
                    823:                                unsigned long w, w1, w2;
                    824:                                int field_selector = parse_L_or_R(s);
                    825:                                switch (field_selector) {
                    826:                                case 2: /* found the field selector R`*/
                    827:                                case 1: /* found the field selector L`*/
                    828:                                        s += 2;  /* eat up L` or R` */
                    829:                                case 0: /* not found */
                    830:                                        getExpression(s);
                    831:                                        break;
                    832:                                default:
                    833:                                        as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
                    834:                                        break;
                    835:                                }
                    836:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                    837:                                        im14 = sign_unext(
                    838:                                                evaluateAbsolute(the_insn.exp,field_selector),
                    839:                                                17);
                    840:                                        dis_assemble_17(im14>>2,&w1,&w2,&w);
                    841:                                        opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
                    842:                                }
                    843:                                else {
                    844:                                        the_insn.reloc = HPPA_RELOC_BR17;
                    845:                                        the_insn.code = 'z';
                    846:                                }
                    847:                                s = expr_end;
                    848:                                continue;
                    849:                        }
                    850:                        case 'k':   /* 21 bit immediate at 31 --- HI21 */
                    851:                        {
                    852:                                int field_selector = parse_L_or_R(s);
                    853:                                switch (field_selector) {
                    854:                                case 2: /* found the field selector R`*/
                    855:                                case 1: /* found the field selector L`*/
                    856:                                        s += 2;  /* eat up L` or R` */
                    857:                                case 0: /* not found */
                    858:                                        getExpression(s);
                    859:                                        break;
                    860:                                default:
                    861:                                        as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
                    862:                                        break;
                    863:                                }
                    864:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                    865:                                        im21 = dis_assemble_21(
                    866: (evaluateAbsolute(the_insn.exp,field_selector) >> 11));
                    867:                                        opcode |=  im21 ;
                    868:                                }
                    869:                                else {
                    870:                                        the_insn.reloc = HPPA_RELOC_HI21;
                    871:                                        the_insn.code = 'k';
                    872:                                }
                    873:                                s = expr_end;
                    874:                                continue;
                    875:                        }
                    876:                        case 'n':   /* nullification for branch instructions */
                    877:                                nullif = pa_parse_nullif(&s);
                    878:                                opcode |= nullif << 1;
                    879:                                continue;               
                    880:                        case 'w':   /* 12 bit branch displacement */
                    881:                                getExpression(s);
                    882:                                the_insn.pcrel_reloc = 0;
                    883:                                the_insn.pcrel = 1;
                    884:                                if ( the_insn.exp.X_add_symbol ) {
                    885:                                    if ( strcmp(
                    886: the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
                    887:                                        unsigned long w1,w,result;
                    888:                                        result = sign_unext( (the_insn.exp.X_add_number
                    889:                                                        - 8) >> 2,
                    890:                                                        12);
                    891:                                        dis_assemble_12(result,&w1,&w);
                    892:                                        opcode |= ( ( w1 << 2 ) | w );
                    893:                                    }
                    894:                                    else {
                    895: /* this has to be wrong -- dont know what is right! */
                    896: /*  the_insn.reloc = R_PCREL_CALL; */
                    897:                                        the_insn.reloc = HPPA_RELOC_12BRANCH;
                    898:                                                the_insn.code = 'w';
                    899:                                    }
                    900:                                }
                    901:                                else {
                    902:                                    unsigned long w1,w,result;
                    903:                                    result = sign_unext( the_insn.exp.X_add_number >> 
                    904:                                        2,12);
                    905:                                    dis_assemble_12(result,&w1,&w);
                    906:                                    opcode |= ( ( w1 << 2 ) | w );
                    907:                                }
                    908:                                s = expr_end;
                    909:                                continue;
                    910:                        case 'W':   /* 17 bit branch displacement --- BL17 */
                    911:                                getExpression(s);
                    912:                                /*
                    913:                                 * The NeXT linker has the ability to scatter
                    914:                                 * blocks of sections between labels.  This
                    915:                                 * requires that brances to labels that survive
                    916:                                 * to the link phase must be able to be
                    917:                                 * relocated.
                    918:                                 */
                    919:                                if(the_insn.exp.X_add_symbol != NULL &&
                    920:                                   (the_insn.exp.X_add_symbol->sy_name[0] != 'L'
                    921:                                    || flagseen['L']))
                    922:                                    the_insn.pcrel_reloc = 1;
                    923:                                else
                    924:                                    the_insn.pcrel_reloc = 0;
                    925:                                the_insn.pcrel = 1;
                    926:                                if ( the_insn.exp.X_add_symbol ) {
                    927:                                        if ( strcmp(the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
                    928:                                                unsigned long w2,w1,w,result;
                    929: 
                    930:                                                result = sign_unext( 
                    931:                                                        (the_insn.exp.X_add_number - 8) >> 2,17);
                    932:                                                dis_assemble_17(result,&w1,&w2,&w);
                    933:                                                opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
                    934:                                        }
                    935:                                        else {
                    936:                                                if ( (the_insn.reloc == HPPA_RELOC_JBSR) &&
                    937:                                                 (the_insn.exp.X_add_symbol->sy_name[0] != 'L') )
                    938:                                                        as_fatal("Stub label used in a JBSR must be "
                    939:                                                                "non-relocatable");
                    940:                                                the_insn.reloc = HPPA_RELOC_BL17;
                    941:                                                the_insn.code = 'W';
                    942:                                        }
                    943:                                }
                    944:                                else {
                    945:                                        unsigned long w2,w1,w,result;
                    946: 
                    947:                                        result = sign_unext( the_insn.exp.X_add_number >> 2,17);
                    948:                                        dis_assemble_17(result,&w1,&w2,&w);
                    949:                                        opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
                    950:                                }
                    951:                                s = expr_end;
                    952:                                continue;
                    953:                        case '@':   /* 17 bit branch displacement --- JBSR */
                    954:                                getExpression(s);
                    955: 
                    956: /*
                    957:  * assumption here is this will only be used in case of jbsr
                    958:  * in which case the format is 
                    959:  *             jbsr,n symbol,register,label
                    960:  * and a relocation entry for symbol needs to be created
                    961:  */
                    962:  
                    963:                                the_insn.pcrel = 0;
                    964:                                the_insn.pcrel_reloc = 1;
                    965:                                the_insn.reloc = HPPA_RELOC_JBSR;
                    966:                                the_insn.code = '@';
                    967:                                s = expr_end;
                    968:  /*
                    969:   * The code to hook a frag in the chain should be here.
                    970:   * Then set a flag saying that the next 'W' should not create a relocation
                    971:   * entry. The way 'jbsr' is expected to work is the label will always be
                    972:   * local!
                    973:   * This flag should be reset in 'W'.
                    974:   */
                    975:                                found_jbsr = 1;
                    976:                                toP = frag_more(4);
                    977:                                fix_new(frag_now,
                    978:                                        (toP - frag_now->fr_literal),
                    979:                                        4,
                    980:                                        the_insn.exp.X_add_symbol,
                    981:                                        the_insn.exp.X_subtract_symbol,
                    982:                                        the_insn.exp.X_add_number,
                    983:                                        the_insn.pcrel,
                    984:                                        the_insn.pcrel_reloc,
                    985:                                        the_insn.reloc);
                    986: 
                    987:                                continue;
                    988:                        case 'B':   /* either "s,b" or "b" where b & s are defined above */
                    989:                                reg1 = pa_parse_number(&s);
                    990:                                if ( *s == ',' ) {
                    991:                                        s++;
                    992:                                        reg2 = pa_parse_number(&s);
                    993:                                }
                    994:                                else {
                    995:                                        reg2 = reg1;
                    996:                                        reg1 = 0;
                    997:                                }
                    998:                                if ( reg1 < 4 && reg1 >= 0 ) {
                    999:                                        opcode |= reg1 << 14;
                   1000:                                        opcode |= reg2 << 21;
                   1001:                                        continue;
                   1002:                                }
                   1003:                                break;
                   1004:                        case 'p':   /* 5 bit shift count at 26 (to support SHD instr.) */
                   1005:                                                /* value is encoded in instr. as 31-p where p is   */
                   1006:                                                /* the value scanned here */
                   1007:                                getExpression(s);
                   1008:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                   1009:                                        opcode |= ( ( (31 - the_insn.exp.X_add_number) & 0x1f ) << 5 );
                   1010:                                }
                   1011:                                s = expr_end;
                   1012:                                continue;
                   1013:                        case 'P':   /* 5-bit bit position at 26 */
                   1014:                                getExpression(s);
                   1015:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                   1016:                                        opcode |= ( the_insn.exp.X_add_number & 0x1f ) << 5;
                   1017:                                }
                   1018:                                s = expr_end;
                   1019:                                continue;
                   1020:                        case 'Q':   /* 5  bit immediate at 10 */
                   1021:                                                /* (unsigned bit position value for the bb instruction) */
                   1022:                                getExpression(s);
                   1023:                                im5 = evaluateAbsolute(the_insn.exp,0);
                   1024:                                if ( im5 > 31 ) {
                   1025:                                        as_bad("Operand out of range. Was: %d. Should be"
                   1026:                                                "[0..31]. Assuming %d.\n",im5,im5&0x1f);
                   1027:                                        im5 = im5 & 0x1f;
                   1028:                                }
                   1029:                                opcode |= im5 << 21;
                   1030:                                s = expr_end;
                   1031:                                continue;
                   1032:                        case 'A':   /* 13 bit immediate at 18 (to support BREAK instr.) */
                   1033:                                getAbsoluteExpression(s);
                   1034:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE )
                   1035:                                opcode |= (the_insn.exp.X_add_number & 0x1fff) << 13;
                   1036:                                s = expr_end;
                   1037:                                continue;
                   1038:                        case 'Z':   /* System Control Completer(for LDA, LHA, etc.) */
                   1039:                                if ( *s == ',' && ( *(s+1) == 'm' || *(s+1) == 'M' ) ) {
                   1040:                                        m = 1;
                   1041:                                        s += 2;
                   1042:                                }
                   1043:                                else
                   1044:                                        m = 0;
                   1045:   
                   1046:                                opcode |= m << 5;
                   1047:                                while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
                   1048:                                        s++;
                   1049:   
                   1050:                                continue;
                   1051:                        case 'D':   /* 26 bit immediate at 31 (to support DIAG instr.) */
                   1052:                                                /* the action (and interpretation of this operand is
                   1053:                                                        implementation dependent) */
                   1054:                                getExpression(s);
                   1055:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
                   1056:                                        opcode |= ( (evaluateAbsolute(the_insn.exp,0) & 0x1ffffff) << 1 );
                   1057:                                }
                   1058:                                else
                   1059:                                        as_bad("Illegal DIAG operand");
                   1060:                                        s = expr_end;
                   1061:                                continue;
                   1062:                        case 'f':   /* 3 bit Special Function Unit (SFU) identifier at 25 */
                   1063:                                sfu = pa_parse_number(&s);
                   1064:                                if ( (sfu > 7) || (sfu < 0) )
                   1065:                                        as_bad("Illegal SFU identifier: %02x", sfu);
                   1066:                                opcode |= (sfu & 7) << 6;
                   1067:                                continue;
                   1068:                        case 'O':   /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */
                   1069:                                getExpression(s);
                   1070:                                s = expr_end;
                   1071:                                continue;
                   1072:                        case 'o':   /* 15 bit Special Function Unit operation at 20 */
                   1073:                                getExpression(s);
                   1074:                                s = expr_end;
                   1075:                                continue;
                   1076:                        case '2':   /* 22 bit SFU op. split between 17 bits at 20
                   1077:                                                        and 5 bits at 31 */
                   1078:                                getExpression(s);
                   1079:                                s = expr_end;
                   1080:                                continue;
                   1081:                        case '1':   /* 15 bit SFU op. split between 10 bits at 20
                   1082:                                                        and 5 bits at 31 */
                   1083:                                getExpression(s);
                   1084:                                s = expr_end;
                   1085:                                continue;
                   1086:                        case '0':   /* 10 bit SFU op. split between 5 bits at 20
                   1087:                                                        and 5 bits at 31 */
                   1088:                                getExpression(s);
                   1089:                                s = expr_end;
                   1090:                                continue;
                   1091:                        case 'u':   /* 3 bit coprocessor unit identifier at 25 */
                   1092:                                getExpression(s);
                   1093:                                s = expr_end;
                   1094:                                continue;
                   1095:                        case 'F':   /* Source FP Operand Format Completer (2 bits at 20) */
                   1096:                                f = pa_parse_fp_format(&s);
                   1097:                                opcode |= (int)f << 11;
                   1098:                                the_insn.fpof1 = f;
                   1099:                                continue;
                   1100:                        case 'G':   /* Destination FP Operand Format Completer (2 bits at 18) */
                   1101:                                s--;    /* need to pass the previous comma to pa_parse_fp_format */
                   1102:                                f = pa_parse_fp_format(&s);
                   1103:                                opcode |= (int)f << 13;
                   1104:                                the_insn.fpof2 = f;
                   1105:                                continue;
                   1106:                        case 'M':   /* FP Compare Conditions (encoded as 5 bits at 31) */
                   1107:                                cond = pa_parse_fp_cmp_cond(&s);
                   1108:                                opcode |= cond;
                   1109:                                continue;
                   1110: 
                   1111:                        case 'v':   /* a 't' type extended to handle L/R register halves. */
                   1112:                                {
                   1113:                                        struct pa_89_fp_reg_struct result;
                   1114: 
                   1115:                                        pa_89_parse_number(&s,&result);
                   1116:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1117:                                                opcode |= (result.number_part & 0x1f);
                   1118: 
                   1119:                                                /* 0x30 opcodes are FP arithmetic operation opcodes */
                   1120:                                                /* load/store FP opcodes do not get converted to 0x38 */
                   1121:                                                /* opcodes like the 0x30 opcodes do */
                   1122:                                                if ( need_89_opcode(&the_insn,&result) ) {
                   1123:                                                        if ( (opcode & 0xfc000000) == 0x30000000 ) {
                   1124:                                                                opcode |= (result.L_R_select & 1) << 6;
                   1125:                                                                opcode |= 1 << 27;
                   1126:                                                        }
                   1127:                                                        else {
                   1128:                                                                opcode |= (result.L_R_select & 1) << 6;
                   1129:                                                        }
                   1130:                                                }
                   1131:                                                continue;
                   1132:                                        }
                   1133:                                }
                   1134:                                break;
                   1135:                        case 'E':   /* a 'b' type extended to handle L/R register halves. */
                   1136:                                {
                   1137:                                        struct pa_89_fp_reg_struct result;
                   1138: 
                   1139:                                        pa_89_parse_number(&s,&result);
                   1140:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1141:                                                opcode |= (result.number_part & 0x1f) << 21;
                   1142:                                                if ( need_89_opcode(&the_insn,&result) ) {
                   1143:                                                        opcode |= (result.L_R_select & 1) << 7;
                   1144:                                                        opcode |= 1 << 27;
                   1145:                                                }
                   1146:                                                continue;
                   1147:                                        }
                   1148:                                }
                   1149:                                break;
                   1150: 
                   1151:                        case 'X':   /* an 'x' type extended to handle L/R register halves. */
                   1152:                                {
                   1153:                                        struct pa_89_fp_reg_struct result;
                   1154: 
                   1155: 
                   1156:                                        pa_89_parse_number(&s,&result);
                   1157:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1158:                                                opcode |= (result.number_part & 0x1f) << 16;
                   1159:                                                if ( need_89_opcode(&the_insn,&result) ) {
                   1160:                                                        opcode |= (result.L_R_select & 1) << 12;
                   1161:                                                        opcode |= 1 << 27;
                   1162:                                                }
                   1163:                                                continue;
                   1164:                                        }
                   1165:                                }
                   1166:                                break;
                   1167: 
                   1168:                        case '4':   /* 5 bit register field at 10
                   1169:                                                (used in 'fmpyadd' and 'fmpysub') */
                   1170:                                {
                   1171:                                        struct pa_89_fp_reg_struct result;
                   1172:                                        int status;
                   1173: 
                   1174:                                        status = pa_89_parse_number(&s,&result);
                   1175:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1176:                                                if ( the_insn.fpof1 == SGL ) {
                   1177:                                                        result.number_part &= 0xF;
                   1178:                                                        result.number_part |= (result.L_R_select & 1) << 4;
                   1179:                                                }
                   1180:                                                opcode |= result.number_part << 21;
                   1181:                                                continue;
                   1182:                                        }
                   1183:                                }
                   1184:                                break;
                   1185: 
                   1186:                        case '6':   /* 5 bit register field at 15
                   1187:                                                (used in 'fmpyadd' and 'fmpysub') */
                   1188:                                {
                   1189:                                        struct pa_89_fp_reg_struct result;
                   1190:                                        int status;
                   1191: 
                   1192:                                        status = pa_89_parse_number(&s,&result);
                   1193:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1194:                                                if ( the_insn.fpof1 == SGL ) {
                   1195:                                                        result.number_part &= 0xF;
                   1196:                                                        result.number_part |= (result.L_R_select & 1) << 4;
                   1197:                                                }
                   1198:                                                opcode |= result.number_part << 16;
                   1199:                                                continue;
                   1200:                                        }
                   1201:                                }
                   1202:                                break;
                   1203: 
                   1204:                        case '7':   /* 5 bit register field at 31
                   1205:                                                (used in 'fmpyadd' and 'fmpysub') */
                   1206:                                {
                   1207:                                        struct pa_89_fp_reg_struct result;
                   1208:                                        int status;
                   1209: 
                   1210:                                        status = pa_89_parse_number(&s,&result);
                   1211:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1212:                                                if ( the_insn.fpof1 == SGL ) {
                   1213:                                                        result.number_part &= 0xF;
                   1214:                                                        result.number_part |= (result.L_R_select & 1) << 4;
                   1215:                                                }
                   1216:                                                opcode |= result.number_part;
                   1217:                                                continue;
                   1218:                                        }
                   1219:                                }
                   1220:                                break;
                   1221: 
                   1222:                        case '8':   /* 5 bit register field at 20
                   1223:                                                (used in 'fmpyadd' and 'fmpysub') */
                   1224:                                {
                   1225:                                        struct pa_89_fp_reg_struct result;
                   1226:                                        int status;
                   1227: 
                   1228:                                        status = pa_89_parse_number(&s,&result);
                   1229:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1230:                                                if ( the_insn.fpof1 == SGL ) {
                   1231:                                                        result.number_part &= 0xF;
                   1232:                                                        result.number_part |= (result.L_R_select & 1) << 4;
                   1233:                                                }
                   1234:                                                opcode |= result.number_part << 11;
                   1235:                                                continue;
                   1236:                                        }
                   1237:                                }
                   1238:                                break;
                   1239: 
                   1240:                        case '9':   /* 5 bit register field at 25
                   1241:                                                (used in 'fmpyadd' and 'fmpysub') */
                   1242:                                {
                   1243:                                        struct pa_89_fp_reg_struct result;
                   1244:                                        int status;
                   1245: 
                   1246:                                        status = pa_89_parse_number(&s,&result);
                   1247:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
                   1248:                                                if ( the_insn.fpof1 == SGL ) {
                   1249:                                                        result.number_part &= 0xF;
                   1250:                                                        result.number_part |= (result.L_R_select & 1) << 4;
                   1251:                                                }
                   1252:                                                opcode |= result.number_part << 6;
                   1253:                                                continue;
                   1254:                                        }
                   1255:                                }
                   1256:                                break;
                   1257: 
                   1258:                        case 'H':  /* Floating Point Operand Format at 26 for       */
                   1259:                                                /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
                   1260:                                                /* bits are switched from other FP Operand       */
                   1261:                                                /* formats. 1=SGL, 1=<none>, 0=DBL               */
                   1262:                                f = pa_parse_fp_format(&s);
                   1263:                                switch (f) {
                   1264:                                case SGL:
                   1265:                                        opcode |= 0x20;
                   1266:                                case DBL:
                   1267:                                        the_insn.fpof1 = f;
                   1268:                                        continue;
                   1269: 
                   1270:                                case QUAD:
                   1271:                                case ILLEGAL_FMT:
                   1272:                                default:
                   1273:                                        as_bad("Illegal Floating Point Operand Format for"
                   1274:                                                "this instruction: '%s'",s);
                   1275:                                }
                   1276:                                break;
                   1277: 
                   1278:                        case 'y' :  /* nullify at 26 */
                   1279:                                nullif = pa_parse_nullif(&s);
                   1280:                                opcode |= nullif << 5;
                   1281:                                continue;
                   1282:                                                
                   1283: /* bug #41317 .... [email protected] Mon May  2 17:53:29 PDT 1994
                   1284: 
                   1285:    These are for 'cache control hints'
                   1286:        
                   1287:        l       Store Instruction Cache Control Hint  (Table 5-8) with
                   1288:                Short displacement load and store completers (Table 5-11) 
                   1289:                 
                   1290:        L       Load and Clear Word Cache Control Hint (Table 5-9) with
                   1291:                Indexed load completers (Table 5-10)
                   1292: 
                   1293:        3       Store Instruction Cache Control Hint  (Table 5-8) with
                   1294:                Indexed load completers (Table 5-10)
                   1295: 
                   1296:        a       Load and Clear Word Cache Control Hint (Table 5-9) with
                   1297:                Short displacement load and store completers (Table 5-11)
                   1298: 
                   1299:        These parse ",cc" and encode "cc" in 2 bits at 20,
                   1300:        where "cc" encoding is as given in Tables 5-8, 5-9.
                   1301:     Refer to 'PA-RISC 1.1 Architecture and Instruction Set Reference
                   1302:        Manual, Second Edition' for the tables.
                   1303: */
                   1304: 
                   1305:                        case 'l' :  /* Store Instruction Cache Control Hint */
                   1306:                                                /* Short displacement load and store completers */
                   1307:                                opcode |= parse_completer_with_cache_control_hint(&s, 0, 'C');
                   1308:                                continue;
                   1309: 
                   1310:                        case 'L' :  /* Load and Clear Word Cache Control Hint */
                   1311:                                                /* Indexed load completers  */
                   1312:                                opcode |= parse_completer_with_cache_control_hint(&s, 1, 'c');
                   1313:                                continue;
                   1314: 
                   1315:                        case '3' :  /* Store Instruction Cache Control Hint */
                   1316:                                                /* Indexed load completers */
                   1317:                                opcode |= parse_completer_with_cache_control_hint(&s, 0, 'c');
                   1318:                                continue;
                   1319: 
                   1320:                        case 'a' :  /* Load and Clear Word Cache Control Hint */
                   1321:                                                /* Short displacement load and store completers */
                   1322:                                opcode |= parse_completer_with_cache_control_hint(&s, 1, 'C');
                   1323:                                continue;
                   1324: 
                   1325:                        default:
                   1326:                                abort();
                   1327:                        }
                   1328:                        break;
                   1329:                }
                   1330: 
                   1331:                if (match == FALSE)
                   1332:                {
                   1333:                /* Args don't match.  */
                   1334:                        if (&insn[1] - pa_opcodes < NUMOPCODES
                   1335:                                && !strcmp(insn->name, insn[1].name))
                   1336:                        {
                   1337:                                ++insn;
                   1338:                                s = argsStart;
                   1339:                                continue;
                   1340:                        }
                   1341:                        else
                   1342:                        {
                   1343:                                as_bad("Illegal operands");
                   1344:                                return;
                   1345:                        }
                   1346:                }
                   1347:                break;
                   1348:        }
                   1349: 
                   1350:        the_insn.opcode = opcode;
                   1351:        return;
                   1352: }    /* end pa_ip() */
                   1353: 
                   1354: /*
                   1355:     This is identical to the md_atof in m68k.c.  I think this is right,
                   1356:     but I'm not sure.
                   1357: 
                   1358:    Turn a string in input_line_pointer into a floating point constant of type
                   1359:    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
                   1360:    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
                   1361:  */
                   1362: 
                   1363: /* Equal to MAX_PRECISION in atof-ieee.c */
                   1364: #define MAX_LITTLENUMS 6
                   1365: 
                   1366: char *
                   1367: md_atof(
                   1368: int type,
                   1369: char *litP,
                   1370: int *sizeP)
                   1371: {
                   1372:     int        prec;
                   1373:     LITTLENUM_TYPE words[MAX_LITTLENUMS];
                   1374:     LITTLENUM_TYPE *wordP;
                   1375:     char       *t;
                   1376:     char       *atof_ieee();
                   1377: 
                   1378:     switch(type) {
                   1379: 
                   1380:     case 'f':
                   1381:     case 'F':
                   1382:     case 's':
                   1383:     case 'S':
                   1384:        prec = 2;
                   1385:        break;
                   1386: 
                   1387:     case 'd':
                   1388:     case 'D':
                   1389:     case 'r':
                   1390:     case 'R':
                   1391:        prec = 4;
                   1392:        break;
                   1393: 
                   1394:     case 'x':
                   1395:     case 'X':
                   1396:        prec = 6;
                   1397:        break;
                   1398: 
                   1399:     case 'p':
                   1400:     case 'P':
                   1401:        prec = 6;
                   1402:        break;
                   1403: 
                   1404:     default:
                   1405:        *sizeP=0;
                   1406:        return "Bad call to MD_ATOF()";
                   1407:     }
                   1408:     t=atof_ieee(input_line_pointer,type,words);
                   1409:     if(t)
                   1410:        input_line_pointer=t;
                   1411:     *sizeP=prec * sizeof(LITTLENUM_TYPE);
                   1412:     for(wordP=words;prec--;) {
                   1413:        md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
                   1414:        litP+=sizeof(LITTLENUM_TYPE);
                   1415:     }
                   1416:     return ""; /* Someone should teach Dean about null pointers */
                   1417: }
                   1418: 
                   1419: /*
                   1420:  * Write out big-endian.
                   1421:  */
                   1422: void
                   1423: md_number_to_chars(
                   1424: char *buf,
                   1425: long val,
                   1426: int n)
                   1427: {
                   1428: 
                   1429:     switch(n) {
                   1430: 
                   1431:     case 4:
                   1432:        *buf++ = val >> 24;
                   1433:        *buf++ = val >> 16;
                   1434:     case 2:
                   1435:        *buf++ = val >> 8;
                   1436:     case 1:
                   1437:        *buf = val;
                   1438:        break;
                   1439: 
                   1440:     default:
                   1441:        abort();
                   1442:     }
                   1443:     return;
                   1444: }
                   1445: 
                   1446: void
                   1447: md_number_to_imm(
                   1448: unsigned char *buf,
                   1449: long val,
                   1450: int n,
                   1451: fixS *fixP,
                   1452: int nsect)
                   1453: {
                   1454:        unsigned long w1,w2,w;
                   1455:        unsigned new_val = 0;
                   1456:        unsigned long left21, right14;
                   1457:        
                   1458:        if(fixP->fx_r_type == NO_RELOC ||
                   1459:           fixP->fx_r_type == HPPA_RELOC_VANILLA){
                   1460:            switch(n){
                   1461:            case 4:
                   1462:                *buf++ = val >> 24;
                   1463:                *buf++ = val >> 16;
                   1464:            case 2:
                   1465:                *buf++ = val >> 8;
                   1466:            case 1:
                   1467:                *buf = val;
                   1468:                break;
                   1469: 
                   1470:            default:
                   1471:                abort();
                   1472:            }
                   1473:            return;
                   1474:        }
                   1475: 
                   1476: 
                   1477:        calc_hppa_HILO(val - fixP->fx_offset, fixP->fx_offset,
                   1478:                       &left21, &right14);
                   1479: 
                   1480:        switch (fixP->fx_r_type) {
                   1481:     default:
                   1482:                break;
                   1483: /*     case 'j': */
                   1484:     case HPPA_RELOC_LO14 :
                   1485:                w = low_sign_unext(right14, 14); 
                   1486:                goto fixit;
                   1487: 
                   1488: /*     case 'k': */
                   1489:     case HPPA_RELOC_HI21 :
                   1490:                w = dis_assemble_21((left21>>11));
                   1491: fixit:
                   1492:       /* There is no guarantee that buf is word-aligned,       */
                   1493:       /* so the adjustment must be done the hard way.          */
                   1494: 
                   1495:                new_val  = (*buf & 0xff) << 24;
                   1496:                new_val |= (*(buf+1) & 0xff) << 16;
                   1497:                new_val |= (*(buf+2) & 0xff) << 8;
                   1498:                new_val |= (*(buf+3) & 0xff);
                   1499:                new_val |= w;   /* Now, make the adjustment */
                   1500:                md_number_to_chars(buf,new_val,4);
                   1501:                break;
                   1502: 
                   1503: /*     case 'W': */
                   1504:        case HPPA_RELOC_BL17 :
                   1505:                if ( !fixP->fx_addsy ) {
                   1506:                        val -= 4;       /* PA adjustment: a 0 disp is actually 4 bytes */
                   1507:                                                /* further because of the delay slot */
                   1508:                        val >>= 2;
                   1509:                        dis_assemble_17(val,&w1,&w2,&w);
                   1510:                /* There is no guarantee that buf is word-aligned,      */
                   1511:                /* so the adjustment must be done the hard way.         */
                   1512: 
                   1513:                new_val  = (*buf & 0xff) << 24;
                   1514:                new_val |= (*(buf+1) & 0xff) << 16;
                   1515:                new_val |= (*(buf+2) & 0xff) << 8;
                   1516:                new_val |= (*(buf+3) & 0xff);
                   1517:                new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
                   1518:                                      /* Now, do the adjustment */
                   1519:                md_number_to_chars(buf,new_val,4);
                   1520:       }
                   1521:       else {
                   1522:                unsigned long result;
                   1523:                val -= 4;       /* PA adjustment: a 0 disp is actually 4 bytes */
                   1524:                                                /* further because of the delay slot */
                   1525:                val >>= 2;
                   1526: 
                   1527:                result = sign_unext( val,17);
                   1528:                dis_assemble_17(result,&w1,&w2,&w);
                   1529:                /* There is no guarantee that buf is word-aligned,      */
                   1530:                /* so the adjustment must be done the hard way.         */
                   1531: 
                   1532:                new_val  = (*buf & 0xff) << 24;
                   1533:                new_val |= (*(buf+1) & 0xff) << 16;
                   1534:                new_val |= (*(buf+2) & 0xff) << 8;
                   1535:                new_val |= (*(buf+3) & 0xff);
                   1536:                new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
                   1537:                                      /* Now, do the adjustment */
                   1538:                md_number_to_chars(buf,new_val,4);
                   1539: 
                   1540:                }
                   1541:                break;
                   1542: /*     case 'z': */
                   1543:        case HPPA_RELOC_BR17 :
                   1544:        {
                   1545:                unsigned long result;
                   1546:                right14 >>= 2;
                   1547:                result = sign_unext(right14,17);
                   1548:                dis_assemble_17(result,&w1,&w2,&w);
                   1549:        /* There is no guarantee that buf is word-aligned,      */
                   1550:        /* so the adjustment must be done the hard way.         */
                   1551: 
                   1552:                new_val  = (*buf & 0xff) << 24;
                   1553:                new_val |= (*(buf+1) & 0xff) << 16;
                   1554:                new_val |= (*(buf+2) & 0xff) << 8;
                   1555:                new_val |= (*(buf+3) & 0xff);
                   1556:                new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
                   1557:                                      /* Now, do the adjustment */
                   1558:                md_number_to_chars(buf,new_val,4);
                   1559:      }
                   1560:                        break;
                   1561: /*     case '@': */
                   1562:     case HPPA_RELOC_JBSR :
                   1563: /*
                   1564:  * In case of the jbsr relocation no bytes are to be written to the 
                   1565:  * output.
                   1566:  * 
                   1567:  * SO DO NOTHING!
                   1568:  */
                   1569:       break;
                   1570:       
                   1571: /*       case 'w': */
                   1572: /* To take care of 12 bit label */
                   1573:       case HPPA_RELOC_12BRANCH :
                   1574:                if ( !fixP->fx_addsy ) {
                   1575:                        val -= 4;       /* PA adjustment: a 0 disp is actually 4 bytes */
                   1576:                                                /* further because of the delay slot */
                   1577:                        val >>= 2;
                   1578:                        dis_assemble_12(val,&w1,&w);
                   1579:                        /* There is no guarantee that buf is word-aligned,      */
                   1580:                        /* so the adjustment must be done the hard way.         */
                   1581: 
                   1582:                        new_val  = (*buf & 0xff) << 24;
                   1583:                        new_val |= (*(buf+1) & 0xff) << 16;
                   1584:                        new_val |= (*(buf+2) & 0xff) << 8;
                   1585:                        new_val |= (*(buf+3) & 0xff);
                   1586:                        new_val |= ( ( w1 << 2 ) | w ); /* Now, do the adjustment */
                   1587:                        md_number_to_chars(buf,new_val,4);
                   1588:                }
                   1589:                else {
                   1590:                        as_bad("Undefined symbol %s", fixP->fx_addsy->sy_name);
                   1591:                }
                   1592:                
                   1593:                 break;
                   1594:     }
                   1595: }
                   1596: 
                   1597: void
                   1598: md_convert_frag(
                   1599: fragS *fragP)
                   1600: {
                   1601:   unsigned int address;
                   1602: 
                   1603:   if ( fragP -> fr_type == rs_machine_dependent ) {
                   1604:     switch ( (int) fragP -> fr_subtype ) {
                   1605:     case 0:
                   1606:       fragP -> fr_type = rs_fill;
                   1607:       know( fragP -> fr_var == 1 );
                   1608:       know( fragP -> fr_next );
                   1609:       address = fragP -> fr_address + fragP -> fr_fix;
                   1610:       if ( address % fragP -> fr_offset ) {
                   1611:        fragP -> fr_offset =
                   1612:          fragP -> fr_next -> fr_address
                   1613:            -   fragP -> fr_address
                   1614:              - fragP -> fr_fix;
                   1615:       }
                   1616:       else
                   1617:        fragP -> fr_offset = 0;
                   1618:       break;
                   1619:     }
                   1620:   }
                   1621: }
                   1622: 
                   1623: int
                   1624: md_estimate_size_before_relax(
                   1625: fragS *fragP,
                   1626: int nsect)
                   1627: {
                   1628:   int size;
                   1629: 
                   1630:   size = 0;
                   1631: 
                   1632:   while ( (fragP->fr_fix + size) % fragP->fr_offset )
                   1633:     size++;
                   1634: 
                   1635:   return size;
                   1636: }
                   1637: 
                   1638: int
                   1639: md_parse_option(
                   1640: char **argP,
                   1641: int *cntP,
                   1642: char ***vecP)
                   1643: {
                   1644:     return 1;
                   1645: }
                   1646: 
                   1647: /*
                   1648: int is_end_of_statement()
                   1649: {
                   1650:   return (   (*input_line_pointer == '\n')
                   1651:          || (*input_line_pointer == ';')
                   1652:          || (*input_line_pointer == '!') );
                   1653: }
                   1654: */
                   1655: 
                   1656: static
                   1657: int
                   1658: parse_L_or_R(
                   1659: char *str)
                   1660: {
                   1661: /* not much work done as yet! */
                   1662:        switch (*str) {
                   1663:        case '%':
                   1664:        case '(':
                   1665:                return 0;       /* ie. not found */
                   1666:                break;
                   1667:        case 'L':
                   1668:        case 'l':
                   1669:                if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
                   1670:                        return 1; /* found */
                   1671:                else
                   1672:                        return 0; /* not found */
                   1673:                break;
                   1674:        case 'R':
                   1675:        case 'r':
                   1676:                if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
                   1677:                        return 2; /* found */
                   1678:                else
                   1679:                        return 0; /* not found */
                   1680:                break;
                   1681:        default: /* default is not found ... at least for the time being */
                   1682:                return 0;
                   1683:                break;
                   1684:        }
                   1685: }    /* end parse_L_or_R() */
                   1686: 
                   1687: static
                   1688: unsigned long
                   1689: parse_cache_control_hint(
                   1690: char   **s,       /* Note : the function changes '*s' */
                   1691: int     option)    /* option = 0 for store instruction */
                   1692:                    /* option = 1 for load and clear instruction */
                   1693: {
                   1694:        unsigned long cc = NO_CACHE_CONTROL_HINT;
                   1695:                                
                   1696:        if (**s == ',') {
                   1697:                (*s)++;
                   1698:                switch (option) {
                   1699:                case 0 : /* Store Instruction Cache Control Hint */ 
                   1700:                        if ( strncasecmp(*s,"bc",2) == 0 ) {
                   1701:                                /* BLOCK_COPY */
                   1702:                                (*s) += 2;
                   1703:                                cc = BC_OR_CO_CACHE_CONTROL_HINT;
                   1704:                                /* eat up extra blanks and tabs */
                   1705:                                while ( **s == ' ' || **s == '\t' )
                   1706:                                        (*s)++;
                   1707:                        } else
                   1708:                                as_fatal("Illegal Cache Control Hint: '%s'"
                   1709:                                        " - expected 'bc'",*s);
                   1710:                        break;
                   1711:                        
                   1712:                case 1 : /* Load and Clear Word Cache Control Hint */
                   1713:                        if ( strncasecmp(*s,"co",2) == 0 ) {
                   1714:                                /* COHERENT_OPERATION */
                   1715:                                (*s) +=2;
                   1716:                                cc = BC_OR_CO_CACHE_CONTROL_HINT;
                   1717:                                /* eat up extra blanks and tabs */
                   1718:                                while ( **s == ' ' || **s == '\t' )
                   1719:                                        (*s)++;
                   1720:                        } else
                   1721:                                as_fatal("Illegal Cache Control Hint: '%s'"
                   1722:                                        " - expected 'co'",*s);
                   1723:                        break;
                   1724:                        
                   1725:                default :
                   1726:                        as_fatal("Invalid option (%d) for parsing cache control hints",
                   1727:                                option);
                   1728:                        break;
                   1729:                }
                   1730:        }
                   1731:                /* else NO_HINT */
                   1732:                                
                   1733:        /*
                   1734:        * the completers have already eaten up extra blanks
                   1735:        * and tabs. So there is no need to do that again here.
                   1736:        */
                   1737:                                 
                   1738:        return cc;
                   1739: 
                   1740: }    /* end parse_cache_control_hint() */
                   1741: 
                   1742: static
                   1743: unsigned long
                   1744: parse_completer_with_cache_control_hint(
                   1745: char   **s,       /* Note : the function changes '*s' */
                   1746: int     option,    /* option = 0 for store instruction */
                   1747:                    /* option = 1 for load and clear instruction */
                   1748: char    completer) /* 'c' or 'C' */
                   1749: {
                   1750:        unsigned long i, result = (unsigned long) 0UL;
                   1751:        int m, a, u;
                   1752:        
                   1753:        switch (completer) {
                   1754:        case 'c':   /* indexed load completer. */
                   1755:                i = m = u = 0;
                   1756:                while ( **s == ',' && i < 3 ) {
                   1757:                        (*s)++;
                   1758:                        if ( strncasecmp((*s),"sm",2) == 0 ) {
                   1759:                                m = u = 1;
                   1760:                                (*s)++;
                   1761:                                i++;
                   1762:                        }
                   1763:                        else if ( strncasecmp((*s),"m",1) == 0 )
                   1764:                                m = 1;
                   1765:                        else if ( strncasecmp((*s),"s",1) == 0 )
                   1766:                                u = 1;
                   1767:                        else if ( strncmp((*s),",",1) == 0 ) /* no completer */
                   1768:                                result |= parse_cache_control_hint(s, option);
                   1769:                        else if ( (strncasecmp((*s),"c",1) == 0) ||
                   1770:                                  (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
                   1771:                                (*s)--;
                   1772:                                result |= parse_cache_control_hint(s, option);
                   1773:                        }
                   1774:                        else
                   1775:                                as_bad("Unrecognized Indexed Load"
                   1776:                                        "Completer with cache control hints...assuming 0");
                   1777:                        if (result == (unsigned long)0UL)
                   1778:                                (*s)++;
                   1779:                        i++;
                   1780:                }
                   1781:                if ( i > 3 )
                   1782:                        as_bad("Illegal Indexed Load Completer with cache control hints"
                   1783:                        " Syntax... extras ignored");
                   1784:                while ( **s == ' ' || **s == '\t' )
                   1785:                        (*s)++;
                   1786:   
                   1787:                result |= m << 5;
                   1788:                result |= u << 13;
                   1789:                break;
                   1790:        case 'C':   /* short load and store completer */
                   1791:                i = m = a = 0;
                   1792:                while ( **s == ',' && i < 2 ) {
                   1793:                        (*s)++;
                   1794:                        if ( strncasecmp((*s),"ma",2) == 0 ) {
                   1795:                                a = 0;
                   1796:                                m = 1;
                   1797:                        }
                   1798:                        else if ( strncasecmp((*s),"mb",2) == 0 ) {
                   1799:                                m = a = 1;
                   1800:                        }
                   1801:                        else if ( strncmp((*s),",",1) == 0 ) /* no completer */
                   1802:                                result |= parse_cache_control_hint(s, option);
                   1803:                        else if ( (strncasecmp((*s),"c",1) == 0) ||
                   1804:                                  (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
                   1805:                                (*s)--;
                   1806:                                result |= parse_cache_control_hint(s, option);
                   1807:                        }
                   1808:                        else
                   1809:                                as_bad("Unrecognized Indexed Load Completer"
                   1810:                                "...assuming 0");
                   1811:                        i++;
                   1812:                        (*s) += 2;
                   1813:                }
                   1814:                while ( **s == ' ' || **s == '\t' )
                   1815:                        (*s)++;
                   1816:                result |= m << 5;
                   1817:                result |= a << 13;
                   1818:                break;
                   1819:                
                   1820:                
                   1821:        default :
                   1822:                        as_fatal("Invalid completer (%c) for parsing cache control hints",
                   1823:                                completer);
                   1824:                        break;
                   1825:        }
                   1826:        return result;
                   1827: }    /* end parse_completer_with_cache_control_hint() */
                   1828: 
                   1829: /* end hppa.c */

unix.superglobalmegacorp.com

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