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

1.1     ! root        1: #undef CHECK_WORD_IMMEDIATES /* bug #26863 */
        !             2: 
        !             3: /* m68k.c  All the m68020 specific stuff in one convenient, huge,
        !             4:    slow to compile, easy to find file.
        !             5:    Copyright (C) 1987 Free Software Foundation, Inc.
        !             6: 
        !             7: This file is part of GAS, the GNU Assembler.
        !             8: 
        !             9: GAS is free software; you can redistribute it and/or modify
        !            10: it under the terms of the GNU General Public License as published by
        !            11: the Free Software Foundation; either version 1, or (at your option)
        !            12: any later version.
        !            13: 
        !            14: GAS is distributed in the hope that it will be useful,
        !            15: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            17: GNU General Public License for more details.
        !            18: 
        !            19: You should have received a copy of the GNU General Public License
        !            20: along with GAS; see the file COPYING.  If not, write to
        !            21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            22: 
        !            23: #include <stdio.h>
        !            24: #include <stdlib.h>
        !            25: #include <string.h>
        !            26: #include <ctype.h>
        !            27: #include "m68k-opcode.h"
        !            28: #include "as.h"
        !            29: #include "obstack.h"
        !            30: #include "struc-symbol.h"
        !            31: #include "flonum.h"
        !            32: #include "expr.h"
        !            33: #include "hash.h"
        !            34: #include "frags.h"
        !            35: #include "fixes.h"
        !            36: #include "read.h"
        !            37: #include "md.h"
        !            38: #ifndef NeXT
        !            39: #include "m68k.h"
        !            40: #endif /* NeXT */
        !            41: #include "xmalloc.h"
        !            42: #include "sections.h"
        !            43: #include "messages.h"
        !            44: #include "atof-ieee.h"
        !            45: #include "input-scrub.h"
        !            46: #include "symbols.h"
        !            47: 
        !            48: /*
        !            49:  * These are the default cputype and cpusubtype for the m68k architecture.
        !            50:  */
        !            51: const cpu_type_t md_cputype = CPU_TYPE_MC680x0;
        !            52: cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_MC680x0_ALL;
        !            53: 
        !            54: /* This is the byte sex for the m68k architecture */
        !            55: const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
        !            56: 
        !            57: /*
        !            58:  * This array holds the chars that always start a comment.  If the
        !            59:  * pre-processor is disabled, these aren't very useful.
        !            60:  */
        !            61: const char md_comment_chars[] = "|";
        !            62: 
        !            63: /*
        !            64:  * This array holds the chars that only start a comment at the beginning of
        !            65:  * a line.  If the line seems to have the form '# 123 filename'
        !            66:  * .line and .file directives will appear in the pre-processed output.
        !            67:  *
        !            68:  * Note that input_file.c hand checks for '#' at the beginning of the
        !            69:  * first line of the input file.  This is because the compiler outputs
        !            70:  * #NO_APP at the beginning of its output.
        !            71:  *
        !            72:  * Also note that a '/' followed by a '*' will always start a comment.
        !            73:  */
        !            74: const char md_line_comment_chars[] = "#";
        !            75: 
        !            76: /* Chars that can be used to separate mant from exp in floating point nums. */
        !            77: const char md_EXP_CHARS[] = "eE";
        !            78: 
        !            79: /*
        !            80:  * Chars that mean this number is a floating point constant.
        !            81:  * As in 0f12.456
        !            82:  * or    0d1.2345e12
        !            83:  *
        !            84:  * Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
        !            85:  * changed in read.c .  Ideally it shouldn't have to know about it at all,
        !            86:  * but nothing is ideal around here.
        !            87:  */
        !            88: const char md_FLT_CHARS[] = "rRsSfFdDxXeEpP";
        !            89: 
        !            90: /* Its an arbitrary name:  This means I don't approve of it */
        !            91: /* See flames below */
        !            92: static struct obstack robyn;
        !            93: 
        !            94: /*
        !            95:  * These macros are used to encode a mode for the rlx_more field of the struct
        !            96:  * relax_typeS in the array md_relax_table below.  The array is indexed by a
        !            97:  * TAB(x,y) value where x is one of BRANCH, FBRANCH, ... and y is BYTE, SHORT,
        !            98:  * ...  Thus the array md_relax_table below is declared to match this use of
        !            99:  * indexes.  The macro TABTYPE(xy) take the value and returns one of BRANCH,
        !           100:  * FBRANCH, ...
        !           101:  */
        !           102: #define TAB(x,y)       (((x)<<2)+(y))
        !           103: #define TABTYPE(xy)     ((xy) >> 2)
        !           104: 
        !           105: #define BRANCH         1
        !           106: #define FBRANCH                2
        !           107: #define PCREL          3
        !           108: #define BCC68000        4
        !           109: #define DBCC            5
        !           110: 
        !           111: #define BYTE           0
        !           112: #define SHORT          1
        !           113: #define LONG           2
        !           114: #define SZ_UNDEF       3
        !           115: 
        !           116: /*
        !           117:  * BCC68000 is for patching in an extra jmp instruction for long offsets
        !           118:  * on the 68000.  The 68000 doesn't support long branches with branchs.
        !           119:  */
        !           120: 
        !           121: /*
        !           122:  * Note that calls to frag_var need to specify the maximum expansion needed.
        !           123:  * This is currently 10 bytes for DBCC.
        !           124:  */
        !           125: 
        !           126: /*
        !           127:  * This table desribes how you change sizes for the various types of variable
        !           128:  * size expressions.  This version only supports two kinds.
        !           129:  * The fields are:
        !           130:  *     How far Forward this mode will reach:
        !           131:  *     How far Backward this mode will reach:
        !           132:  *     How many bytes this mode will add to the size of the frag
        !           133:  *     Which mode to go to if the offset won't fit in this one
        !           134:  */
        !           135: const
        !           136: relax_typeS
        !           137: md_relax_table[] = {
        !           138: { 1,           1,              0,      0 },    /* First entries aren't used */
        !           139: { 1,           1,              0,      0 },    /* For no good reason except */
        !           140: { 1,           1,              0,      0 },    /* that the VAX doesn't either */
        !           141: { 1,           1,              0,      0 },
        !           142: 
        !           143: { (127),       (-128),         0,      TAB(BRANCH,SHORT)},
        !           144: { (32767),     (-32768),       2,      TAB(BRANCH,LONG) },
        !           145: { 0,           0,              4,      0 },
        !           146: { 1,           1,              0,      0 },
        !           147: 
        !           148: { 1,           1,              0,      0 },    /* FBRANCH doesn't come BYTE */
        !           149: { (32767),     (-32768),       2,      TAB(FBRANCH,LONG)},
        !           150: { 0,           0,              4,      0 },
        !           151: { 1,           1,              0,      0 },
        !           152: 
        !           153: { 1,           1,              0,      0 },    /* PCREL doesn't come BYTE */
        !           154: { (32767),     (-32768),       2,      TAB(PCREL,LONG)},
        !           155: { 0,           0,              4,      0 },
        !           156: { 1,           1,              0,      0 },
        !           157: 
        !           158: { (127),       (-128),         0,      TAB(BCC68000,SHORT)},
        !           159: { (32767),     (-32768),       2,      TAB(BCC68000,LONG) },
        !           160: { 0,           0,              6,      0 },    /* jmp long space */
        !           161: { 1,           1,              0,      0 },
        !           162: 
        !           163: { 1,           1,              0,      0 },    /* DBCC doesn't come BYTE */
        !           164: { (32767),     (-32768),       2,      TAB(DBCC,LONG) },
        !           165: { 0,           0,              10,     0 },    /* bra/jmp long space */
        !           166: { 1,           1,              0,      0 },
        !           167: 
        !           168: };
        !           169: 
        !           170: static void s_even(
        !           171:     int value);
        !           172: static void s_proc(
        !           173:     int value);
        !           174: 
        !           175: /*
        !           176:  * These are the machine dependent pseudo-ops.  These are included so
        !           177:  * the assembler can work on the output from the SUN C compiler, which
        !           178:  * generates these.
        !           179:  */
        !           180: 
        !           181: /* This table describes all the machine specific pseudo-ops the assembler
        !           182:  * has to support.  The fields are:
        !           183:  *       pseudo-op name without dot
        !           184:  *       function to call to execute this pseudo-op
        !           185:  *       Integer arg to pass to the function
        !           186:  */
        !           187: const pseudo_typeS md_pseudo_table[] = {
        !           188:        { "float",      float_cons,     'f'     },
        !           189:        { "int",        cons,           4       },
        !           190:        { "word",       cons,           2       },
        !           191:        { "quad",       big_cons,       8       },
        !           192:        { "octa",       big_cons,       16      },
        !           193:        { "even",       s_even,         0       },
        !           194:        { "skip",       s_space,        0       },
        !           195:        { "proc",       s_proc,         0       },
        !           196:        { 0,            0,              0       }
        !           197: };
        !           198: 
        !           199: #define issbyte(x)     ((x)>=-128 && (x)<=127)
        !           200: #define isubyte(x)     ((x)>=0 && (x)<=255)
        !           201: #define issword(x)     ((x)>=-32768 && (x)<=32767)
        !           202: #define isuword(x)     ((x)>=0 && (x)<=65535)
        !           203: 
        !           204: #define isbyte(x)      ((x)>=-128 && (x)<=255)
        !           205: #define isword(x)      ((x)>=-32768 && (x)<=65535)
        !           206: #define islong(x)      (1)
        !           207: 
        !           208: /* Operands we can parse:  (And associated modes)
        !           209: 
        !           210: numb:  8 bit num
        !           211: numw:  16 bit num
        !           212: numl:  32 bit num
        !           213: dreg:  data reg 0-7
        !           214: reg:   address or data register
        !           215: areg:  address register
        !           216: apc:   address register, PC, ZPC or empty string
        !           217: num:   16 or 32 bit num
        !           218: num2:  like num
        !           219: sz:    w or l          if omitted, l assumed
        !           220: scale: 1 2 4 or 8      if omitted, 1 assumed
        !           221: 
        !           222: 7.4 IMMED #num                         --> NUM
        !           223: 0.? DREG  dreg                         --> dreg
        !           224: 1.? AREG  areg                         --> areg
        !           225: 2.? AINDR areg@                                --> *(areg)
        !           226: 3.? AINC  areg@+                       --> *(areg++)
        !           227: 4.? ADEC  areg@-                       --> *(--areg)
        !           228: 5.? AOFF  apc@(numw)                   --> *(apc+numw) -- empty string and ZPC not allowed here
        !           229: 6.? AINDX apc@(num,reg:sz:scale)       --> *(apc+num+reg*scale)
        !           230: 6.? AINDX apc@(reg:sz:scale)           --> same, with num=0
        !           231: 6.? APODX apc@(num)@(num2,reg:sz:scale)        --> *(*(apc+num)+num2+reg*scale)
        !           232: 6.? APODX apc@(num)@(reg:sz:scale)     --> same, with num2=0
        !           233: 6.? AMIND apc@(num)@(num2)             --> *(*(apc+num)+num2) (previous mode without an index reg)
        !           234: 6.? APRDX apc@(num,reg:sz:scale)@(num2)        --> *(*(apc+num+reg*scale)+num2)
        !           235: 6.? APRDX apc@(reg:sz:scale)@(num2)    --> same, with num=0
        !           236: 7.0 ABSL  num:sz                       --> *(num)
        !           237:           num                          --> *(num) (sz L assumed)
        !           238: *** MSCR  otherreg                     --> Magic
        !           239: With -l option
        !           240: 5.? AOFF  apc@(num)                    --> *(apc+num) -- empty string and ZPC not allowed here still
        !           241: 
        !           242: examples:
        !           243:        #foo    #0x35   #12
        !           244:        d2
        !           245:        a4
        !           246:        a3@
        !           247:        a5@+
        !           248:        a6@-
        !           249:        a2@(12) pc@(14)
        !           250:        a1@(5,d2:w:1)   @(45,d6:l:4)
        !           251:        pc@(a2)         @(d4)
        !           252:        etc . . .
        !           253: 
        !           254: 
        !           255: #name@(numw)   -->turn into PC rel mode
        !           256: apc@(num8,reg:sz:scale)                --> *(apc+num8+reg*scale)
        !           257: 
        !           258: */
        !           259: 
        !           260: #define IMMED  1
        !           261: #define DREG   2
        !           262: #define AREG   3
        !           263: #define AINDR  4
        !           264: #define ADEC   5
        !           265: #define AINC   6
        !           266: #define AOFF   7
        !           267: #define AINDX  8
        !           268: #define APODX  9
        !           269: #define AMIND  10
        !           270: #define APRDX  11
        !           271: #define ABSL   12
        !           272: #define MSCR   13
        !           273: #define REGLST 14
        !           274: 
        !           275: #define FAIL   0
        !           276: #define OK     1
        !           277: 
        !           278: /* DATA and ADDR have to be contiguous, so that reg-DATA gives 0-7==data reg,
        !           279:    8-15==addr reg for operands that take both types */
        !           280: #define DATA   1               /*   1- 8 == data registers 0-7 */
        !           281: #define ADDR   (DATA+8)        /*   9-16 == address regs 0-7 */
        !           282: #define FPREG  (ADDR+8)        /*  17-24 Eight FP registers */
        !           283: #define COPNUM (FPREG+8)       /*  25-32 Co-processor #1-#8 */
        !           284: #undef PC
        !           285: #define PC     (COPNUM+8)      /*  33 Program counter */
        !           286: #define ZPC    (PC+1)          /*  34 Hack for Program space, but 0 addressing */
        !           287: #define SR     (ZPC+1)         /*  35 Status Reg */
        !           288: #define CCR    (SR+1)          /*  36 Condition code Reg */
        !           289: 
        !           290: #define FPI    (CCR+1)         /*  37 floating-point instruction register */
        !           291: #define FPS    (FPI+1)         /*  38 floating-point status register */
        !           292: #define FPC    (FPS+1)         /*  39 floating-point condition register */
        !           293: 
        !           294: /* These have to be in order for the movec instruction to work. */
        !           295: /* The comment above should read: All the registers that can be in a movec
        !           296:    instruction must be bounded by USP and MSP (or SRP if BUILTIN_MMUS is
        !           297:    defined) for the 'J' kind of operand to be checked correctly in m68_ip() */
        !           298: #define USP    (FPC+1)         /*  40 User Stack Pointer */
        !           299: #define ISP    (USP+1)         /*  41 Interrupt stack pointer */
        !           300: #define SFC    (ISP+1)         /*  42 Source function control code register */
        !           301: #define DFC    (SFC+1)         /*  43 Destination function code register */
        !           302: #define CACR   (DFC+1)         /*  44 Cashe control register */
        !           303: #define VBR    (CACR+1)        /*  45 wector base register */
        !           304: #define CAAR   (VBR+1)         /*  46 Cashe address register */
        !           305: #define MSP    (CAAR+1)        /*  47 Master stack pointer */
        !           306: 
        !           307: #ifdef BUILTIN_MMUS
        !           308: /* mc68040 mmu registers, can be used in a movec instruction  */
        !           309: #define        ITT0    (MSP+1)  /* 48 instruction transparent translation register 0 */
        !           310: #define        ITT1    (ITT0+1) /* 49 instruction transparent translation register 1 */
        !           311: #define        DTT0    (ITT1+1) /* 50 data transparent translation register 0 */
        !           312: #define        DTT1    (DTT0+1) /* 51 data transparent translation register 1 */
        !           313: #define        URP     (DTT1+1) /* 53 user root pointer */
        !           314: 
        !           315: /* mc68030 and mc68040 mmu registers, can be used in a movec instruction */
        !           316: #define        MMUSR   (URP+1)  /* 52 MMU status register */
        !           317: #define TC     (MMUSR+1)/* 54 MMU translation control register */
        !           318: #define SRP    (TC+1)   /* 55 supervisor root pointer */
        !           319: 
        !           320: /* mc68030 mmu registers, can't be used in a movec instruction (but rather in a
        !           321:    pmove instruction) */
        !           322: #define CRP    (SRP+1)  /* 56 cpu root pointer */
        !           323: #define        TT0     (CRP+1)  /* 57 transparent translation register 0 */
        !           324: #define        TT1     (TT0+1)  /* 58 transparent translation register 0 */
        !           325: 
        !           326: /* mc68040 operands to cache instructions  */
        !           327: #define        IC      (TT1+1)  /* 59 instruction cache */
        !           328: #define        DC      (IC+1)   /* 60 data cache */
        !           329: #define        BC      (DC+1)   /* 61 both instruction and data caches */
        !           330: #endif /* BUILTIN_MMUS */
        !           331: 
        !           332: #ifdef m68851
        !           333: /*
        !           334:  * these defines should be in m68k.c but
        !           335:  * i put them here to keep all the m68851 stuff
        !           336:  * together -rab
        !           337:  * JF--Make sure these #s don't clash with the ones in m68k.c
        !           338:  * That would be BAD.
        !           339:  */
        !           340: #define TC     (MSP+1)         /* 48 */
        !           341: #define DRP    (TC+1)          /* 49 */
        !           342: #define SRP    (DRP+1)         /* 50 */
        !           343: #define CRP    (SRP+1)         /* 51 */
        !           344: #define CAL    (CRP+1)         /* 52 */
        !           345: #define VAL    (CAL+1)         /* 53 */
        !           346: #define SCC    (VAL+1)         /* 54 */
        !           347: #define AC     (SCC+1)         /* 55 */
        !           348: #define BAD    (AC+1)          /* 56,57,58,59, 60,61,62,63 */
        !           349: #define BAC    (BAD+8)         /* 64,65,66,67, 68,69,70,71 */
        !           350: #define PSR    (BAC+8)         /* 72 */
        !           351: #define PCSR   (PSR+1)         /* 73 */
        !           352: #endif m68851
        !           353: 
        !           354: 
        !           355: /* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */
        !           356: /* I think. . .  */
        !           357: 
        !           358: #undef SP
        !           359: #define        SP      ADDR+7
        !           360: 
        !           361: /* JF these tables here are for speed at the expense of size */
        !           362: /* You can replace them with the #if 0 versions if you really
        !           363:    need space and don't mind it running a bit slower */
        !           364: 
        !           365: static char mklower_table[256];
        !           366: #define mklower(c) (mklower_table[(unsigned char)(c)])
        !           367: static char notend_table[256];
        !           368: static char alt_notend_table[256];
        !           369: #define notend(s) ( !(notend_table[(unsigned char)(*s)] || (*s==':' &&\
        !           370:  alt_notend_table[(unsigned char)(s[1])])))
        !           371: 
        !           372: #if 0
        !           373: #define mklower(c)     (isupper(c) ? tolower(c) : c)
        !           374: #endif
        !           375: 
        !           376: 
        !           377: struct m68k_exp {
        !           378:        char    *e_beg;
        !           379:        char    *e_end;
        !           380:        expressionS e_exp;
        !           381:        short   e_siz;          /* 0== default 1==short/byte 2==word 3==long */
        !           382: };
        !           383: 
        !           384: /* Internal form of an operand.  */
        !           385: struct m68k_op {
        !           386:        char    *error;         /* Couldn't parse it */
        !           387:        int     mode;           /* What mode this instruction is in.  */
        !           388:        unsigned long int       reg;            /* Base register */
        !           389:        struct m68k_exp *con1;
        !           390:        int     ireg;           /* Index register */
        !           391:        int     isiz;           /* 0==unspec  1==byte(?)  2==short  3==long  */
        !           392:        int     imul;           /* Multipy ireg by this (1,2,4,or 8) */
        !           393:        struct  m68k_exp *con2;
        !           394: };
        !           395: 
        !           396: /* internal form of a 68020 instruction */
        !           397: struct m68_it {
        !           398:        char    *error;
        !           399:        char    *args;          /* list of opcode info */
        !           400:        int     numargs;
        !           401: 
        !           402: #ifdef NeXT
        !           403:        char    *cpus;
        !           404: #endif /* NeXT */
        !           405:        int     numo;           /* Number of shorts in opcode */
        !           406:        short   opcode[11];
        !           407: 
        !           408:        struct m68k_op operands[6];
        !           409: 
        !           410:        int     nexp;           /* number of exprs in use */
        !           411:        struct m68k_exp exprs[4];
        !           412: 
        !           413:        int     nfrag;          /* Number of frags we have to produce */
        !           414:        struct {
        !           415:                int fragoff;    /* Where in the current opcode[] the frag ends */
        !           416:                symbolS *fadd;
        !           417:                long int foff;
        !           418:                int fragty;
        !           419:        } fragb[4];
        !           420: 
        !           421:        int     nrel;           /* Num of reloc strucs in use */
        !           422:        struct  {
        !           423:                int     n;
        !           424:                symbolS *add,
        !           425:                        *sub;
        !           426:                long int off;
        !           427:                char    wid;
        !           428:                char    pcrel;
        !           429:        } reloc[5];             /* Five is enough??? */
        !           430: };
        !           431: 
        !           432: static struct m68_it the_ins;          /* the instruction being assembled */
        !           433: 
        !           434: 
        !           435: /* Macros for adding things to the m68_it struct */
        !           436: 
        !           437: #define addword(w)     the_ins.opcode[the_ins.numo++]=(w)
        !           438: 
        !           439: /* Like addword, but goes BEFORE general operands */
        !           440: #define insop(w)       {int z;\
        !           441:  for(z=the_ins.numo;z>opcode->m_codenum;--z)\
        !           442:    the_ins.opcode[z]=the_ins.opcode[z-1];\
        !           443:  for(z=0;z<the_ins.nrel;z++)\
        !           444:    the_ins.reloc[z].n+=2;\
        !           445:  the_ins.opcode[opcode->m_codenum]=(w);\
        !           446:  the_ins.numo++;\
        !           447: }
        !           448: 
        !           449: 
        !           450: #define add_exp(beg,end) (\
        !           451:        the_ins.exprs[the_ins.nexp].e_beg=(beg),\
        !           452:        the_ins.exprs[the_ins.nexp].e_end=(end),\
        !           453:        &the_ins.exprs[the_ins.nexp++]\
        !           454: )
        !           455: 
        !           456: 
        !           457: /* The numo+1 kludge is so we can hit the low order byte of the prev word. Blecch*/
        !           458: #define add_fix(width,exp,pc_rel) {\
        !           459:        the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \
        !           460:                (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\
        !           461:        the_ins.reloc[the_ins.nrel].add=adds((exp));\
        !           462:        the_ins.reloc[the_ins.nrel].sub=subs((exp));\
        !           463:        the_ins.reloc[the_ins.nrel].off=offs((exp));\
        !           464:        the_ins.reloc[the_ins.nrel].wid=(width);\
        !           465:        the_ins.reloc[the_ins.nrel++].pcrel=(pc_rel);\
        !           466: }
        !           467: 
        !           468: #define add_frag(add,off,type)  {\
        !           469:        the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\
        !           470:        the_ins.fragb[the_ins.nfrag].fadd=(add);\
        !           471:        the_ins.fragb[the_ins.nfrag].foff=(off);\
        !           472:        the_ins.fragb[the_ins.nfrag++].fragty=(type);\
        !           473: }
        !           474: 
        !           475: #define isvar(exp)     ((exp) && (adds(exp) || subs(exp)))
        !           476: 
        !           477: #define seg(exp)       ((exp)->e_exp.X_seg)
        !           478: #define adds(exp)      ((exp)->e_exp.X_add_symbol)
        !           479: #define subs(exp)      ((exp)->e_exp.X_subtract_symbol)
        !           480: #define offs(exp)      ((exp)->e_exp.X_add_number)
        !           481: 
        !           482: 
        !           483: struct m68_incant {
        !           484:        char *m_operands;
        !           485:        unsigned long m_opcode;
        !           486:        short m_opnum;
        !           487:        short m_codenum;
        !           488: #ifdef NeXT
        !           489:        char *m_cpus;
        !           490: #endif /* NeXT */
        !           491:        struct m68_incant *m_next;
        !           492: };
        !           493: 
        !           494: #define getone(x)      ((((x)->m_opcode)>>16)&0xffff)
        !           495: #define gettwo(x)      (((x)->m_opcode)&0xffff)
        !           496: 
        !           497: /*
        !           498:  * Declarations static functions in this file.
        !           499:  */
        !           500: static int m68k_reg_parse(
        !           501:     char **ccp);
        !           502: static int m68k_ip_op(
        !           503:     char *str,
        !           504:     struct m68k_op *opP);
        !           505: static int try_index(
        !           506:     char **s,
        !           507:     struct m68k_op *opP);
        !           508: static void m68_ip(
        !           509:     char *instring);
        !           510: static int get_regs(
        !           511:     int i,
        !           512:     struct m68k_op *opP,
        !           513:     char *str);
        !           514: static int reverse_16_bits(
        !           515:     int in);
        !           516: static int reverse_8_bits(
        !           517:     int in);
        !           518: static void install_operand(
        !           519:     int mode,
        !           520:     int val);
        !           521: static void install_gen_operand(
        !           522:     int mode,
        !           523:     int val);
        !           524: static char *crack_operand(
        !           525:     char *str,
        !           526:     struct m68k_op *opP);
        !           527: static int get_num(
        !           528:     struct m68k_exp *exp,
        !           529:     int ok);
        !           530: 
        !           531: /* JF modified this to handle cases where the first part of a symbol name
        !           532:    looks like a register */
        !           533: 
        !           534: static
        !           535: int
        !           536: m68k_reg_parse(
        !           537: char **ccp)
        !           538: {
        !           539:        register char c1,
        !           540:                c2,
        !           541:                c3,
        !           542:                c4;
        !           543: #ifdef BUILTIN_MMUS
        !           544:        char    c5;
        !           545: #endif
        !           546:        register int n = 0,
        !           547:                ret = 0;
        !           548: 
        !           549:        c1=mklower(ccp[0][0]);
        !           550:        c2=mklower(ccp[0][1]);
        !           551:        c3=mklower(ccp[0][2]);
        !           552:        c4=mklower(ccp[0][3]);
        !           553: #ifdef BUILTIN_MMUS
        !           554:        c5=mklower(ccp[0][4]);
        !           555: #endif
        !           556: 
        !           557:        switch(c1) {
        !           558:        case 'a':
        !           559:                if(c2>='0' && c2<='7') {
        !           560:                        n=2;
        !           561:                        ret=ADDR+c2-'0';
        !           562:                }
        !           563: #ifdef m68851
        !           564:                else if (c2 == 'c') {
        !           565:                        n = 2;
        !           566:                        ret = AC;
        !           567:                }
        !           568: #endif
        !           569:                break;
        !           570: #ifdef m68851
        !           571:        case 'b':
        !           572:                if (c2 == 'a') {
        !           573:                        if (c3 == 'd') {
        !           574:                                if (c4 >= '0' && c4 <= '7') {
        !           575:                                        n = 4;
        !           576:                                        ret = BAD + c4 - '0';
        !           577:                                }
        !           578:                        }
        !           579:                        if (c3 == 'c') {
        !           580:                                if (c4 >= '0' && c4 <= '7') {
        !           581:                                        n = 4;
        !           582:                                        ret = BAC + c4 - '0';
        !           583:                                }
        !           584:                        }
        !           585:                }
        !           586:                break;
        !           587: #endif
        !           588: #ifdef BUILTIN_MMUS
        !           589:        case 'b':
        !           590:                if (c2 == 'c') {
        !           591:                        n = 2;
        !           592:                        ret = (BC);
        !           593:                }
        !           594:                break;
        !           595: #endif
        !           596:        case 'c':
        !           597: #ifdef m68851
        !           598:                if (c2 == 'a' && c3 == 'l') {
        !           599:                        n = 3;
        !           600:                        ret = CAL;
        !           601:                } else
        !           602: #endif
        !           603:                        /* This supports both CCR and CC as the ccr reg. */
        !           604:                if(c2=='c' && c3=='r') {
        !           605:                        n=3;
        !           606:                        ret = CCR;
        !           607:                } else if(c2=='c') {
        !           608:                        n=2;
        !           609:                        ret = CCR;
        !           610:                } else if(c2=='a' && (c3=='a' || c3=='c') && c4=='r') {
        !           611:                        n=4;
        !           612:                        ret = c3=='a' ? CAAR : CACR;
        !           613:                }
        !           614: #if defined(m68851) || defined (BUILTIN_MMUS)
        !           615:                else if (c2 == 'r' && c3 == 'p') {
        !           616:                        n = 3;
        !           617:                        ret = (CRP);
        !           618:                }
        !           619: #endif
        !           620:                break;
        !           621:        case 'd':
        !           622:                if(c2>='0' && c2<='7') {
        !           623:                        n=2;
        !           624:                        ret = DATA+c2-'0';
        !           625:                } else if(c2=='f' && c3=='c') {
        !           626:                        n=3;
        !           627:                        ret = DFC;
        !           628:                }
        !           629: #ifdef m68851
        !           630:                else if (c2 == 'r' && c3 == 'p') {
        !           631:                        n = 3;
        !           632:                        ret = (DRP);
        !           633:                }
        !           634: #endif
        !           635: #ifdef BUILTIN_MMUS
        !           636:                else if (c2 == 't' && c3 == 't' && (c4 == '0' || c4 == '1')) {
        !           637:                        n = 4;
        !           638:                        if(c4 == '0')
        !           639:                            ret = (DTT0);
        !           640:                        else
        !           641:                            ret = (DTT1);
        !           642:                }
        !           643:                else if (c2 == 'c') {
        !           644:                        n = 2;
        !           645:                        ret = (DC);
        !           646:                }
        !           647: #endif
        !           648:                break;
        !           649:        case 'f':
        !           650:                if(c2=='p') {
        !           651:                        if(c3>='0' && c3<='7') {
        !           652:                                n=3;
        !           653:                                ret = FPREG+c3-'0';
        !           654:                                if(c4==':')
        !           655:                                        ccp[0][3]=',';
        !           656:                        } else if(c3=='i') {
        !           657:                                n=3;
        !           658:                                ret = FPI;
        !           659:                        } else if(c3=='s') {
        !           660:                                n= (c4 == 'r' ? 4 : 3);
        !           661:                                ret = FPS;
        !           662:                        } else if(c3=='c') {
        !           663:                                n= (c4 == 'r' ? 4 : 3);
        !           664:                                ret = FPC;
        !           665:                        }
        !           666:                }
        !           667:                break;
        !           668:        case 'i':
        !           669:                if(c2=='s' && c3=='p') {
        !           670:                        n=3;
        !           671:                        ret = ISP;
        !           672:                }
        !           673: #ifdef BUILTIN_MMUS
        !           674:                else if (c2 == 't' && c3 == 't' && (c4 == '0' || c4 == '1')) {
        !           675:                        n = 4;
        !           676:                        if(c4 == '0')
        !           677:                            ret = (ITT0);
        !           678:                        else
        !           679:                            ret = (ITT1);
        !           680:                }
        !           681:                else if (c2 == 'c') {
        !           682:                        n = 2;
        !           683:                        ret = (IC);
        !           684:                }
        !           685: #endif
        !           686:                break;
        !           687:        case 'm':
        !           688:                if(c2=='s' && c3=='p') {
        !           689:                        n=3;
        !           690:                        ret = MSP;
        !           691:                }
        !           692: #ifdef BUILTIN_MMUS
        !           693:                if(c2=='m' && c3=='u' && c4=='s' && c5=='r') {
        !           694:                        n=5;
        !           695:                        ret = MMUSR;
        !           696:                }
        !           697: #endif
        !           698:                break;
        !           699:        case 'p':
        !           700:                if(c2=='c') {
        !           701: #ifdef m68851
        !           702:                        if(c3 == 's' && c4=='r') {
        !           703:                                n=4;
        !           704:                                ret = (PCSR);
        !           705:                        } else
        !           706: #endif
        !           707:                        {
        !           708:                                n=2;
        !           709:                                ret = PC;
        !           710:                        }
        !           711:                }
        !           712: #ifdef m68851
        !           713:                else if (c2 == 's' && c3 == 'r') {
        !           714:                        n = 3;
        !           715:                        ret = (PSR);
        !           716:                }
        !           717: #endif
        !           718: #ifdef BUILTIN_MMUS
        !           719:                else if (c2 == 's' && c3 == 'r') {
        !           720:                        n = 3;
        !           721:                        ret = (MMUSR);
        !           722:                }
        !           723: #endif
        !           724:                break;
        !           725:        case 's':
        !           726: #if defined(m68851) || defined(BUILTIN_MMUS)
        !           727:                if (c2 == 'r' && c3 == 'p') {
        !           728:                        n = 3;
        !           729:                        ret = (SRP);
        !           730:                }
        !           731: #endif
        !           732: #ifdef m68851
        !           733:                else if (c2 == 'c' && c3 == 'c') {
        !           734:                        n = 3;
        !           735:                        ret = (SCC);
        !           736:                }
        !           737: #endif
        !           738: #if defined(m68851) || defined(BUILTIN_MMUS)
        !           739:                else
        !           740: #endif
        !           741:                if(c2=='r') {
        !           742:                        n=2;
        !           743:                        ret = SR;
        !           744:                } else if(c2=='p') {
        !           745:                        n=2;
        !           746:                        ret = ADDR+7;
        !           747:                } else if(c2=='f' && c3=='c') {
        !           748:                        n=3;
        !           749:                        ret = SFC;
        !           750:                }
        !           751:                break;
        !           752: #if defined(m68851) || defined(BUILTIN_MMUS)
        !           753:        case 't':
        !           754:                if(c2 == 'c') {
        !           755:                        n=2;
        !           756:                        ret=TC;
        !           757:                }
        !           758: #ifdef BUILTIN_MMUS
        !           759:                else if (c2 == 't' && (c3 == '0' || c3 == '1')) {
        !           760:                        n = 3;
        !           761:                        if(c3 == '0')
        !           762:                            ret = (TT0);
        !           763:                        else
        !           764:                            ret = (TT1);
        !           765:                }
        !           766: #endif
        !           767:                break;
        !           768: #endif
        !           769:        case 'u':
        !           770:                if(c2=='s' && c3=='p') {
        !           771:                        n=3;
        !           772:                        ret = USP;
        !           773:                }
        !           774: #ifdef BUILTIN_MMUS
        !           775:                else if(c2=='r' && c3=='p') {
        !           776:                        n=3;
        !           777:                        ret = URP;
        !           778:                }
        !           779: #endif
        !           780:                break;
        !           781:        case 'v':
        !           782: #ifdef m68851
        !           783:                if (c2 == 'a' && c3 == 'l') {
        !           784:                        n = 3;
        !           785:                        ret = (VAL);
        !           786:                } else
        !           787: #endif
        !           788:                if(c2=='b' && c3=='r') {
        !           789:                        n=3;
        !           790:                        ret = VBR;
        !           791:                }
        !           792:                break;
        !           793:        case 'z':
        !           794:                if(c2=='p' && c3=='c') {
        !           795:                        n=3;
        !           796:                        ret = ZPC;
        !           797:                }
        !           798:                break;
        !           799:        default:
        !           800:                break;
        !           801:        }
        !           802:        if(n) {
        !           803:                if(isalnum(ccp[0][n]) || ccp[0][n]=='_')
        !           804:                        ret=FAIL;
        !           805:                else
        !           806:                        ccp[0]+=n;
        !           807:        } else
        !           808:                ret = FAIL;
        !           809:        return ret;
        !           810: }
        !           811: 
        !           812: #define SKIP_WHITE()   { str++; if(*str==' ') str++;}
        !           813: 
        !           814: static
        !           815: int
        !           816: m68k_ip_op(
        !           817: char *str,
        !           818: struct m68k_op *opP)
        !           819: {
        !           820:        char    *strend;
        !           821:        long    i;
        !           822: 
        !           823:        if(*str==' ')
        !           824:                str++;
        !           825:                /* Find the end of the string */
        !           826:        if(!*str) {
        !           827:                /* Out of gas */
        !           828:                opP->error="Missing operand";
        !           829:                return FAIL;
        !           830:        }
        !           831:        for(strend=str;*strend;strend++)
        !           832:                ;
        !           833:        --strend;
        !           834: 
        !           835:                /* Guess what:  A constant.  Shar and enjoy */
        !           836:        if(*str=='#') {
        !           837:                str++;
        !           838:                opP->con1=add_exp(str,strend);
        !           839:                opP->mode=IMMED;
        !           840:                return OK;
        !           841:        }
        !           842:        i=m68k_reg_parse(&str);
        !           843:        if((i==FAIL || *str!='\0') && *str!='@') {
        !           844:                char *stmp;
        !           845: 
        !           846:                if(i!=FAIL && (*str=='/' || *str=='-')) {
        !           847:                        opP->mode=REGLST;
        !           848:                        return get_regs(i,opP,str);
        !           849:                }
        !           850:                if((stmp=index(str,'@'))) {
        !           851:                        opP->con1=add_exp(str,stmp-1);
        !           852:                        if(stmp==strend) {
        !           853:                                opP->mode=AINDX;
        !           854:                                return OK;
        !           855:                        }
        !           856:                        stmp++;
        !           857:                        if(*stmp++!='(' || *strend--!=')') {
        !           858:                                opP->error="Malformed operand";
        !           859:                                return FAIL;
        !           860:                        }
        !           861:                        i=try_index(&stmp,opP);
        !           862:                        opP->con2=add_exp(stmp,strend);
        !           863:                        if(i==FAIL) opP->mode=AMIND;
        !           864:                        else opP->mode=APODX;
        !           865:                        return OK;
        !           866:                }
        !           867:                opP->mode=ABSL;
        !           868:                opP->con1=add_exp(str,strend);
        !           869:                return OK;
        !           870:        }
        !           871:        opP->reg=i;
        !           872:        if(*str=='\0') {
        !           873:                if(i>=DATA+0 && i<=DATA+7)
        !           874:                        opP->mode=DREG;
        !           875:                else if(i>=ADDR+0 && i<=ADDR+7)
        !           876:                        opP->mode=AREG;
        !           877:                else
        !           878:                        opP->mode=MSCR;
        !           879:                return OK;
        !           880:        }
        !           881:        if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) {      /* Can't indirect off non address regs */
        !           882:                opP->error="Invalid indirect register";
        !           883:                return FAIL;
        !           884:        }
        !           885:        if(*str!='@')
        !           886:                abort();
        !           887:        str++;
        !           888:        switch(*str) {
        !           889:        case '\0':
        !           890:                opP->mode=AINDR;
        !           891:                return OK;
        !           892:        case '-':
        !           893:                opP->mode=ADEC;
        !           894:                return OK;
        !           895:        case '+':
        !           896:                opP->mode=AINC;
        !           897:                return OK;
        !           898:        case '(':
        !           899:                str++;
        !           900:                break;
        !           901:        default:
        !           902:                opP->error="Junk after indirect";
        !           903:                return FAIL;
        !           904:        }
        !           905:                /* Some kind of indexing involved.  Lets find out how bad it is */
        !           906:        i=try_index(&str,opP);
        !           907:                /* Didn't start with an index reg, maybe its offset or offset,reg */
        !           908:        if(i==FAIL) {
        !           909:                char *beg_str;
        !           910: 
        !           911:                beg_str=str;
        !           912:                for(i=1;i;) {
        !           913:                        switch(*str++) {
        !           914:                        case '\0':
        !           915:                                opP->error="Missing )";
        !           916:                                return FAIL;
        !           917:                        case ',': i=0; break;
        !           918:                        case '(': i++; break;
        !           919:                        case ')': --i; break;
        !           920:                        }
        !           921:                }
        !           922:                opP->con1=add_exp(beg_str,str-2);
        !           923:                        /* Should be offset,reg */
        !           924:                if(str[-1]==',') {
        !           925:                        i=try_index(&str,opP);
        !           926:                        if(i==FAIL) {
        !           927:                                opP->error="Malformed index reg";
        !           928:                                return FAIL;
        !           929:                        }
        !           930:                }
        !           931:        }
        !           932:                /* We've now got offset)   offset,reg)   or    reg) */
        !           933: 
        !           934:        if(*str=='\0') {
        !           935:                /* Th-the-thats all folks */
        !           936: #ifdef NeXT
        !           937:        /* all forms using zpc must use pc@(bd,Xn) and not pc@(d16) because
        !           938:           you can only suppress the base register in the first form */
        !           939:                if(opP->reg==FAIL || opP->reg==ZPC) opP->mode=AINDX;    /* Other form of indirect */
        !           940: #else /* !defined(NeXT) */
        !           941:                if(opP->reg==FAIL) opP->mode=AINDX;     /* Other form of indirect */
        !           942: #endif /* NeXT */
        !           943:                else if(opP->ireg==FAIL) opP->mode=AOFF;
        !           944:                else opP->mode=AINDX;
        !           945:                return OK;
        !           946:        }
        !           947:                /* Next thing had better be another @ */
        !           948:        if(*str!='@' || str[1]!='(') {
        !           949:                opP->error="junk after indirect";
        !           950:                return FAIL;
        !           951:        }
        !           952:        str+=2;
        !           953:        if(opP->ireg!=FAIL) {
        !           954:                opP->mode=APRDX;
        !           955:                i=try_index(&str,opP);
        !           956:                if(i!=FAIL) {
        !           957:                        opP->error="Two index registers!  not allowed!";
        !           958:                        return FAIL;
        !           959:                }
        !           960:        } else
        !           961:                i=try_index(&str,opP);
        !           962:        if(i==FAIL) {
        !           963:                char *beg_str;
        !           964: 
        !           965:                beg_str=str;
        !           966:                for(i=1;i;) {
        !           967:                        switch(*str++) {
        !           968:                        case '\0':
        !           969:                                opP->error="Missing )";
        !           970:                                return FAIL;
        !           971:                        case ',': i=0; break;
        !           972:                        case '(': i++; break;
        !           973:                        case ')': --i; break;
        !           974:                        }
        !           975:                }
        !           976:                opP->con2=add_exp(beg_str,str-2);
        !           977:                if(str[-1]==',') {
        !           978:                        if(opP->ireg!=FAIL) {
        !           979:                                opP->error="Can't have two index regs";
        !           980:                                return FAIL;
        !           981:                        }
        !           982:                        i=try_index(&str,opP);
        !           983:                        if(i==FAIL) {
        !           984:                                opP->error="malformed index reg";
        !           985:                                return FAIL;
        !           986:                        }
        !           987:                        opP->mode=APODX;
        !           988:                } else if(opP->ireg!=FAIL)
        !           989:                        opP->mode=APRDX;
        !           990:                else
        !           991:                        opP->mode=AMIND;
        !           992:        } else
        !           993:                opP->mode=APODX;
        !           994:        if(*str!='\0') {
        !           995:                opP->error="Junk after indirect";
        !           996:                return FAIL;
        !           997:        }
        !           998:        return OK;
        !           999: }
        !          1000: 
        !          1001: static
        !          1002: int
        !          1003: try_index(
        !          1004: char **s,
        !          1005: struct m68k_op *opP)
        !          1006: {
        !          1007:        register int    i;
        !          1008:        char    *ss;
        !          1009: #define SKIP_W()       { ss++; if(*ss==' ') ss++;}
        !          1010: 
        !          1011:        ss= *s;
        !          1012:        /* SKIP_W(); */
        !          1013:        i=m68k_reg_parse(&ss);
        !          1014:        if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */
        !          1015:                *s=ss;
        !          1016:                return FAIL;
        !          1017:        }
        !          1018:        opP->ireg=i;
        !          1019:        /* SKIP_W(); */
        !          1020:        if(*ss==')') {
        !          1021:                opP->isiz=0;
        !          1022:                opP->imul=1;
        !          1023:                SKIP_W();
        !          1024:                *s=ss;
        !          1025:                return OK;
        !          1026:        }
        !          1027:        if(*ss!=':') {
        !          1028:                opP->error="Missing : in index register";
        !          1029:                *s=ss;
        !          1030:                return FAIL;
        !          1031:        }
        !          1032:        SKIP_W();
        !          1033:        if(mklower(*ss)=='w') opP->isiz=2;
        !          1034:        else if(mklower(*ss)=='l') opP->isiz=3;
        !          1035:        else {
        !          1036:                opP->error="Size spec not :w or :l";
        !          1037:                *s=ss;
        !          1038:                return FAIL;
        !          1039:        }
        !          1040:        SKIP_W();
        !          1041:        if(*ss==':') {
        !          1042:                SKIP_W();
        !          1043:                switch(*ss) {
        !          1044:                case '1':
        !          1045:                case '2':
        !          1046:                case '4':
        !          1047:                case '8':
        !          1048:                        opP->imul= *ss-'0';
        !          1049:                        break;
        !          1050:                default:
        !          1051:                        opP->error="index multiplier not 1, 2, 4 or 8";
        !          1052:                        *s=ss;
        !          1053:                        return FAIL;
        !          1054:                }
        !          1055:                SKIP_W();
        !          1056:        } else opP->imul=1;
        !          1057:        if(*ss!=')') {
        !          1058:                opP->error="Missing )";
        !          1059:                *s=ss;
        !          1060:                return FAIL;
        !          1061:        }
        !          1062:        SKIP_W();
        !          1063:        *s=ss;
        !          1064:        return OK;
        !          1065: }
        !          1066: 
        !          1067: #ifdef TEST1   /* TEST1 tests m68k_ip_op(), which parses operands */
        !          1068: void
        !          1069: main(
        !          1070: int argc,
        !          1071: char *argv[],
        !          1072: char *envp[])
        !          1073: {
        !          1074:     char buf[128];
        !          1075:     struct m68k_op thark;
        !          1076: 
        !          1077:        for(;;){
        !          1078:                if(!gets(buf))
        !          1079:                    break;
        !          1080:                memset(&thark, '\0', sizeof(thark));
        !          1081:                if(!m68k_ip_op(buf, &thark))
        !          1082:                    printf("FAIL:");
        !          1083:                if(thark.error)
        !          1084:                    printf("op1 error %s in %s\n",thark.error,buf);
        !          1085:                printf("mode %d, reg %d, ",thark.mode,thark.reg);
        !          1086:                if(thark.con1)
        !          1087:                    printf("con1: '%.*s',",
        !          1088:                           1 + thark.con1->e_end - thark.con1->e_beg,
        !          1089:                           thark.con1->e_beg);
        !          1090:                printf("ireg %d, isiz %d, imul %d ",
        !          1091:                       thark.ireg, thark.isiz, thark.imul);
        !          1092:                if(thark.con2)
        !          1093:                    printf("con2: '%.*s'",
        !          1094:                           1 + thark.con2->e_end - thark.con2->e_beg,
        !          1095:                           thark.con2->e_beg);
        !          1096:                printf("\n");
        !          1097:        }
        !          1098:        exit(0);
        !          1099: }
        !          1100: #endif /* TEST1 */
        !          1101: 
        !          1102: 
        !          1103: /*
        !          1104:  * Handle of the OPCODE hash table NULL means any use before m68_ip_begin()
        !          1105:  * will crash.
        !          1106:  */
        !          1107: static struct hash_control *op_hash = NULL;
        !          1108: 
        !          1109: 
        !          1110: /*
        !          1111:  *             m 6 8 _ i p ( )
        !          1112:  *
        !          1113:  * This converts a string into a 68k instruction.
        !          1114:  * The string must be a bare single instruction in sun format
        !          1115:  * with RMS-style 68020 indirects
        !          1116:  *  (example:  )
        !          1117:  *
        !          1118:  * It provides some error messages: at most one fatal error message (which
        !          1119:  * stops the scan) and at most one warning message for each operand.
        !          1120:  * The 68k instruction is returned in exploded form, since we have no
        !          1121:  * knowledge of how you parse (or evaluate) your expressions.
        !          1122:  * We do however strip off and decode addressing modes and operation
        !          1123:  * mnemonic.
        !          1124:  *
        !          1125:  * This function's value is a string. If it is not "" then an internal
        !          1126:  * logic error was found: read this code to assign meaning to the string.
        !          1127:  * No argument string should generate such an error string:
        !          1128:  * it means a bug in our code, not in the user's text.
        !          1129:  *
        !          1130:  * You MUST have called m86_ip_begin() once and m86_ip_end() never before using
        !          1131:  * this function.
        !          1132:  */
        !          1133: 
        !          1134: /* JF this function no longer returns a useful value.  Sorry */
        !          1135: static
        !          1136: void
        !          1137: m68_ip(
        !          1138: char *instring)
        !          1139: {
        !          1140:        register char *p;
        !          1141:        register struct m68k_op *opP;
        !          1142:        register struct m68_incant *opcode;
        !          1143:        register char *s;
        !          1144:        register int tmpreg = 0,
        !          1145:                baseo = 0,
        !          1146:                outro = 0,
        !          1147:                nextword;
        !          1148:        int     siz1,
        !          1149:                siz2;
        !          1150:        char    c;
        !          1151:        int     losing;
        !          1152:        int     opsfound;
        !          1153:        LITTLENUM_TYPE words[6];
        !          1154:        LITTLENUM_TYPE *wordp;
        !          1155: 
        !          1156:        if (*instring == ' ')
        !          1157:                instring++;                     /* skip leading whitespace */
        !          1158: 
        !          1159:   /* Scan up to end of operation-code, which MUST end in end-of-string
        !          1160:      or exactly 1 space. */
        !          1161:        for (p = instring; *p != '\0'; p++)
        !          1162:                if (*p == ' ')
        !          1163:                        break;
        !          1164: 
        !          1165: 
        !          1166:        if (p == instring) {
        !          1167:                the_ins.error = "No operator";
        !          1168:                the_ins.opcode[0] = 0;
        !          1169:                /* the_ins.numo=1; */
        !          1170:                return;
        !          1171:        }
        !          1172: 
        !          1173:   /* p now points to the end of the opcode name, probably whitespace.
        !          1174:      make sure the name is null terminated by clobbering the whitespace,
        !          1175:      look it up in the hash table, then fix it back. */   
        !          1176:        c = *p;
        !          1177:        *p = '\0';
        !          1178:        opcode = (struct m68_incant *)hash_find (op_hash, instring);
        !          1179:        *p = c;
        !          1180: 
        !          1181:        if (opcode == NULL) {
        !          1182:                the_ins.error = "Unknown operator";
        !          1183:                the_ins.opcode[0] = 0;
        !          1184:                /* the_ins.numo=1; */
        !          1185:                return;
        !          1186:        }
        !          1187: 
        !          1188:   /* found a legitimate opcode, start matching operands */
        !          1189:        for(opP= &the_ins.operands[0];*p;opP++) {
        !          1190:                p = crack_operand (p, opP);
        !          1191:                if(opP->error) {
        !          1192:                        the_ins.error=opP->error;
        !          1193:                        return;
        !          1194:                }
        !          1195:        }
        !          1196: 
        !          1197:        opsfound=opP- &the_ins.operands[0];
        !          1198:        /* This ugly hack is to support the floating pt opcodes in their standard form */
        !          1199:        /* Essentially, we fake a first enty of type COP#1 */
        !          1200:        if(opcode->m_operands[0]=='I') {
        !          1201:                int     n;
        !          1202: 
        !          1203:                for(n=opsfound;n>0;--n)
        !          1204:                        the_ins.operands[n]=the_ins.operands[n-1];
        !          1205: 
        !          1206:                /* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */
        !          1207:                memset((char *)(&the_ins.operands[0]), '\0',
        !          1208:                       sizeof(the_ins.operands[0]));
        !          1209:                the_ins.operands[0].mode=MSCR;
        !          1210:                the_ins.operands[0].reg=COPNUM;         /* COP #1 */
        !          1211:                opsfound++;
        !          1212:        }
        !          1213:                /* We've got the operands.  Find an opcode that'll
        !          1214:                   accept them */
        !          1215:        for(losing=0;;) {
        !          1216:                if(opsfound!=opcode->m_opnum)
        !          1217:                        losing++;
        !          1218:                else for(s=opcode->m_operands,opP= &the_ins.operands[0];*s && !losing;s+=2,opP++) {
        !          1219:                                /* Warning: this switch is huge! */
        !          1220:                                /* I've tried to organize the cases into  this order:
        !          1221:                                   non-alpha first, then alpha by letter.  lower-case goes directly
        !          1222:                                   before uppercase counterpart. */
        !          1223:                                /* Code with multiple case ...: gets sorted by the lowest case ...
        !          1224:                                   it belongs to.  I hope this makes sense. */
        !          1225:                        switch(*s) {
        !          1226:                        case '!':
        !          1227:                                if(opP->mode==MSCR || opP->mode==IMMED ||
        !          1228:  opP->mode==DREG || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)
        !          1229:                                        losing++;
        !          1230:                                break;
        !          1231: 
        !          1232:                        case '#':
        !          1233:                                if(opP->mode!=IMMED)
        !          1234:                                        losing++;
        !          1235:                                else {
        !          1236:                                        long t;
        !          1237: 
        !          1238:                                        t=get_num(opP->con1,80);
        !          1239:                                        if(s[1]=='b' && !isbyte(t))
        !          1240:                                                losing++;
        !          1241: #ifdef CHECK_WORD_IMMEDIATES
        !          1242:                                        else if((s[1]=='w' || s[1]=='z') &&
        !          1243:                                                !isword(t))
        !          1244:                                                losing++;
        !          1245: #else
        !          1246:                                        else if(s[1]=='z' && !isword(t))
        !          1247:                                                losing++;
        !          1248: #endif
        !          1249:                                }
        !          1250:                                break;
        !          1251: 
        !          1252:                        case '^':
        !          1253:                        case 'T':
        !          1254:                                if(opP->mode!=IMMED)
        !          1255:                                        losing++;
        !          1256:                                break;
        !          1257: 
        !          1258:                        case '$':
        !          1259:                                if(opP->mode==MSCR || opP->mode==AREG ||
        !          1260:  opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)
        !          1261:                                        losing++;
        !          1262:                                break;
        !          1263: 
        !          1264:                        case '%':
        !          1265:                                if(opP->mode==MSCR || opP->reg==PC ||
        !          1266:  opP->reg==ZPC || opP->mode==REGLST)
        !          1267:                                        losing++;
        !          1268:                                break;
        !          1269: 
        !          1270: 
        !          1271:                        case '&':
        !          1272:                                if(opP->mode==MSCR || opP->mode==DREG ||
        !          1273:  opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC ||
        !          1274:  opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)
        !          1275:                                        losing++;
        !          1276:                                break;
        !          1277: 
        !          1278:                        case '*':
        !          1279:                                if(opP->mode==MSCR || opP->mode==REGLST)
        !          1280:                                        losing++;
        !          1281:                                break;
        !          1282: 
        !          1283:                        case '+':
        !          1284:                                if(opP->mode!=AINC)
        !          1285:                                        losing++;
        !          1286:                                break;
        !          1287: 
        !          1288:                        case '-':
        !          1289:                                if(opP->mode!=ADEC)
        !          1290:                                        losing++;
        !          1291:                                break;
        !          1292: 
        !          1293: #ifdef NeXT
        !          1294:                        case '0':
        !          1295:                                if(opP->mode!=AINDR)
        !          1296:                                        losing++;
        !          1297:                                break;
        !          1298: #endif /* NeXT */
        !          1299: 
        !          1300:                        case '/':
        !          1301:                                if(opP->mode==MSCR || opP->mode==AREG ||
        !          1302:  opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->mode==REGLST)
        !          1303:                                        losing++;
        !          1304:                                break;
        !          1305: 
        !          1306:                        case ';':
        !          1307:                                if(opP->mode==MSCR || opP->mode==AREG || opP->mode==REGLST)
        !          1308:                                        losing++;
        !          1309:                                break;
        !          1310: 
        !          1311:                        case '?':
        !          1312:                                if(opP->mode==MSCR || opP->mode==AREG ||
        !          1313:  opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->reg==PC ||
        !          1314:  opP->reg==ZPC || opP->mode==REGLST)
        !          1315:                                        losing++;
        !          1316:                                break;
        !          1317: 
        !          1318:                        case '@':
        !          1319:                                if(opP->mode==MSCR || opP->mode==AREG ||
        !          1320:  opP->mode==IMMED || opP->mode==REGLST)
        !          1321:                                        losing++;
        !          1322:                                break;
        !          1323: 
        !          1324:                        case '~':               /* For now! (JF FOO is this right?) */
        !          1325:                                if(opP->mode==MSCR || opP->mode==DREG ||
        !          1326:  opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)
        !          1327:                                        losing++;
        !          1328:                                break;
        !          1329: 
        !          1330:                        case 'A':
        !          1331:                                if(opP->mode!=AREG)
        !          1332:                                        losing++;
        !          1333:                                break;
        !          1334: 
        !          1335:                        case 'B':       /* FOO */
        !          1336:                                if(opP->mode!=ABSL)
        !          1337:                                        losing++;
        !          1338:                                break;
        !          1339: 
        !          1340:                        case 'C':
        !          1341:                                if(opP->mode!=MSCR || opP->reg!=CCR)
        !          1342:                                        losing++;
        !          1343:                                break;
        !          1344: 
        !          1345:                        case 'd':       /* FOO This mode is a KLUDGE!! */
        !          1346:                                if(opP->mode!=AOFF && (opP->mode!=ABSL ||
        !          1347:  opP->con1->e_beg[0]!='(' || opP->con1->e_end[0]!=')'))
        !          1348:                                        losing++;
        !          1349:                                break;
        !          1350: 
        !          1351:                        case 'D':
        !          1352:                                if(opP->mode!=DREG)
        !          1353:                                        losing++;
        !          1354:                                break;
        !          1355: 
        !          1356:                        case 'F':
        !          1357:                                if(opP->mode!=MSCR || opP->reg<(FPREG+0) || opP->reg>(FPREG+7))
        !          1358:                                        losing++;
        !          1359:                                break;
        !          1360: 
        !          1361:                        case 'I':
        !          1362:                                if(opP->mode!=MSCR || opP->reg<COPNUM ||
        !          1363:  opP->reg>=COPNUM+7)
        !          1364:                                        losing++;
        !          1365:                                break;
        !          1366: 
        !          1367:                        case 'J':
        !          1368: #ifdef BUILTIN_MMUS
        !          1369:                                if(opP->mode!=MSCR || opP->reg<USP || opP->reg>SRP)
        !          1370: #else
        !          1371:                                if(opP->mode!=MSCR || opP->reg<USP || opP->reg>MSP)
        !          1372: #endif
        !          1373:                                        losing++;
        !          1374:                                break;
        !          1375: 
        !          1376:                        case 'k':
        !          1377:                                if(opP->mode!=IMMED)
        !          1378:                                        losing++;
        !          1379:                                break;
        !          1380: 
        !          1381:                        case 'l':
        !          1382:                        case 'L':
        !          1383:                                if(opP->mode==DREG || opP->mode==AREG || opP->mode==FPREG) {
        !          1384:                                        if(s[1]=='8')
        !          1385:                                                losing++;
        !          1386:                                        else {
        !          1387:                                                opP->mode=REGLST;
        !          1388:                                                opP->reg=1<<(opP->reg-DATA);
        !          1389:                                        }
        !          1390:                                } else if(opP->mode!=REGLST) {
        !          1391:                                        losing++;
        !          1392:                                } else if(s[1]=='8' && opP->reg&0x0FFffFF)
        !          1393:                                        losing++;
        !          1394:                                else if(s[1]=='3' && opP->reg&0x7000000)
        !          1395:                                        losing++;
        !          1396:                                break;
        !          1397: 
        !          1398:                        case 'M':
        !          1399:                                if(opP->mode!=IMMED)
        !          1400:                                        losing++;
        !          1401:                                else {
        !          1402:                                        long t;
        !          1403: 
        !          1404:                                        t=get_num(opP->con1,80);
        !          1405: #ifdef NeXT    /* feature to try to make expressions absolute */
        !          1406:                                        /* DJA -- Bug fix. allow absolute expressions */
        !          1407:                                        if(! (issbyte(t) && seg(opP->con1)==SEG_ABSOLUTE) )
        !          1408: #else /* !defined(NeXT) */
        !          1409:                                        if(!issbyte(t) || isvar(opP->con1))
        !          1410: #endif /* NeXT */
        !          1411:                                                losing++;
        !          1412:                                }
        !          1413:                                break;
        !          1414: 
        !          1415:                        case 'O':
        !          1416:                                if(opP->mode!=DREG && opP->mode!=IMMED)
        !          1417:                                        losing++;
        !          1418:                                break;
        !          1419: 
        !          1420:                        case 'Q':
        !          1421:                                if(opP->mode!=IMMED)
        !          1422:                                        losing++;
        !          1423:                                else {
        !          1424:                                        long t;
        !          1425: 
        !          1426:                                        t=get_num(opP->con1,80);
        !          1427:                                        if(t<1 || t>8 || isvar(opP->con1))
        !          1428:                                                losing++;
        !          1429:                                }
        !          1430:                                break;
        !          1431: 
        !          1432:                        case 'R':
        !          1433:                                if(opP->mode!=DREG && opP->mode!=AREG)
        !          1434:                                        losing++;
        !          1435:                                break;
        !          1436: 
        !          1437:                        case 's':
        !          1438:                                if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC))
        !          1439:                                        losing++;
        !          1440:                                break;
        !          1441: 
        !          1442:                        case 'S':
        !          1443:                                if(opP->mode!=MSCR || opP->reg!=SR)
        !          1444:                                        losing++;
        !          1445:                                break;
        !          1446: 
        !          1447:                        case 'U':
        !          1448:                                if(opP->mode!=MSCR || opP->reg!=USP)
        !          1449:                                        losing++;
        !          1450:                                break;
        !          1451: 
        !          1452:                        /* JF these are out of order.  We could put them
        !          1453:                           in order if we were willing to put up with
        !          1454:                           bunches of #ifdef m68851s in the code */
        !          1455: #ifdef m68851
        !          1456:                        /* Memory addressing mode used by pflushr */
        !          1457:                        case '|':
        !          1458:                                if(opP->mode==MSCR || opP->mode==DREG ||
        !          1459:  opP->mode==AREG || opP->mode==REGLST)
        !          1460:                                        losing++;
        !          1461:                                break;
        !          1462: #endif
        !          1463: 
        !          1464: #if defined(m68851) || defined(BUILTIN_MMUS)
        !          1465:                        case 'f':
        !          1466:                                if (opP->mode != MSCR || (opP->reg != SFC && opP->reg != DFC))
        !          1467:                                        losing++;
        !          1468:                                break;
        !          1469: #endif
        !          1470: 
        !          1471: #ifdef m68851
        !          1472:                        case 'P':
        !          1473:                                if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL &&
        !          1474:                                    opP->reg != VAL && opP->reg != SCC && opP->reg != AC))
        !          1475:                                        losing++;
        !          1476:                                break;
        !          1477: 
        !          1478:                        case 'V':
        !          1479:                                if (opP->reg != VAL)
        !          1480:                                        losing++;
        !          1481:                                break;
        !          1482: 
        !          1483:                        case 'W':
        !          1484:                                if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP &&
        !          1485:                                    opP->reg != CRP))
        !          1486:                                        losing++;
        !          1487:                                break;
        !          1488: 
        !          1489:                        case 'X':
        !          1490:                                if (opP->mode != MSCR ||
        !          1491:                                    (!(opP->reg >= BAD && opP->reg <= BAD+7) &&
        !          1492:                                     !(opP->reg >= BAC && opP->reg <= BAC+7)))
        !          1493:                                        losing++;
        !          1494:                                break;
        !          1495: 
        !          1496:                        case 'Y':
        !          1497:                                if (opP->reg != PSR)
        !          1498:                                        losing++;
        !          1499:                                break;
        !          1500: 
        !          1501:                        case 'Z':
        !          1502:                                if (opP->reg != PCSR)
        !          1503:                                        losing++;
        !          1504:                                break;
        !          1505: #endif
        !          1506: #ifdef BUILTIN_MMUS
        !          1507:                        case 'a':
        !          1508:                                if ((opP->mode != MSCR) || (opP->reg != SRP &&
        !          1509:                                     opP->reg != CRP && opP->reg != TC))
        !          1510:                                        losing++;
        !          1511:                                break;
        !          1512:                        case 'b':
        !          1513:                                if (opP->mode != MSCR || opP->reg != MMUSR)
        !          1514:                                        losing++;
        !          1515:                                break;
        !          1516:                        case 'c':
        !          1517:                                if ((opP->mode != MSCR) || (opP->reg != IC &&
        !          1518:                                     opP->reg != DC && opP->reg != BC))
        !          1519:                                        losing++;
        !          1520:                                break;
        !          1521:                        case 'e':
        !          1522:                                if ((opP->mode != MSCR) || (opP->reg != TT0 &&
        !          1523:                                     opP->reg != TT1))
        !          1524:                                        losing++;
        !          1525:                                break;
        !          1526: #endif
        !          1527:                        default:
        !          1528:                                as_fatal("Internal error:  Operand mode %c unknown",*s);
        !          1529:                        }
        !          1530:                }
        !          1531:                if(!losing)
        !          1532:                        break;
        !          1533:                opcode=opcode->m_next;
        !          1534:                if(!opcode) {           /* Fell off the end */
        !          1535:                        the_ins.error="instruction/operands mismatch";
        !          1536:                        return;
        !          1537:                }
        !          1538:                losing=0;
        !          1539:        }
        !          1540:        the_ins.args=opcode->m_operands;
        !          1541:        the_ins.numargs=opcode->m_opnum;
        !          1542:        the_ins.numo=opcode->m_codenum;
        !          1543:        the_ins.opcode[0]=getone(opcode);
        !          1544:        the_ins.opcode[1]=gettwo(opcode);
        !          1545: #ifdef NeXT
        !          1546:        the_ins.cpus=opcode->m_cpus;
        !          1547: #endif /* NeXT */
        !          1548: 
        !          1549:        for(s=the_ins.args,opP= &the_ins.operands[0];*s;s+=2,opP++) {
        !          1550:                        /* This switch is a doozy.
        !          1551:                           What the first step; its a big one! */
        !          1552:                switch(s[0]) {
        !          1553: 
        !          1554:                case '*':
        !          1555:                case '~':
        !          1556:                case '%':
        !          1557:                case ';':
        !          1558:                case '@':
        !          1559:                case '!':
        !          1560:                case '&':
        !          1561:                case '$':
        !          1562:                case '?':
        !          1563:                case '/':
        !          1564: #ifdef m68851
        !          1565:                case '|':
        !          1566: #endif
        !          1567:                        switch(opP->mode) {
        !          1568:                        case IMMED:
        !          1569:                                tmpreg=0x3c;    /* 7.4 */
        !          1570:                                if(index("bwzl",s[1]))
        !          1571:                                        nextword=get_num(opP->con1,80);
        !          1572:                                else
        !          1573:                                        nextword=get_num(opP->con1,0);
        !          1574:                                if(isvar(opP->con1))
        !          1575:                                        add_fix(s[1],opP->con1,0);
        !          1576:                                switch(s[1]) {
        !          1577:                                case 'b':
        !          1578:                                        if(!isbyte(nextword))
        !          1579:                                                opP->error="operand out of range";
        !          1580:                                        addword(nextword);
        !          1581:                                        baseo=0;
        !          1582:                                        break;
        !          1583:                                case 'w':
        !          1584:                                case 'z':
        !          1585: #ifdef CHECK_WORD_IMMEDIATES
        !          1586:                                        if(!isword(nextword))
        !          1587:                                                opP->error="operand out of range";
        !          1588: #endif
        !          1589:                                        addword(nextword);
        !          1590:                                        baseo=0;
        !          1591:                                        break;
        !          1592: #ifdef NeXT    /* Used in the fmoveml (control) registers */
        !          1593:                                case 's':
        !          1594: #endif /* NeXT */
        !          1595:                                case 'l':
        !          1596:                                        addword(nextword>>16);
        !          1597:                                        addword(nextword);
        !          1598:                                        baseo=0;
        !          1599:                                        break;
        !          1600: 
        !          1601:                                case 'f':
        !          1602:                                        baseo=2;
        !          1603:                                        outro=8;
        !          1604:                                        break;
        !          1605:                                case 'F':
        !          1606:                                        baseo=4;
        !          1607:                                        outro=11;
        !          1608:                                        break;
        !          1609:                                case 'x':
        !          1610:                                        baseo=6;
        !          1611:                                        outro=15;
        !          1612:                                        break;
        !          1613: #ifdef PACKED_IMMEDIATE
        !          1614: /* This does not work.  The call to gen_to_words() below does not put out
        !          1615:    68k packed decimal format. */
        !          1616:                                case 'p':
        !          1617:                                        baseo=6;
        !          1618:                                        outro= -1;
        !          1619:                                        break;
        !          1620: #endif
        !          1621:                                default:
        !          1622:                                        as_fatal("Internal error:  Can't decode %c%c",*s,s[1]);
        !          1623:                                }
        !          1624:                                if(!baseo)
        !          1625:                                        break;
        !          1626: 
        !          1627:                                /* We gotta put out some float */
        !          1628:                                if(seg(opP->con1)!=SEG_BIG) {
        !          1629:                                        int_to_gen(nextword);
        !          1630:                                        gen_to_words(words,baseo,(long int)outro);
        !          1631:                                        for(wordp=words;baseo--;wordp++)
        !          1632:                                                addword(*wordp);
        !          1633:                                        break;
        !          1634:                                }               /* Its BIG */
        !          1635:                                if(offs(opP->con1)>0) {
        !          1636: #ifndef NeXT   /* fix for bug #8331 */
        !          1637:                                        as_warn("Bignum assumed to be binary bit-pattern");
        !          1638: #endif /* NeXT */
        !          1639:                                        if(offs(opP->con1)>baseo) {
        !          1640:                                                as_warn("Bignum too big for %c format; truncated",s[1]);
        !          1641:                                                offs(opP->con1)=baseo;
        !          1642:                                        }
        !          1643:                                        baseo-=offs(opP->con1);
        !          1644:                                        for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp)
        !          1645:                                                addword(*wordp);
        !          1646:                                        while(baseo--)
        !          1647:                                                addword(0);
        !          1648:                                        break;
        !          1649:                                }
        !          1650:                                gen_to_words(words,baseo,(long int)outro);
        !          1651:                                for(wordp=words;baseo--;wordp++)
        !          1652:                                        addword(*wordp);
        !          1653:                                break;
        !          1654:                        case DREG:
        !          1655:                                tmpreg=opP->reg-DATA; /* 0.dreg */
        !          1656:                                break;
        !          1657:                        case AREG:
        !          1658:                                tmpreg=0x08+opP->reg-ADDR; /* 1.areg */
        !          1659:                                break;
        !          1660:                        case AINDR:
        !          1661: #ifdef NeXT
        !          1662:                                /* fixes "pc@" operand */
        !          1663:                                if(opP->reg==PC){
        !          1664:                                        tmpreg=0x3A; /* 7.2 */
        !          1665:                                        addword(0x0000);
        !          1666:                                }
        !          1667:                                else
        !          1668: #endif /* NeXT */
        !          1669:                                tmpreg=0x10+opP->reg-ADDR; /* 2.areg */
        !          1670:                                break;
        !          1671:                        case ADEC:
        !          1672:                                tmpreg=0x20+opP->reg-ADDR; /* 4.areg */
        !          1673:                                break;
        !          1674:                        case AINC:
        !          1675:                                tmpreg=0x18+opP->reg-ADDR; /* 3.areg */
        !          1676:                                break;
        !          1677:                        case AOFF:
        !          1678:                                if(opP->reg==PC)
        !          1679:                                        tmpreg=0x3A; /* 7.2 */
        !          1680:                                else
        !          1681:                                        tmpreg=0x28+opP->reg-ADDR; /* 5.areg */
        !          1682:                                nextword=get_num(opP->con1,80);
        !          1683:                                /* Force into index mode.  Hope this works */
        !          1684:                                if(!issword(nextword)) {
        !          1685:                                        if(opP->reg==PC)
        !          1686:                                                tmpreg=0x3B;    /* 7.3 */
        !          1687:                                        else
        !          1688:                                                tmpreg=0x30+opP->reg-ADDR;      /* 6.areg */
        !          1689:                                        /* addword(0x0171); */
        !          1690: /* 171 seems to be wrong, and I can't find the 68020 manual, so we'll try 170
        !          1691:    (which is what the Sun asm seems to generate */
        !          1692:                                        addword(0x0170);
        !          1693:                                        if(isvar(opP->con1))
        !          1694:                                                add_fix('l',opP->con1,0);
        !          1695:                                        addword(nextword>>16);
        !          1696:                                        /* addword(nextword); */
        !          1697:                                } else if(isvar(opP->con1)) {
        !          1698:                                        if(!flagseen['l'] &&
        !          1699:                                           flagseen['k'] &&
        !          1700:                                           seg(opP->con1) != SEG_DIFFSECT)
        !          1701:                                        {
        !          1702:                                                add_fix('w',opP->con1,0);
        !          1703:                                        } else {
        !          1704:                                                if(opP->reg==PC)
        !          1705:                                                    tmpreg=0x3B; /* 7.3 */
        !          1706:                                                else
        !          1707:                                                    tmpreg=0x30+opP->reg-ADDR;
        !          1708:                                                addword(0x0170);
        !          1709:                                                /*
        !          1710:                                                 * If this is a pc register with
        !          1711:                                                 * a SEGDIFF where the -symbol
        !          1712:                                                 * is "." adjust the value of
        !          1713:                                                 * of "." to include the two
        !          1714:                                                 * bytes of opcode.
        !          1715:                                                 */
        !          1716:                                                if(opP->reg==PC &&
        !          1717:                                                   seg(opP->con1) ==
        !          1718:                                                   SEG_DIFFSECT &&
        !          1719:                                                   opP->con1->
        !          1720:                                                    e_exp.X_subtract_symbol->
        !          1721:                                                     sy_frag == frag_now &&
        !          1722:                                                   strcmp(opP->con1->
        !          1723:                                                      e_exp.X_subtract_symbol->
        !          1724:                                                          sy_nlist.n_un.n_name,
        !          1725:                                                          "L0\001") == 0)
        !          1726:                                                   opP->con1->
        !          1727:                                                    e_exp.X_subtract_symbol->
        !          1728:                                                     sy_nlist.n_value += 2;
        !          1729:                                                add_fix('l',opP->con1,0);
        !          1730:                                                addword(nextword>>16);
        !          1731:                                        }
        !          1732:                                }
        !          1733:                                addword(nextword);
        !          1734:                                break;
        !          1735:                        case AINDX:
        !          1736:                        case APODX:
        !          1737:                        case AMIND:
        !          1738:                        case APRDX:
        !          1739:                                nextword=0;
        !          1740:                                baseo=get_num(opP->con1,80);
        !          1741:                                outro=get_num(opP->con2,80);
        !          1742:                                        /* Figure out the 'addressing mode' */
        !          1743:                                        /* Also turn on the BASE_DISABLE bit, if needed */
        !          1744:                                if(opP->reg==PC || opP->reg==ZPC) {
        !          1745:                                        tmpreg=0x3b; /* 7.3 */
        !          1746:                                        if(opP->reg==ZPC)
        !          1747:                                                nextword|=0x80;
        !          1748:                                } else if(opP->reg==FAIL) {
        !          1749:                                        nextword|=0x80;
        !          1750:                                        tmpreg=0x30;    /* 6.garbage */
        !          1751:                                } else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */
        !          1752: 
        !          1753:                                siz1= (opP->con1) ? opP->con1->e_siz : 0;
        !          1754:                                siz2= (opP->con2) ? opP->con2->e_siz : 0;
        !          1755: 
        !          1756:                                        /* Index register stuff */
        !          1757:                                if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) {
        !          1758:                                        nextword|=(opP->ireg-DATA)<<12;
        !          1759: 
        !          1760:                                        if(opP->isiz==0 || opP->isiz==3)
        !          1761:                                                nextword|=0x800;
        !          1762:                                        switch(opP->imul) {
        !          1763:                                        case 1: break;
        !          1764:                                        case 2: nextword|=0x200; break;
        !          1765:                                        case 4: nextword|=0x400; break;
        !          1766:                                        case 8: nextword|=0x600; break;
        !          1767:                                        default: abort();
        !          1768:                                        }
        !          1769:                                                /* IF its simple, GET US OUT OF HERE! */
        !          1770:                                                /* Must be INDEX, with an index register.  Address register
        !          1771:                                                   cannot be ZERO-PC, and either :b was forced, or we know it'll fit */
        !          1772:                                        if(opP->mode==AINDX &&
        !          1773:  opP->reg!=FAIL && opP->reg!=ZPC && (siz1==1 || (issbyte(baseo) &&
        !          1774:  !isvar(opP->con1)))) {
        !          1775:                                                nextword +=baseo&0xff;
        !          1776:                                                addword(nextword);
        !          1777:                                                if(isvar(opP->con1))
        !          1778:                                                        add_fix('B',opP->con1,0);
        !          1779:                                                break;
        !          1780:                                        }
        !          1781:                                } else
        !          1782:                                        nextword|=0x40; /* No index reg */
        !          1783: 
        !          1784:                                        /* It aint simple */
        !          1785:                                nextword|=0x100;
        !          1786:                                        /* If the guy specified a width, we assume that
        !          1787:                                           it is wide enough.  Maybe it isn't.  Ifso, we lose
        !          1788:                                         */
        !          1789:                                switch(siz1) {
        !          1790:                                case 0:
        !          1791:                                        if(isvar(opP->con1) || !issword(baseo)) {
        !          1792:                                                siz1=3;
        !          1793:                                                nextword|=0x30;
        !          1794:                                        } else if(baseo==0)
        !          1795:                                                nextword|=0x10;
        !          1796:                                        else {  
        !          1797:                                                nextword|=0x20;
        !          1798:                                                siz1=2;
        !          1799:                                        }
        !          1800:                                        break;
        !          1801:                                case 1:
        !          1802:                                        as_warn("Byte dispacement won't work.  Defaulting to :w");
        !          1803:                                case 2:
        !          1804:                                        nextword|=0x20;
        !          1805:                                        break;
        !          1806:                                case 3:
        !          1807:                                        nextword|=0x30;
        !          1808:                                        break;
        !          1809:                                }
        !          1810: 
        !          1811:                                        /* Figure out innner displacement stuff */
        !          1812:                                if(opP->mode!=AINDX) {
        !          1813:                                        switch(siz2) {
        !          1814:                                        case 0:
        !          1815:                                                if(isvar(opP->con2) || !issword(outro)) {
        !          1816:                                                        siz2=3;
        !          1817:                                                        nextword|=0x3;
        !          1818:                                                } else if(outro==0)
        !          1819:                                                        nextword|=0x1;
        !          1820:                                                else {  
        !          1821:                                                        nextword|=0x2;
        !          1822:                                                        siz2=2;
        !          1823:                                                }
        !          1824:                                                break;
        !          1825:                                        case 1:
        !          1826:                                                as_warn("Byte dispacement won't work.  Defaulting to :w");
        !          1827:                                        case 2:
        !          1828:                                                nextword|=0x2;
        !          1829:                                                break;
        !          1830:                                        case 3:
        !          1831:                                                nextword|=0x3;
        !          1832:                                                break;
        !          1833:                                        }
        !          1834:                                        if(opP->mode==APODX) nextword|=0x04;
        !          1835:                                        else if(opP->mode==AMIND) nextword|=0x40;
        !          1836:                                }
        !          1837:                                addword(nextword);
        !          1838: 
        !          1839:                                if(isvar(opP->con1))
        !          1840:                                        add_fix(siz1==3 ? 'l' : 'w',opP->con1,0);
        !          1841:                                if(siz1==3)
        !          1842:                                        addword(baseo>>16);
        !          1843:                                if(siz1)
        !          1844:                                        addword(baseo);
        !          1845: 
        !          1846:                                if(isvar(opP->con2))
        !          1847:                                        add_fix(siz2==3 ? 'l' : 'w',opP->con2,0);
        !          1848:                                if(siz2==3)
        !          1849:                                        addword(outro>>16);
        !          1850:                                if(siz2)
        !          1851:                                        addword(outro);
        !          1852: 
        !          1853:                                break;
        !          1854: 
        !          1855:                        case ABSL:
        !          1856:                                nextword=get_num(opP->con1,80);
        !          1857:                                switch(opP->con1->e_siz) {
        !          1858:                                case 1: /* treat like not there, fall through */
        !          1859:                                    as_warn("ignoring :b suffix on %*s",
        !          1860:                                       (int)(opP->con1->e_end-opP->con1->e_beg),
        !          1861:                                       opP->con1->e_beg);
        !          1862:                                case 0:
        !          1863:                                        if(!isvar(opP->con1) &&
        !          1864:                                           issword(offs(opP->con1))) {
        !          1865:                                                tmpreg=0x38; /* 7.0 */
        !          1866:                                                addword(nextword);
        !          1867:                                                break;
        !          1868:                                        }
        !          1869:                                        /* Don't generate pc relative code
        !          1870:                                           on 68010 and 68000 */
        !          1871:                                        if(isvar(opP->con1) &&
        !          1872:                                           !subs(opP->con1) &&
        !          1873:                                           seg(opP->con1) == SEG_SECT &&
        !          1874:                                           frchain_now->frch_nsect ==
        !          1875:                                               opP->con1->e_exp.X_add_symbol->
        !          1876:                                                    sy_nlist.n_sect &&
        !          1877:                                           flagseen['m'] == 0 &&
        !          1878:                                            !index("~%&$?", s[0])) {
        !          1879:                                                tmpreg=0x3A; /* 7.2 */
        !          1880:                                                add_frag(adds(opP->con1),
        !          1881:                                                         offs(opP->con1),
        !          1882:                                                         TAB(PCREL,SZ_UNDEF));
        !          1883:                                                break;
        !          1884:                                        }
        !          1885:                                case 3:         /* Fall through into long */
        !          1886:                                        if(isvar(opP->con1))
        !          1887:                                                add_fix('l',opP->con1,0);
        !          1888: 
        !          1889:                                        tmpreg=0x39;    /* 7.1 mode */
        !          1890:                                        addword(nextword>>16);
        !          1891:                                        addword(nextword);
        !          1892:                                        break;
        !          1893: 
        !          1894:                                case 2:         /* Word */
        !          1895:                                        if(isvar(opP->con1))
        !          1896:                                                add_fix('w',opP->con1,0);
        !          1897: 
        !          1898:                                        tmpreg=0x38;    /* 7.0 mode */
        !          1899:                                        addword(nextword);
        !          1900:                                        break;
        !          1901:                                }
        !          1902:                                break;
        !          1903:                        case MSCR:
        !          1904:                        default:
        !          1905:                                as_bad("unknown/incorrect operand");
        !          1906:                                /* abort(); */
        !          1907:                        }
        !          1908:                        install_gen_operand(s[1],tmpreg);
        !          1909:                        break;
        !          1910: 
        !          1911:                case '#':
        !          1912:                case '^':
        !          1913:                        switch(s[1]) {  /* JF: I hate floating point! */
        !          1914:                        case 'j':
        !          1915:                                tmpreg=70;
        !          1916:                                break;
        !          1917:                        case '8':
        !          1918:                                tmpreg=20;
        !          1919:                                break;
        !          1920:                        case 'C':
        !          1921:                                tmpreg=50;
        !          1922:                                break;
        !          1923:                        case '3':
        !          1924:                        default:
        !          1925:                                tmpreg=80;
        !          1926:                                break;
        !          1927:                        }
        !          1928:                        tmpreg=get_num(opP->con1,tmpreg);
        !          1929:                        if(isvar(opP->con1))
        !          1930:                                add_fix(s[1],opP->con1,0);
        !          1931:                        switch(s[1]) {
        !          1932:                        case 'b':       /* Danger:  These do no check for
        !          1933:                                           certain types of overflow.
        !          1934:                                           user beware! */
        !          1935:                                if(!isbyte(tmpreg))
        !          1936:                                        opP->error="out of range";
        !          1937:                                insop(tmpreg);
        !          1938:                                if(isvar(opP->con1))
        !          1939:                                        the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
        !          1940:                                break;
        !          1941: #ifdef NeXT
        !          1942:                        case 'j':
        !          1943:                                if(tmpreg < 0 || tmpreg > 0xfff)
        !          1944:                                        opP->error="out of range";
        !          1945:                                tmpreg&=0xFFF;
        !          1946:                                install_operand(s[1],tmpreg);
        !          1947:                                break;
        !          1948: #endif /* NeXT */
        !          1949:                        case 'w':
        !          1950:                        case 'z':
        !          1951: #ifdef CHECK_WORD_IMMEDIATES
        !          1952:                                if(!isword(tmpreg))
        !          1953:                                        opP->error="out of range";
        !          1954: #endif
        !          1955:                                insop(tmpreg);
        !          1956:                                if(isvar(opP->con1))
        !          1957:                                        the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
        !          1958:                                break;
        !          1959:                        case 'l':
        !          1960:                                insop(tmpreg);          /* Because of the way insop works, we put these two out backwards */
        !          1961:                                insop(tmpreg>>16);
        !          1962:                                if(isvar(opP->con1))
        !          1963:                                        the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
        !          1964:                                break;
        !          1965:                        case '3':
        !          1966:                                tmpreg&=0xFF;
        !          1967: #ifdef NeXT
        !          1968:                                if (isvar(opP->con1))
        !          1969:                                  the_ins.reloc[the_ins.nrel-1].n = 
        !          1970:                                    (opcode->m_codenum) + 1;
        !          1971: #endif /* NeXT */
        !          1972:                        case '8':
        !          1973:                        case 'C':
        !          1974:                                install_operand(s[1],tmpreg);
        !          1975:                                break;
        !          1976:                        default:
        !          1977:                                as_fatal("Internal error:  Unknown mode #%c",s[1]);
        !          1978:                        }
        !          1979:                        break;
        !          1980: 
        !          1981:                case '+':
        !          1982:                case '-':
        !          1983:                case 'A':
        !          1984:                        install_operand(s[1],opP->reg-ADDR);
        !          1985:                        break;
        !          1986: 
        !          1987:                case 'B':
        !          1988:                        tmpreg = get_num(opP->con1, 80);
        !          1989:                        switch(s[1]){
        !          1990:                        case 'g':
        !          1991:                            /* Deal with fixed size stuff by hand */
        !          1992:                            if(opP->con1->e_siz){
        !          1993:                                switch(opP->con1->e_siz){
        !          1994:                                case 1:
        !          1995:                                    add_fix('B', opP->con1, 1);
        !          1996:                                    break;
        !          1997:                                case 2:
        !          1998:                                    if(strncmp(instring, "jbsr", 4) == 0){
        !          1999:                                        if(isvar(opP->con1))
        !          2000:                                            add_fix('w', opP->con1, 0);
        !          2001:                                        /* force a jsr 7.0 mode (xxx):W */
        !          2002:                                        the_ins.opcode[the_ins.numo-1] = 0x4eb8;
        !          2003:                                        addword(tmpreg);
        !          2004:                                        break;
        !          2005:                                    }
        !          2006:                                    if(strncmp(instring, "jra", 3) == 0){
        !          2007:                                        if(isvar(opP->con1))
        !          2008:                                            add_fix('w', opP->con1, 0);
        !          2009:                                        /* force a jmp 7.0 mode (xxx):W */
        !          2010:                                        the_ins.opcode[the_ins.numo-1] = 0x4ef8;
        !          2011:                                        addword(tmpreg);
        !          2012:                                        break;
        !          2013:                                    }
        !          2014:                                    opP->con1->e_exp.X_add_number += 2;
        !          2015:                                    add_fix('w', opP->con1, 1);
        !          2016:                                    addword(0);
        !          2017:                                    break;
        !          2018:                                case 3:
        !          2019:                                    the_ins.opcode[the_ins.numo-1] |= 0xff;
        !          2020:                                    opP->con1->e_exp.X_add_number += 4;
        !          2021:                                    add_fix('l', opP->con1, 1);
        !          2022:                                    addword(0);
        !          2023:                                    addword(0);
        !          2024:                                    break;
        !          2025:                                default:
        !          2026:                                    as_fatal("Bad size for expression %d",
        !          2027:                                             opP->con1->e_siz);
        !          2028:                                }
        !          2029:                            }
        !          2030:                            else if(subs(opP->con1)){
        !          2031:                                /* We can't relax it */
        !          2032:                                the_ins.opcode[the_ins.numo-1] |= 0xff;
        !          2033:                                add_fix('l', opP->con1, 1);
        !          2034:                                addword(0);
        !          2035:                                addword(0);
        !          2036:                            }
        !          2037:                            else if(adds(opP->con1)){
        !          2038:                                if(flagseen['m'] && 
        !          2039:                                   (the_ins.opcode[0] >= 0x6200) &&
        !          2040:                                   (the_ins.opcode[0] <= 0x6f00)){
        !          2041:                                    add_frag(adds(opP->con1),
        !          2042:                                             offs(opP->con1),
        !          2043:                                             TAB(BCC68000, SZ_UNDEF));
        !          2044:                                }
        !          2045:                                else{
        !          2046:                                    add_frag(adds(opP->con1),
        !          2047:                                             offs(opP->con1),
        !          2048:                                             TAB(BRANCH, SZ_UNDEF));
        !          2049:                                }
        !          2050:                            }
        !          2051:                            else{
        !          2052:                                the_ins.opcode[the_ins.numo-1] |= 0xff;
        !          2053:                                opP->con1->e_exp.X_add_number += 4;
        !          2054:                                add_fix('l', opP->con1, 1);
        !          2055:                                addword(0);
        !          2056:                                addword(0);
        !          2057:                            }
        !          2058:                            break;
        !          2059:                        case 'w':
        !          2060:                            if(isvar(opP->con1)){
        !          2061:                                /* check for DBcc instruction */
        !          2062:                                if((the_ins.opcode[0] & 0xf0f8) ==0x50c8){
        !          2063:                                    /* size varies if patch */
        !          2064:                                    /* needed for long form */
        !          2065:                                    add_frag(adds(opP->con1),
        !          2066:                                             offs(opP->con1),
        !          2067:                                             TAB(DBCC, SZ_UNDEF));
        !          2068:                                    break;
        !          2069:                                }
        !          2070:                            }
        !          2071:                            opP->con1->e_exp.X_add_number += 2;
        !          2072:                            add_fix('w', opP->con1, 1);
        !          2073:                            addword(0);
        !          2074:                            break;
        !          2075:                        case 'c':
        !          2076:                            if(opP->con1->e_siz){
        !          2077:                                switch(opP->con1->e_siz){
        !          2078:                                case 2:
        !          2079:                                    opP->con1->e_exp.X_add_number += 2;
        !          2080:                                    add_fix('w', opP->con1, 1);
        !          2081:                                    addword(0);
        !          2082:                                    break;
        !          2083:                                case 3:
        !          2084:                                    the_ins.opcode[the_ins.numo-1] |= 0x40;
        !          2085:                                    opP->con1->e_exp.X_add_number += 4;
        !          2086:                                    add_fix('l', opP->con1, 1);
        !          2087:                                    addword(0);
        !          2088:                                    addword(0);
        !          2089:                                    break;
        !          2090:                                default:
        !          2091:                                    as_bad("Bad size for offset, must be word "
        !          2092:                                           "or long");
        !          2093:                                    break;
        !          2094:                                }
        !          2095:                            }
        !          2096:                            else if(subs(opP->con1)){
        !          2097:                                /* We can't relax it */
        !          2098:                                the_ins.opcode[the_ins.numo-1] |= 0x40;
        !          2099:                                add_fix('l', opP->con1, 1);
        !          2100:                                addword(0);
        !          2101:                                addword(0);
        !          2102:                            }
        !          2103:                            else if(adds(opP->con1)){
        !          2104:                                add_frag(adds(opP->con1),
        !          2105:                                         offs(opP->con1),
        !          2106:                                         TAB(FBRANCH, SZ_UNDEF));
        !          2107:                            }
        !          2108:                            else{
        !          2109:                                the_ins.opcode[the_ins.numo-1] |= 0x40;
        !          2110:                                opP->con1->e_exp.X_add_number += 4;
        !          2111:                                add_fix('l', opP->con1, 1);
        !          2112:                                addword(0);
        !          2113:                                addword(0);
        !          2114:                            }
        !          2115:                            break;
        !          2116:                        default:
        !          2117:                            as_fatal("Internal error: operand type B%c unknown",
        !          2118:                                     s[1]);
        !          2119:                        }
        !          2120:                        break;
        !          2121: 
        !          2122:                case 'C':               /* Ignore it */
        !          2123:                        break;
        !          2124: 
        !          2125:                case 'd':               /* JF this is a kludge */
        !          2126:                        if(opP->mode==AOFF) {
        !          2127:                                install_operand('s',opP->reg-ADDR);
        !          2128:                        } else {
        !          2129:                                char *tmpP;
        !          2130: 
        !          2131:                                tmpP=opP->con1->e_end-2;
        !          2132:                                opP->con1->e_beg++;
        !          2133:                                opP->con1->e_end-=4;    /* point to the , */
        !          2134:                                baseo=m68k_reg_parse(&tmpP);
        !          2135:                                if(baseo<ADDR+0 || baseo>ADDR+7) {
        !          2136:                                        as_bad("Unknown address reg, using A0");
        !          2137:                                        baseo=0;
        !          2138:                                } else baseo-=ADDR;
        !          2139:                                install_operand('s',baseo);
        !          2140:                        }
        !          2141:                        tmpreg=get_num(opP->con1,80);
        !          2142:                        if(!issword(tmpreg)) {
        !          2143:                                as_warn("Expression out of range, using 0");
        !          2144:                                tmpreg=0;
        !          2145:                        }
        !          2146:                        addword(tmpreg);
        !          2147:                        break;
        !          2148: 
        !          2149:                case 'D':
        !          2150:                        install_operand(s[1],opP->reg-DATA);
        !          2151:                        break;
        !          2152: 
        !          2153:                case 'F':
        !          2154:                        install_operand(s[1],opP->reg-FPREG);
        !          2155:                        break;
        !          2156: 
        !          2157:                case 'I':
        !          2158:                        tmpreg=1+opP->reg-COPNUM;
        !          2159:                        if(tmpreg==8)
        !          2160:                                tmpreg=0;
        !          2161:                        install_operand(s[1],tmpreg);
        !          2162:                        break;
        !          2163: 
        !          2164:                case 'J':               /* JF foo */
        !          2165:                        switch(opP->reg) {
        !          2166:                        case SFC:
        !          2167:                                tmpreg=0;
        !          2168:                                break;
        !          2169:                        case DFC:
        !          2170:                                tmpreg=0x001;
        !          2171:                                break;
        !          2172:                        case CACR:
        !          2173:                                tmpreg=0x002;
        !          2174:                                break;
        !          2175:                        case USP:
        !          2176:                                tmpreg=0x800;
        !          2177:                                break;
        !          2178:                        case VBR:
        !          2179:                                tmpreg=0x801;
        !          2180:                                break;
        !          2181:                        case CAAR:
        !          2182:                                tmpreg=0x802;
        !          2183:                                break;
        !          2184:                        case MSP:
        !          2185:                                tmpreg=0x803;
        !          2186:                                break;
        !          2187:                        case ISP:
        !          2188:                                tmpreg=0x804;
        !          2189:                                break;
        !          2190: #ifdef BUILTIN_MMUS
        !          2191:                        case TC:
        !          2192:                                tmpreg=0x003;
        !          2193:                                break;
        !          2194:                        case ITT0:
        !          2195:                                tmpreg=0x004;
        !          2196:                                break;
        !          2197:                        case ITT1:
        !          2198:                                tmpreg=0x005;
        !          2199:                                break;
        !          2200:                        case DTT0:
        !          2201:                                tmpreg=0x006;
        !          2202:                                break;
        !          2203:                        case DTT1:
        !          2204:                                tmpreg=0x007;
        !          2205:                                break;
        !          2206:                        case MMUSR:
        !          2207:                                tmpreg=0x805;
        !          2208:                                break;
        !          2209:                        case URP:
        !          2210:                                tmpreg=0x806;
        !          2211:                                break;
        !          2212:                        case SRP:
        !          2213:                                tmpreg=0x807;
        !          2214:                                break;
        !          2215: #endif /* BUILTIN_MMUS */
        !          2216:                        default:
        !          2217:                                abort();
        !          2218:                        }
        !          2219:                        install_operand(s[1],tmpreg);
        !          2220:                        break;
        !          2221: #ifdef NeXT
        !          2222:                case '0':
        !          2223:                        tmpreg=opP->reg-ADDR;
        !          2224:                        install_operand(s[1],tmpreg);
        !          2225:                        break;
        !          2226: #endif /* NeXT */
        !          2227: 
        !          2228:                case 'k':
        !          2229:                        tmpreg=get_num(opP->con1,55);
        !          2230:                        install_operand(s[1],tmpreg&0x7f);
        !          2231:                        break;
        !          2232: 
        !          2233:                case 'l':
        !          2234:                        tmpreg=opP->reg;
        !          2235:                        if(s[1]=='w') {
        !          2236:                                if(tmpreg&0x7FF0000)
        !          2237:                                        as_bad("Floating point register in register list");
        !          2238:                                insop(reverse_16_bits(tmpreg));
        !          2239:                        } else {
        !          2240:                                if(tmpreg&0x700FFFF)
        !          2241:                                        as_bad("Wrong register in floating-point reglist");
        !          2242:                                install_operand(s[1],reverse_8_bits(tmpreg>>16));
        !          2243:                        }
        !          2244:                        break;
        !          2245: 
        !          2246:                case 'L':
        !          2247:                        tmpreg=opP->reg;
        !          2248:                        if(s[1]=='w') {
        !          2249:                                if(tmpreg&0x7FF0000)
        !          2250:                                        as_bad("Floating point register in register list");
        !          2251:                                insop(tmpreg);
        !          2252:                        } else if(s[1]=='8') {
        !          2253:                                if(tmpreg&0x0FFFFFF)
        !          2254:                                        as_bad("incorrect register in reglist");
        !          2255:                                install_operand(s[1],tmpreg>>24);
        !          2256:                        } else {
        !          2257:                                if(tmpreg&0x700FFFF)
        !          2258:                                        as_bad("wrong register in floating-point reglist");
        !          2259:                                else
        !          2260:                                        install_operand(s[1],tmpreg>>16);
        !          2261:                        }
        !          2262:                        break;
        !          2263: 
        !          2264:                case 'M':
        !          2265:                        install_operand(s[1],get_num(opP->con1,60));
        !          2266:                        break;
        !          2267: 
        !          2268:                case 'O':
        !          2269:                        tmpreg= (opP->mode==DREG)
        !          2270:                                ? 0x20+opP->reg-DATA
        !          2271:                                : (get_num(opP->con1,40)&0x1F);
        !          2272:                        install_operand(s[1],tmpreg);
        !          2273:                        break;
        !          2274: 
        !          2275:                case 'Q':
        !          2276:                        tmpreg=get_num(opP->con1,10);
        !          2277:                        if(tmpreg==8)
        !          2278:                                tmpreg=0;
        !          2279:                        install_operand(s[1],tmpreg);
        !          2280:                        break;
        !          2281: 
        !          2282:                case 'R':
        !          2283:                        /* This depends on the fact that ADDR registers are
        !          2284:                           eight more than their corresponding DATA regs, so
        !          2285:                           the result will have the ADDR_REG bit set */
        !          2286:                        install_operand(s[1],opP->reg-DATA);
        !          2287:                        break;
        !          2288: 
        !          2289:                case 's':
        !          2290:                        if(opP->reg==FPI) tmpreg=0x1;
        !          2291:                        else if(opP->reg==FPS) tmpreg=0x2;
        !          2292:                        else if(opP->reg==FPC) tmpreg=0x4;
        !          2293:                        else abort();
        !          2294:                        install_operand(s[1],tmpreg);
        !          2295:                        break;
        !          2296: 
        !          2297:                case 'S':       /* Ignore it */
        !          2298:                        break;
        !          2299: 
        !          2300:                case 'T':
        !          2301:                        install_operand(s[1],get_num(opP->con1,30));
        !          2302:                        break;
        !          2303: 
        !          2304:                case 'U':       /* Ignore it */
        !          2305:                        break;
        !          2306: 
        !          2307: #if defined(m68851) || defined(BUILTIN_MMUS)
        !          2308:                        /* JF: These are out of order, I fear. */
        !          2309:                case 'f':
        !          2310:                        switch (opP->reg) {
        !          2311:                        case SFC:
        !          2312:                                tmpreg=0;
        !          2313:                                break;
        !          2314:                        case DFC:
        !          2315:                                tmpreg=1;
        !          2316:                                break;
        !          2317:                        default:
        !          2318:                                abort();
        !          2319:                        }
        !          2320:                        install_operand(s[1],tmpreg);
        !          2321:                        break;
        !          2322: #endif
        !          2323: 
        !          2324: #ifdef BUILTIN_MMUS
        !          2325:                case 'a':
        !          2326:                        switch (opP->reg) {
        !          2327:                        case SRP:
        !          2328:                                tmpreg=2;
        !          2329:                                break;
        !          2330:                        case CRP:
        !          2331:                                tmpreg=3;
        !          2332:                                break;
        !          2333:                        case TC:
        !          2334:                                tmpreg=0;
        !          2335:                                break;
        !          2336:                        default:
        !          2337:                                abort();
        !          2338:                        }
        !          2339:                        install_operand(s[1],tmpreg);
        !          2340:                        break;
        !          2341:                case 'b':
        !          2342:                        switch (opP->reg) {
        !          2343:                        case MMUSR:
        !          2344:                                tmpreg=0;
        !          2345:                                break;
        !          2346:                        default:
        !          2347:                                abort();
        !          2348:                        }
        !          2349:                        install_operand(s[1],tmpreg);
        !          2350:                        break;
        !          2351:                case 'c':
        !          2352:                        switch (opP->reg) {
        !          2353:                        case IC:
        !          2354:                                tmpreg=2;
        !          2355:                                break;
        !          2356:                        case DC:
        !          2357:                                tmpreg=1;
        !          2358:                                break;
        !          2359:                        case BC:
        !          2360:                                tmpreg=3;
        !          2361:                                break;
        !          2362:                        default:
        !          2363:                                abort();
        !          2364:                        }
        !          2365:                        install_operand(s[1],tmpreg);
        !          2366:                        break;
        !          2367:                case 'e':
        !          2368:                        switch (opP->reg) {
        !          2369:                        case TT0:
        !          2370:                                tmpreg=2;
        !          2371:                                break;
        !          2372:                        case TT1:
        !          2373:                                tmpreg=3;
        !          2374:                                break;
        !          2375:                        default:
        !          2376:                                abort();
        !          2377:                        }
        !          2378:                        install_operand(s[1],tmpreg);
        !          2379:                        break;
        !          2380: #endif
        !          2381: 
        !          2382: #ifdef m68851
        !          2383:                case 'P':
        !          2384:                        switch(opP->reg) {
        !          2385:                        case TC:
        !          2386:                                tmpreg=0;
        !          2387:                                break;
        !          2388:                        case CAL:
        !          2389:                                tmpreg=4;
        !          2390:                                break;
        !          2391:                        case VAL:
        !          2392:                                tmpreg=5;
        !          2393:                                break;
        !          2394:                        case SCC:
        !          2395:                                tmpreg=6;
        !          2396:                                break;
        !          2397:                        case AC:
        !          2398:                                tmpreg=7;
        !          2399:                                break;
        !          2400:                        default:
        !          2401:                                abort();
        !          2402:                        }
        !          2403:                        install_operand(s[1],tmpreg);
        !          2404:                        break;
        !          2405: 
        !          2406:                case 'V':
        !          2407:                        if (opP->reg == VAL)
        !          2408:                                break;
        !          2409:                        abort();
        !          2410: 
        !          2411:                case 'W':
        !          2412:                        switch(opP->reg) {
        !          2413: 
        !          2414:                        case DRP:
        !          2415:                                tmpreg=1;
        !          2416:                                break;
        !          2417:                        case SRP:
        !          2418:                                tmpreg=2;
        !          2419:                                break;
        !          2420:                        case CRP:
        !          2421:                                tmpreg=3;
        !          2422:                                break;
        !          2423:                        default:
        !          2424:                                abort();
        !          2425:                        }
        !          2426:                        install_operand(s[1],tmpreg);
        !          2427:                        break;
        !          2428: 
        !          2429:                case 'X':
        !          2430:                        switch (opP->reg) {
        !          2431:                        case BAD: case BAD+1: case BAD+2: case BAD+3:
        !          2432:                        case BAD+4: case BAD+5: case BAD+6: case BAD+7:
        !          2433:                                tmpreg = (4 << 10) | ((opP->reg - BAD) << 2);
        !          2434:                                break;
        !          2435: 
        !          2436:                        case BAC: case BAC+1: case BAC+2: case BAC+3:
        !          2437:                        case BAC+4: case BAC+5: case BAC+6: case BAC+7:
        !          2438:                                tmpreg = (5 << 10) | ((opP->reg - BAC) << 2);
        !          2439:                                break;
        !          2440: 
        !          2441:                        default:
        !          2442:                                abort();
        !          2443:                        }
        !          2444:                        install_operand(s[1], tmpreg);
        !          2445:                        break;
        !          2446:                case 'Y':
        !          2447:                        if (opP->reg == PSR)
        !          2448:                                break;
        !          2449:                        abort();
        !          2450: 
        !          2451:                case 'Z':
        !          2452:                        if (opP->reg == PCSR)
        !          2453:                                break;
        !          2454:                        abort();
        !          2455: #endif /* m68851 */
        !          2456:                default:
        !          2457:                        as_fatal("Internal error:  Operand type %c unknown",s[0]);
        !          2458:                }
        !          2459:        }
        !          2460:        /* By the time whe get here (FINALLY) the_ins contains the complete
        !          2461:           instruction, ready to be emitted. . . */
        !          2462: }
        !          2463: 
        !          2464: static
        !          2465: int
        !          2466: get_regs(
        !          2467: int i,
        !          2468: struct m68k_op *opP,
        !          2469: char *str)
        !          2470: {
        !          2471:        /*                           26, 25, 24, 23-16,  15-8, 0-7 */
        !          2472:        /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */
        !          2473:        unsigned long int cur_regs = 0;
        !          2474:        int     reg1,
        !          2475:                reg2;
        !          2476: 
        !          2477: #define ADD_REG(x)     {     if(x==FPI) cur_regs|=(1<<24);\
        !          2478:                         else if(x==FPS) cur_regs|=(1<<25);\
        !          2479:                         else if(x==FPC) cur_regs|=(1<<26);\
        !          2480:                         else cur_regs|=(1<<(x-1));  }
        !          2481: 
        !          2482:        reg1=i;
        !          2483:        for(;;) {
        !          2484:                if(*str=='/') {
        !          2485:                        ADD_REG(reg1);
        !          2486:                        str++;
        !          2487:                } else if(*str=='-') {
        !          2488:                        str++;
        !          2489:                        reg2=m68k_reg_parse(&str);
        !          2490:                        if(reg2<DATA || reg2>=FPREG+8 || reg1==FPI || reg1==FPS || reg1==FPC) {
        !          2491:                                opP->error="unknown register in register list";
        !          2492:                                return FAIL;
        !          2493:                        }
        !          2494:                        while(reg1<=reg2) {
        !          2495:                                ADD_REG(reg1);
        !          2496:                                reg1++;
        !          2497:                        }
        !          2498:                        if(*str=='\0')
        !          2499:                                break;
        !          2500:                } else if(*str=='\0') {
        !          2501:                        ADD_REG(reg1);
        !          2502:                        break;
        !          2503:                } else {
        !          2504:                        opP->error="unknow character in register list";
        !          2505:                        return FAIL;
        !          2506:                }
        !          2507: /* DJA -- Bug Fix.  Did't handle d1-d2/a1 until the following instruction was added */
        !          2508:                if (*str=='/')
        !          2509:                  str ++;
        !          2510:                reg1=m68k_reg_parse(&str);
        !          2511:                if((reg1<DATA || reg1>=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) {
        !          2512:                        opP->error="unknown register in register list";
        !          2513:                        return FAIL;
        !          2514:                }
        !          2515:        }
        !          2516:        opP->reg=cur_regs;
        !          2517:        return OK;
        !          2518: }
        !          2519: 
        !          2520: static
        !          2521: int
        !          2522: reverse_16_bits(
        !          2523: int in)
        !          2524: {
        !          2525:        int out=0;
        !          2526:        int n;
        !          2527: 
        !          2528:        static int mask[16] = {
        !          2529: 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
        !          2530: 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000
        !          2531:        };
        !          2532:        for(n=0;n<16;n++) {
        !          2533:                if(in&mask[n])
        !          2534:                        out|=mask[15-n];
        !          2535:        }
        !          2536:        return out;
        !          2537: }
        !          2538: 
        !          2539: static
        !          2540: int
        !          2541: reverse_8_bits(
        !          2542: int in)
        !          2543: {
        !          2544:        int out=0;
        !          2545:        int n;
        !          2546: 
        !          2547:        static int mask[8] = {
        !          2548: 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
        !          2549:        };
        !          2550: 
        !          2551:        for(n=0;n<8;n++) {
        !          2552:                if(in&mask[n])
        !          2553:                        out|=mask[7-n];
        !          2554:        }
        !          2555:        return out;
        !          2556: }
        !          2557: 
        !          2558: static
        !          2559: void
        !          2560: install_operand(
        !          2561: int mode,
        !          2562: int val)
        !          2563: {
        !          2564:        switch(mode) {
        !          2565:        case 's':
        !          2566:                the_ins.opcode[0]|=val & 0xFF;  /* JF FF is for M kludge */
        !          2567:                break;
        !          2568:        case 'd':
        !          2569:                the_ins.opcode[0]|=val<<9;
        !          2570:                break;
        !          2571:        case '1':
        !          2572:                the_ins.opcode[1]|=val<<12;
        !          2573:                break;
        !          2574:        case '2':
        !          2575:                the_ins.opcode[1]|=val<<6;
        !          2576:                break;
        !          2577:        case '3':
        !          2578:                the_ins.opcode[1]|=val;
        !          2579:                break;
        !          2580:        case '4':
        !          2581:                the_ins.opcode[2]|=val<<12;
        !          2582:                break;
        !          2583:        case '5':
        !          2584:                the_ins.opcode[2]|=val<<6;
        !          2585:                break;
        !          2586:        case '6':
        !          2587:                        /* DANGER!  This is a hack to force cas2l and cas2w cmds
        !          2588:                           to be three words long! */
        !          2589:                the_ins.numo++;
        !          2590:                the_ins.opcode[2]|=val;
        !          2591:                break;
        !          2592:        case '7':
        !          2593:                the_ins.opcode[1]|=val<<7;
        !          2594:                break;
        !          2595:        case '8':
        !          2596:                the_ins.opcode[1]|=val<<10;
        !          2597:                break;
        !          2598: #if defined(m68851) || defined(BUILTIN_MMUS)
        !          2599:        case '9':
        !          2600:                the_ins.opcode[1]|=val<<5;
        !          2601:                break;
        !          2602: #endif
        !          2603: #ifdef BUILTIN_MMUS
        !          2604:        case 'S':
        !          2605:                the_ins.opcode[0]|=val<<6;
        !          2606:                break;
        !          2607: #endif
        !          2608:        case 't':
        !          2609:                the_ins.opcode[1]|=(val<<10)|(val<<7);
        !          2610:                break;
        !          2611:        case 'D':
        !          2612:                the_ins.opcode[1]|=(val<<12)|val;
        !          2613:                break;
        !          2614:        case 'g':
        !          2615:                the_ins.opcode[0]|=val=0xff;
        !          2616:                break;
        !          2617:        case 'i':
        !          2618:                the_ins.opcode[0]|=val<<9;
        !          2619:                break;
        !          2620:        case 'C':
        !          2621:                the_ins.opcode[1]|=val;
        !          2622:                break;
        !          2623:        case 'j':
        !          2624:                the_ins.opcode[1]|=val;
        !          2625:                the_ins.numo++;         /* What a hack */
        !          2626:                break;
        !          2627:        case 'k':
        !          2628:                the_ins.opcode[1]|=val<<4;
        !          2629:                break;
        !          2630:        case 'b':
        !          2631:        case 'w':
        !          2632:        case 'l':
        !          2633:                break;
        !          2634:        case 'c':
        !          2635:        default:
        !          2636:                abort();
        !          2637:        }
        !          2638: }
        !          2639: 
        !          2640: static
        !          2641: void
        !          2642: install_gen_operand(
        !          2643: int mode,
        !          2644: int val)
        !          2645: {
        !          2646:        switch(mode) {
        !          2647:        case 's':
        !          2648:                the_ins.opcode[0]|=val;
        !          2649:                break;
        !          2650:        case 'd':
        !          2651:                        /* This is a kludge!!! */
        !          2652:                the_ins.opcode[0]|=(val&0x07)<<9|(val&0x38)<<3;
        !          2653:                break;
        !          2654:        case 'b':
        !          2655:        case 'w':
        !          2656:        case 'l':
        !          2657:        case 'f':
        !          2658:        case 'F':
        !          2659:        case 'x':
        !          2660:        case 'p':
        !          2661:                the_ins.opcode[0]|=val;
        !          2662:                break;
        !          2663:                /* more stuff goes here */
        !          2664:        default:
        !          2665:                abort();
        !          2666:        }
        !          2667: }
        !          2668: 
        !          2669: static
        !          2670: char *
        !          2671: crack_operand(
        !          2672: char *str,
        !          2673: struct m68k_op *opP)
        !          2674: {
        !          2675:        register int parens;
        !          2676:        register int c;
        !          2677:        register char *beg_str;
        !          2678: 
        !          2679:        if(!str) {
        !          2680:                return str;
        !          2681:        }
        !          2682:        beg_str=str;
        !          2683:        for(parens=0;*str && (parens>0 || notend(str));str++) {
        !          2684:                if(*str == '"') {
        !          2685:                        str++;
        !          2686:                        while(*str && *str != '"')
        !          2687:                                str++;
        !          2688:                        if(*str != '"'){        /* ERROR */
        !          2689:                                opP->error="Missing \"";
        !          2690:                                return str;
        !          2691:                        }
        !          2692:                }
        !          2693:                else{   
        !          2694:                        if(*str=='(')
        !          2695:                                parens++;
        !          2696:                        else if(*str==')') {
        !          2697:                                if(!parens) {           /* ERROR */
        !          2698:                                        opP->error="Extra )";
        !          2699:                                        return str;
        !          2700:                                }
        !          2701:                                --parens;
        !          2702:                        }
        !          2703:                }
        !          2704:        }
        !          2705:        if(!*str && parens) {           /* ERROR */
        !          2706:                opP->error="Missing )";
        !          2707:                return str;
        !          2708:        }
        !          2709:        c= *str;
        !          2710:        *str='\0';
        !          2711:        if(m68k_ip_op(beg_str,opP)==FAIL) {
        !          2712:                *str=c;
        !          2713:                return str;
        !          2714:        }
        !          2715:        *str=c;
        !          2716:        if(c=='}')
        !          2717:                c= *++str;              /* JF bitfield hack */
        !          2718:        if(c) {
        !          2719:                c= *++str;
        !          2720:                if(!c)
        !          2721:                        as_bad("Missing operand");
        !          2722:        }
        !          2723:        return str;
        !          2724: }
        !          2725: 
        !          2726: /* See the comment up above where the #define notend(... is */
        !          2727: #if 0
        !          2728: notend(s)
        !          2729: char *s;
        !          2730: {
        !          2731:        if(*s==',') return 0;
        !          2732:        if(*s=='{' || *s=='}')
        !          2733:                return 0;
        !          2734:        if(*s!=':') return 1;
        !          2735:                /* This kludge here is for the division cmd, which is a kludge */
        !          2736:        if(index("aAdD#",s[1])) return 0;
        !          2737:        return 1;
        !          2738: }
        !          2739: #endif /* 0 */
        !          2740: 
        !          2741: #ifdef NeXT
        !          2742: static char *file_030, *file_040;
        !          2743: static unsigned long line_030, line_040;
        !          2744: #endif /* NeXT */
        !          2745: 
        !          2746: /* This is the guts of the machine-dependent assembler.  STR points to a
        !          2747:    machine dependent instruction.  This funciton is supposed to emit
        !          2748:    the frags/bytes it assembles to.
        !          2749:  */
        !          2750: void
        !          2751: md_assemble(
        !          2752: char *str)
        !          2753: {
        !          2754:        char *er;
        !          2755:        short   *fromP;
        !          2756:        char    *toP = NULL;
        !          2757:        int     m,n;
        !          2758:        char    *to_beg_P;
        !          2759:        int     shorts_this_frag;
        !          2760: 
        !          2761:        memset((char *)(&the_ins), '\0', sizeof(the_ins));
        !          2762:        m68_ip(str);
        !          2763:        er=the_ins.error;
        !          2764:        if(!er) {
        !          2765:                for(n=the_ins.numargs;n;--n)
        !          2766:                        if(the_ins.operands[n].error) {
        !          2767:                                er=the_ins.operands[n].error;
        !          2768:                                break;
        !          2769:                        }
        !          2770:        }
        !          2771:        if(er) {
        !          2772:                as_bad("\"%s\" -- Statement '%s' ignored",er,str);
        !          2773:                return;
        !          2774:        }
        !          2775: 
        !          2776: #ifdef NeXT
        !          2777:        if(the_ins.cpus != NULL && !force_cpusubtype_ALL){
        !          2778:            if(md_cpusubtype == CPU_SUBTYPE_MC680x0_ALL){
        !          2779:                switch(*the_ins.cpus){
        !          2780:                case '2':
        !          2781:                    as_bad("implementation specific instruction for the MC68020"
        !          2782:                           " and -force_cpusubtype_ALL not specified");
        !          2783:                    break;
        !          2784:                case '3':
        !          2785:                    if(archflag_cpusubtype == CPU_SUBTYPE_MC68040)
        !          2786:                        as_bad("030 instruction not allowed with -arch m68040");
        !          2787:                    else{
        !          2788:                        file_030 = logical_input_file ?
        !          2789:                                   logical_input_file : physical_input_file;
        !          2790:                        line_030 = logical_input_line ?
        !          2791:                                   logical_input_line : physical_input_line;
        !          2792:                        md_cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
        !          2793:                    }
        !          2794:                    break;
        !          2795:                case '4':
        !          2796:                    if(archflag_cpusubtype == CPU_SUBTYPE_MC68030_ONLY)
        !          2797:                        as_bad("040 instruction not allowed with -arch m68030");
        !          2798:                    else{
        !          2799:                        file_040 = logical_input_file ?
        !          2800:                                   logical_input_file : physical_input_file;
        !          2801:                        line_040 = logical_input_line ?
        !          2802:                                   logical_input_line : physical_input_line;
        !          2803:                        md_cpusubtype = CPU_SUBTYPE_MC68040;
        !          2804:                    }
        !          2805:                    break;
        !          2806:                }
        !          2807:            }
        !          2808:            else{
        !          2809:                switch(*the_ins.cpus){
        !          2810:                case '2':
        !          2811:                    as_bad("implementation specific instruction for the MC68020"
        !          2812:                           " and -force_cpusubtype_ALL not specified");
        !          2813:                    break;
        !          2814:                case '3':
        !          2815:                    if(archflag_cpusubtype == CPU_SUBTYPE_MC68040)
        !          2816:                        as_bad("030 instruction not allowed with -arch m68040");
        !          2817:                    else{
        !          2818:                        if(md_cpusubtype != CPU_SUBTYPE_MC680x0_ALL &&
        !          2819:                           md_cpusubtype != CPU_SUBTYPE_MC68030_ONLY)
        !          2820:                            as_bad("more than one implementation specific "
        !          2821:                                   "instruction seen and -force_cpusubtype_ALL "
        !          2822:                                   " not specified (first 040 instruction in: "
        !          2823:                                   "%s at line %lu)", file_040, line_040);
        !          2824:                        md_cpusubtype = CPU_SUBTYPE_MC68030_ONLY;
        !          2825:                    }
        !          2826:                    break;
        !          2827:                case '4':
        !          2828:                    if(archflag_cpusubtype == CPU_SUBTYPE_MC68030_ONLY)
        !          2829:                        as_bad("040 instruction not allowed with -arch m68030");
        !          2830:                    else{
        !          2831:                        if(md_cpusubtype != CPU_SUBTYPE_MC680x0_ALL &&
        !          2832:                           md_cpusubtype != CPU_SUBTYPE_MC68040)
        !          2833:                            as_bad("more than one implementation specific "
        !          2834:                                   "instruction seen and -force_cpusubtype_ALL "
        !          2835:                                   "not specified (first 030 instruction in: "
        !          2836:                                   "%s at line %lu)", file_030, line_030);
        !          2837:                        md_cpusubtype = CPU_SUBTYPE_MC68040;
        !          2838:                    }
        !          2839:                    break;
        !          2840:                }
        !          2841:            }
        !          2842:        }
        !          2843: #endif /* NeXT */
        !          2844: 
        !          2845: #ifdef NeXT    /* generate stabs for debugging assembly code */
        !          2846:        /*
        !          2847:         * If the -g flag is present generate a line number stab for the
        !          2848:         * instruction.
        !          2849:         * 
        !          2850:         * See the detailed comments about stabs in read_a_source_file() for a
        !          2851:         * description of what is going on here.
        !          2852:         */
        !          2853:        if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){
        !          2854:            (void)symbol_new(
        !          2855:                  "",
        !          2856:                  68 /* N_SLINE */,
        !          2857:                  text_nsect,
        !          2858:                  logical_input_line /* n_desc, line number */,
        !          2859:                  obstack_next_free(&frags) - frag_now->fr_literal,
        !          2860:                  frag_now);
        !          2861:        }
        !          2862: #endif /* NeXT */
        !          2863: 
        !          2864:        if(the_ins.nfrag==0) {  /* No frag hacking involved; just put it out */
        !          2865:                toP=frag_more(2*the_ins.numo);
        !          2866:                fromP= &the_ins.opcode[0];
        !          2867:                for(m=the_ins.numo;m;--m) {
        !          2868:                        md_number_to_chars(toP,(long)(*fromP),2);
        !          2869:                        toP+=2;
        !          2870:                        fromP++;
        !          2871:                }
        !          2872:                        /* put out symbol-dependent info */
        !          2873:                for(m=0;m<the_ins.nrel;m++) {
        !          2874:                        switch(the_ins.reloc[m].wid) {
        !          2875:                        case 'B':
        !          2876:                                n=1;
        !          2877:                                break;
        !          2878:                        case 'b':
        !          2879:                                n=1;
        !          2880:                                break;
        !          2881:                        case '3':
        !          2882: #ifdef NeXT
        !          2883:                                /* This is a bug fix that is not in the 1.36
        !          2884:                                 * version of GAS for this construct:
        !          2885:                                 *      fmovemx #foo,a0@-
        !          2886:                                 * foo = 0xffff;
        !          2887:                                 * Where the width of the relocation should be
        !          2888:                                 * one byte (the low 8 bits of the second word)
        !          2889:                                 * for the floating point register mask. Other-                                  * wise the next byte after this instruction
        !          2890:                                 * gets trashed by this relocation.
        !          2891:                                 */
        !          2892:                                n=1;
        !          2893: #else /* !defined(NeXT) */
        !          2894:                                n=2;
        !          2895: #endif /* NeXT */
        !          2896:                                break;
        !          2897:                        case 'w':
        !          2898:                                n=2;
        !          2899:                                break;
        !          2900:                        case 'l':
        !          2901:                                n=4;
        !          2902:                                break;
        !          2903:                        default:
        !          2904:                                as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins.reloc[m].wid);
        !          2905:                        }
        !          2906: 
        !          2907:                        fix_new(frag_now,
        !          2908:                                (toP - frag_now->fr_literal) -
        !          2909:                                    the_ins.numo * 2 + the_ins.reloc[m].n,
        !          2910:                                n,
        !          2911:                                the_ins.reloc[m].add,
        !          2912:                                the_ins.reloc[m].sub,
        !          2913:                                the_ins.reloc[m].off,
        !          2914:                                the_ins.reloc[m].pcrel,
        !          2915:                                0,0);
        !          2916:                }
        !          2917:                return;
        !          2918:        }
        !          2919: 
        !          2920:                /* There's some frag hacking */
        !          2921:        for(n=0,fromP= &the_ins.opcode[0];n<the_ins.nfrag;n++) {
        !          2922:                int wid;
        !          2923: 
        !          2924:                if(n==0) wid=2*the_ins.fragb[n].fragoff;
        !          2925:                else wid=2*(the_ins.numo-the_ins.fragb[n-1].fragoff);
        !          2926:                toP=frag_more(wid);
        !          2927:                to_beg_P=toP;
        !          2928:                shorts_this_frag=0;
        !          2929:                for(m=wid/2;m;--m) {
        !          2930:                        md_number_to_chars(toP,(long)(*fromP),2);
        !          2931:                        toP+=2;
        !          2932:                        fromP++;
        !          2933:                        shorts_this_frag++;
        !          2934:                }
        !          2935:                for(m=0;m<the_ins.nrel;m++) {
        !          2936:                        if((the_ins.reloc[m].n)>= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */) {
        !          2937:                                the_ins.reloc[m].n-= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */;
        !          2938:                                break;
        !          2939:                        }
        !          2940:                        wid=the_ins.reloc[m].wid;
        !          2941:                        if(wid==0)
        !          2942:                                continue;
        !          2943:                        the_ins.reloc[m].wid=0;
        !          2944:                        wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000;
        !          2945: 
        !          2946:                        fix_new(frag_now,
        !          2947:                                (toP - frag_now->fr_literal) -
        !          2948:                                    the_ins.numo * 2 + the_ins.reloc[m].n,
        !          2949:                                wid,
        !          2950:                                the_ins.reloc[m].add,
        !          2951:                                the_ins.reloc[m].sub,
        !          2952:                                the_ins.reloc[m].off,
        !          2953:                                the_ins.reloc[m].pcrel,
        !          2954:                                0,0);
        !          2955:                }
        !          2956:                know(the_ins.fragb[n].fadd);
        !          2957:                (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty),
        !          2958:  the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P);
        !          2959:        }
        !          2960:        n=(the_ins.numo-the_ins.fragb[n-1].fragoff);
        !          2961:        shorts_this_frag=0;
        !          2962:        if(n) {
        !          2963:                toP=frag_more(n*sizeof(short));
        !          2964:                while(n--) {
        !          2965:                        md_number_to_chars(toP,(long)(*fromP),2);
        !          2966:                        toP+=2;
        !          2967:                        fromP++;
        !          2968:                        shorts_this_frag++;
        !          2969:                }
        !          2970:        }
        !          2971:        for(m=0;m<the_ins.nrel;m++) {
        !          2972:                int wid;
        !          2973: 
        !          2974:                wid=the_ins.reloc[m].wid;
        !          2975:                if(wid==0)
        !          2976:                        continue;
        !          2977:                the_ins.reloc[m].wid=0;
        !          2978:                wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000;
        !          2979: 
        !          2980:                fix_new(frag_now,
        !          2981:                        (the_ins.reloc[m].n + toP-frag_now->fr_literal) -
        !          2982:                            /* the_ins.numo */ shorts_this_frag * 2,
        !          2983:                        wid,
        !          2984:                        the_ins.reloc[m].add,
        !          2985:                        the_ins.reloc[m].sub,
        !          2986:                        the_ins.reloc[m].off,
        !          2987:                        the_ins.reloc[m].pcrel,
        !          2988:                        0,0);
        !          2989:        }
        !          2990: }
        !          2991: 
        !          2992: /* This function is called once, at assembler startup time.  This should
        !          2993:    set up all the tables, etc that the MD part of the assembler needs
        !          2994:  */
        !          2995: void
        !          2996: md_begin(
        !          2997: void)
        !          2998: {
        !          2999: /*
        !          3000:  * md_begin -- set up hash tables with 68000 instructions.
        !          3001:  * similar to what the vax assembler does.  ---phr
        !          3002:  */
        !          3003:        /* RMS claims the thing to do is take the m68k-opcode.h table, and make
        !          3004:           a copy of it at runtime, adding in the information we want but isn't
        !          3005:           there.  I think it'd be better to have an awk script hack the table
        !          3006:           at compile time.  Or even just xstr the table and use it as-is.  But
        !          3007:           my lord ghod hath spoken, so we do it this way.  Excuse the ugly var
        !          3008:           names.  */
        !          3009: 
        !          3010:        register struct m68k_opcode *ins;
        !          3011:        register struct m68_incant *hack,
        !          3012:                *slak;
        !          3013:        register char *retval = 0;              /* empty string, or error msg text */
        !          3014:        register int i;
        !          3015:        register char c;
        !          3016: 
        !          3017:        if ((op_hash = hash_new()) == NULL)
        !          3018:                as_fatal("Virtual memory exhausted");
        !          3019: 
        !          3020:        obstack_begin(&robyn,4000);
        !          3021:        for (ins = (struct m68k_opcode *)m68k_opcodes; ins < endop; ins++) {
        !          3022:                hack=slak=(struct m68_incant *)obstack_alloc(&robyn,sizeof(struct m68_incant));
        !          3023:                do {
        !          3024:                        slak->m_operands=ins->args;
        !          3025:                        slak->m_opnum=strlen(slak->m_operands)/2;
        !          3026:                        slak->m_opcode=ins->opcode;
        !          3027:                                /* This is kludgey */
        !          3028:                        slak->m_codenum=((ins->match)&0xffffL) ? 2 : 1;
        !          3029: #ifdef NeXT
        !          3030:                        slak->m_cpus = ins->cpus;
        !          3031: #endif /* NeXT */
        !          3032:                        if((ins+1)!=endop && !strcmp(ins->name,(ins+1)->name)) {
        !          3033:                                slak->m_next=(struct m68_incant *)
        !          3034: obstack_alloc(&robyn,sizeof(struct m68_incant));
        !          3035:                                ins++;
        !          3036:                        } else
        !          3037:                                slak->m_next=0;
        !          3038:                        slak=slak->m_next;
        !          3039:                } while(slak);
        !          3040: 
        !          3041:                retval = hash_insert (op_hash, ins->name,(char *)hack);
        !          3042:                        /* Didn't his mommy tell him about null pointers? */
        !          3043:                if(retval && *retval)
        !          3044:                        as_fatal("Internal Error:  Can't hash %s: %s",ins->name,retval);
        !          3045:        }
        !          3046: 
        !          3047:        for (i = 0; i < sizeof(mklower_table) ; i++)
        !          3048:                mklower_table[i] = (isupper(c = (char) i)) ? tolower(c) : c;
        !          3049: 
        !          3050:        for (i = 0 ; i < sizeof(notend_table) ; i++) {
        !          3051:                notend_table[i] = 0;
        !          3052:                alt_notend_table[i] = 0;
        !          3053:        }
        !          3054:        notend_table[','] = 1;
        !          3055:        notend_table['{'] = 1;
        !          3056:        notend_table['}'] = 1;
        !          3057:        alt_notend_table['a'] = 1;
        !          3058:        alt_notend_table['A'] = 1;
        !          3059:        alt_notend_table['d'] = 1;
        !          3060:        alt_notend_table['D'] = 1;
        !          3061:        alt_notend_table['#'] = 1;
        !          3062:        alt_notend_table['f'] = 1;
        !          3063:        alt_notend_table['F'] = 1;
        !          3064: }
        !          3065: 
        !          3066: #if 0
        !          3067: #define notend(s) ((*s == ',' || *s == '}' || *s == '{' \
        !          3068:                    || (*s == ':' && index("aAdD#", s[1]))) \
        !          3069:                ? 0 : 1)
        !          3070: #endif
        !          3071: 
        !          3072: /* This funciton is called once, before the assembler exits.  It is
        !          3073:    supposed to do any final cleanup for this part of the assembler.
        !          3074:  */
        !          3075: void
        !          3076: md_end(
        !          3077: void)
        !          3078: {
        !          3079: }
        !          3080: 
        !          3081: /* Equal to MAX_PRECISION in atof-ieee.c */
        !          3082: #define MAX_LITTLENUMS 6
        !          3083: 
        !          3084: /* Turn a string in input_line_pointer into a floating point constant of type
        !          3085:    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
        !          3086:    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
        !          3087:  */
        !          3088: char *
        !          3089: md_atof(
        !          3090: int type,
        !          3091: char *litP,
        !          3092: int *sizeP)
        !          3093: {
        !          3094:        int     prec;
        !          3095:        LITTLENUM_TYPE words[MAX_LITTLENUMS];
        !          3096:        LITTLENUM_TYPE *wordP;
        !          3097:        char    *t;
        !          3098: 
        !          3099:        switch(type) {
        !          3100:        case 'f':
        !          3101:        case 'F':
        !          3102:        case 's':
        !          3103:        case 'S':
        !          3104:                prec = 2;
        !          3105:                break;
        !          3106: 
        !          3107:        case 'd':
        !          3108:        case 'D':
        !          3109:        case 'r':
        !          3110:        case 'R':
        !          3111:                prec = 4;
        !          3112:                break;
        !          3113: 
        !          3114:        case 'x':
        !          3115:        case 'X':
        !          3116:                prec = 6;
        !          3117:                break;
        !          3118: 
        !          3119:        case 'p':
        !          3120:        case 'P':
        !          3121:                prec = 6;
        !          3122:                break;
        !          3123: 
        !          3124:        default:
        !          3125:                *sizeP=0;
        !          3126:                return "Bad call to MD_ATOF()";
        !          3127:        }
        !          3128:        t=atof_ieee(input_line_pointer,type,words);
        !          3129:        if(t)
        !          3130:                input_line_pointer=t;
        !          3131: 
        !          3132:        *sizeP=prec * sizeof(LITTLENUM_TYPE);
        !          3133:        for(wordP=words;prec--;) {
        !          3134:                md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
        !          3135:                litP+=sizeof(LITTLENUM_TYPE);
        !          3136:        }
        !          3137:        return "";      /* Someone should teach Dean about null pointers */
        !          3138: }
        !          3139: 
        !          3140: /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
        !          3141:    for use in the a.out file, and stores them in the array pointed to by buf.
        !          3142:    This knows about the endian-ness of the target machine and does
        !          3143:    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
        !          3144:    2 (short) and 4 (long)  Floating numbers are put out as a series of
        !          3145:    LITTLENUMS (shorts, here at least)
        !          3146:  */
        !          3147: void
        !          3148: md_number_to_chars(
        !          3149: char *buf,
        !          3150: long val,
        !          3151: int n)
        !          3152: {
        !          3153:        switch(n) {
        !          3154:        case 1:
        !          3155:                *buf++=val;
        !          3156:                break;
        !          3157:        case 2:
        !          3158:                *buf++=(val>>8);
        !          3159:                *buf++=val;
        !          3160:                break;
        !          3161:        case 4:
        !          3162:                *buf++=(val>>24);
        !          3163:                *buf++=(val>>16);
        !          3164:                *buf++=(val>>8);
        !          3165:                *buf++=val;
        !          3166:                break;
        !          3167:        default:
        !          3168:                abort();
        !          3169:        }
        !          3170: }
        !          3171: 
        !          3172: void
        !          3173: md_number_to_imm(
        !          3174: unsigned char *buf,
        !          3175: long val,
        !          3176: int n,
        !          3177: fixS *fixP,
        !          3178: int nsect)
        !          3179: {
        !          3180:        switch(n) {
        !          3181:        case 1:
        !          3182:                *buf++=val;
        !          3183:                break;
        !          3184:        case 2:
        !          3185:                *buf++=(val>>8);
        !          3186:                *buf++=val;
        !          3187:                break;
        !          3188:        case 4:
        !          3189:                *buf++=(val>>24);
        !          3190:                *buf++=(val>>16);
        !          3191:                *buf++=(val>>8);
        !          3192:                *buf++=val;
        !          3193:                break;
        !          3194:        default:
        !          3195:                abort();
        !          3196:        }
        !          3197: }
        !          3198: 
        !          3199: /*
        !          3200:  * Force truly undefined symbols to their maximum size, and generally set up
        !          3201:  * the frag list to be relaxed.  It is the caller's responsiblity to set the
        !          3202:  * current section, frchain_now, to the corresponding nsect specified so that
        !          3203:  * calls to fix_new() will make fixes for this section.
        !          3204:  */
        !          3205: int
        !          3206: md_estimate_size_before_relax(
        !          3207: fragS *fragP,
        !          3208: int nsect)
        !          3209: {
        !          3210:     int old_fix;
        !          3211: 
        !          3212:        old_fix = fragP->fr_fix;
        !          3213: 
        !          3214:        /*
        !          3215:         * Handle SZ_UNDEF first, it can be changed to BYTE or SHORT.
        !          3216:         */
        !          3217:        switch(fragP->fr_subtype){
        !          3218:        case TAB(DBCC, SZ_UNDEF):
        !          3219:            if(fragP->fr_symbol->sy_nlist.n_sect == nsect){
        !          3220:                fragP->fr_subtype = TAB(DBCC, SHORT);
        !          3221:                fragP->fr_var += 2;
        !          3222:                break;
        !          3223:            }
        !          3224:            /*
        !          3225:             * Only DBcc 68000 instructions can come here.
        !          3226:             * Change dbcc into dbcc/jmp absl long.
        !          3227:             */
        !          3228:            fragP->fr_opcode[2] = 0x00;  /* branch offset = 4 */
        !          3229:            fragP->fr_opcode[3] = 0x04;  
        !          3230:            fragP->fr_opcode[4] = 0x60;  /* put in bra pc+6 */ 
        !          3231:            fragP->fr_opcode[5] = 0x06;  
        !          3232:            fragP->fr_opcode[6] = 0x4e;  /* put in jmp long (0x4ef9) */ 
        !          3233:            fragP->fr_opcode[7] = 0xf9;  
        !          3234:            fragP->fr_fix += 6;   /* account for bra/jmp instructions */
        !          3235:            fix_new(fragP,
        !          3236:                    fragP->fr_fix,
        !          3237:                    4,
        !          3238:                    fragP->fr_symbol,
        !          3239:                    0,
        !          3240:                    fragP->fr_offset,
        !          3241:                    0,
        !          3242:                    0,
        !          3243:                    0);
        !          3244:            fragP->fr_fix += 4; /* account for jmp instruction displacement */
        !          3245:            frag_wane(fragP);
        !          3246:            break;
        !          3247: 
        !          3248:        case TAB(BCC68000, SZ_UNDEF):
        !          3249:            if(fragP->fr_symbol->sy_nlist.n_sect == nsect){
        !          3250:                fragP->fr_subtype = TAB(BCC68000, BYTE);
        !          3251:                break;
        !          3252:            }
        !          3253:            /*
        !          3254:             * Only Bcc 68000 instructions can come here.
        !          3255:             * Change bcc into b!cc/jmp absl long.
        !          3256:             */
        !          3257:            fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
        !          3258:            fragP->fr_opcode[1] = 0x6;   /* branch offset = 6 */
        !          3259:            fragP->fr_opcode[2] = 0x4e;  /* put in jmp long (0x4ef9) */ 
        !          3260:            fragP->fr_opcode[3] = 0xf9;  
        !          3261:            fragP->fr_fix += 2;      /* account for jmp instruction */
        !          3262:            fix_new(fragP,
        !          3263:                    fragP->fr_fix,
        !          3264:                    4,
        !          3265:                    fragP->fr_symbol,
        !          3266:                    0, 
        !          3267:                    fragP->fr_offset,
        !          3268:                    0,
        !          3269:                    0,
        !          3270:                    0);
        !          3271:            fragP->fr_fix += 4; /* account for jmp instruction displacement */
        !          3272:            frag_wane(fragP);
        !          3273:            break;
        !          3274: 
        !          3275:        case TAB(BRANCH, SZ_UNDEF):
        !          3276:            if(fragP->fr_symbol->sy_nlist.n_sect == nsect){
        !          3277:                /*
        !          3278:                 * The NeXT linker has the ability to scatter blocks of
        !          3279:                 * sections between labels.  This requires that brances to
        !          3280:                 * labels that survive to the link phase must be able to
        !          3281:                 * be relocated.
        !          3282:                 */
        !          3283:                if(fragP->fr_symbol->sy_name[0] != 'L' || flagseen ['L']){
        !          3284:                    fix_new(fragP,
        !          3285:                            fragP->fr_fix,
        !          3286:                            4,
        !          3287:                            fragP->fr_symbol,
        !          3288:                            0,
        !          3289:                            fragP->fr_offset + 4,
        !          3290:                            1,
        !          3291:                            1,
        !          3292:                            0);
        !          3293:                    fragP->fr_fix += 4;
        !          3294:                    fragP->fr_opcode[1] = 0xff;
        !          3295:                    frag_wane(fragP);
        !          3296:                    break;
        !          3297:                }
        !          3298:                else
        !          3299:                    fragP->fr_subtype = TAB(BRANCH, BYTE);
        !          3300:                break;
        !          3301:            }
        !          3302:            else if(flagseen['m']){
        !          3303:                if(fragP->fr_opcode[0] == 0x61){
        !          3304:                    fragP->fr_opcode[0] = 0x4E;
        !          3305:                    fragP->fr_opcode[1] = 0xB9; /* JBSR with ABSL LONG offset */
        !          3306:                    fix_new(fragP,
        !          3307:                            fragP->fr_fix,
        !          3308:                            4, 
        !          3309:                            fragP->fr_symbol,
        !          3310:                            0,
        !          3311:                            fragP->fr_offset,
        !          3312:                            0,
        !          3313:                            0,
        !          3314:                            0);
        !          3315:                    fragP->fr_fix += 4;
        !          3316:                    frag_wane(fragP);
        !          3317:                }
        !          3318:                else if(fragP->fr_opcode[0] == 0x60){
        !          3319:                    fragP->fr_opcode[0] = 0x4E;
        !          3320:                    fragP->fr_opcode[1] = 0xF9;  /* JMP with ABSL LONG offset */
        !          3321:                    fix_new(fragP,
        !          3322:                            fragP->fr_fix,
        !          3323:                            4, 
        !          3324:                            fragP->fr_symbol,
        !          3325:                            0,
        !          3326:                            fragP->fr_offset,
        !          3327:                            0,
        !          3328:                            0,
        !          3329:                            0);
        !          3330:                    fragP->fr_fix += 4;
        !          3331:                    frag_wane(fragP);
        !          3332:                }
        !          3333:                else{
        !          3334:                    as_warn("Long branch offset to extern symbol not "
        !          3335:                            "supported.");
        !          3336:                }
        !          3337:                break;
        !          3338:            }
        !          3339:            else{
        !          3340:                /* Symbol is still undefined.  Make it simple */
        !          3341:                fix_new(fragP,
        !          3342:                        fragP->fr_fix,
        !          3343:                        4,
        !          3344:                        fragP->fr_symbol,
        !          3345:                        0,
        !          3346:                        fragP->fr_offset + 4,
        !          3347:                        1,
        !          3348:                        1,
        !          3349:                        0);
        !          3350:                fragP->fr_fix += 4;
        !          3351:                fragP->fr_opcode[1] = 0xff;
        !          3352:                frag_wane(fragP);
        !          3353:                break;
        !          3354:            }
        !          3355:            break;
        !          3356: 
        !          3357:        case TAB(FBRANCH, SZ_UNDEF):
        !          3358:            if(fragP->fr_symbol->sy_nlist.n_sect == nsect){
        !          3359:                /*
        !          3360:                 * The NeXT linker has the ability to scatter blocks of
        !          3361:                 * sections between labels.  This requires that brances to
        !          3362:                 * labels that survive to the link phase must be able to
        !          3363:                 * be relocated.
        !          3364:                 */
        !          3365:                if(fragP->fr_symbol->sy_name[0] != 'L' || flagseen ['L']) {
        !          3366:                    fix_new(fragP,
        !          3367:                            fragP->fr_fix,
        !          3368:                            4,
        !          3369:                            fragP->fr_symbol,
        !          3370:                            0,
        !          3371:                            fragP->fr_offset + 4,
        !          3372:                            1,
        !          3373:                            1,
        !          3374:                            0);
        !          3375:                    fragP->fr_fix += 4;
        !          3376:                    fragP->fr_opcode[1] |= 0x40;
        !          3377:                    frag_wane(fragP);
        !          3378:                    break;
        !          3379:                }
        !          3380:                else{
        !          3381:                    fragP->fr_subtype = TAB(FBRANCH, SHORT);
        !          3382:                    fragP->fr_var += 2;
        !          3383:                }
        !          3384:            }
        !          3385:            else {
        !          3386:                /* Symbol is still undefined.  Make it long */
        !          3387:                fix_new(fragP,
        !          3388:                        fragP->fr_fix,
        !          3389:                        4,
        !          3390:                        fragP->fr_symbol,
        !          3391:                        0,
        !          3392:                        fragP->fr_offset + 4,
        !          3393:                        1,
        !          3394:                        1,
        !          3395:                        0);
        !          3396:                fragP->fr_fix += 4;
        !          3397:                fragP->fr_opcode[1] |= 0x40;
        !          3398:                frag_wane(fragP);
        !          3399:                break;
        !          3400:            }
        !          3401:            break;
        !          3402: 
        !          3403:        case TAB(PCREL, SZ_UNDEF):
        !          3404:            if(fragP->fr_symbol->sy_nlist.n_sect == nsect){
        !          3405:                /*
        !          3406:                 * The NeXT linker has the ability to scatter blocks of
        !          3407:                 * sections between labels.  This requires that brances to
        !          3408:                 * labels that survive to the link phase must be able to
        !          3409:                 * be relocated.
        !          3410:                 */
        !          3411:                if(fragP->fr_symbol->sy_name[0] != 'L' || flagseen ['L']) {
        !          3412:                    /*
        !          3413:                     * The thing to do here is force it to ABSOLUTE LONG, since
        !          3414:                     * PCREL is really trying to shorten an ABSOLUTE address
        !          3415:                     * anyway.
        !          3416:                     */
        !          3417:                    if((fragP->fr_opcode[1] & 0x3F) != 0x3A)
        !          3418:                        as_bad("Internal error (long PC-relative operand) for "
        !          3419:                               "insn 0x%04x at 0x%lx", fragP->fr_opcode[0],
        !          3420:                               fragP->fr_address);
        !          3421:                    fragP->fr_opcode[1] &= ~0x3F;
        !          3422:                    fragP->fr_opcode[1] |= 0x39;        /* Mode 7.1 */
        !          3423:                    fix_new(fragP,
        !          3424:                            fragP->fr_fix,
        !          3425:                            4,
        !          3426:                            fragP->fr_symbol,
        !          3427:                            0,
        !          3428:                            fragP->fr_offset,
        !          3429:                            0,
        !          3430:                            0,
        !          3431:                            0);
        !          3432:                    fragP->fr_fix += 4;
        !          3433:                    frag_wane(fragP);
        !          3434:                }
        !          3435:                else{
        !          3436:                    fragP->fr_subtype = TAB(PCREL, SHORT);
        !          3437:                    fragP->fr_var += 2;
        !          3438:                }
        !          3439:            }
        !          3440:            else {
        !          3441:                /* Symbol is still undefined.  Make it long */
        !          3442:                if((fragP->fr_opcode[1] & 0x3F) != 0x3A)
        !          3443:                    as_bad("Internal error (long PC-relative operand) for "
        !          3444:                           "insn 0x%04x at 0x%lx", fragP->fr_opcode[0],
        !          3445:                           fragP->fr_address);
        !          3446:                fragP->fr_opcode[1] &= ~0x3F;
        !          3447:                fragP->fr_opcode[1] |= 0x39;    /* Mode 7.1 */
        !          3448:                fix_new(fragP,
        !          3449:                        fragP->fr_fix,
        !          3450:                        4,
        !          3451:                        fragP->fr_symbol,
        !          3452:                        0,
        !          3453:                        fragP->fr_offset,
        !          3454:                        1,
        !          3455:                        1,
        !          3456:                        0);
        !          3457:                fragP->fr_fix += 4;
        !          3458:                frag_wane(fragP);
        !          3459:                break;
        !          3460:            }
        !          3461:            break;
        !          3462: 
        !          3463:        default:
        !          3464:            break;
        !          3465:        }
        !          3466: 
        !          3467:        /*
        !          3468:         * Now that SZ_UNDEF are taken care of, check others
        !          3469:         */
        !          3470:        switch(fragP->fr_subtype) {
        !          3471:        case TAB(BCC68000, BYTE):
        !          3472:        case TAB(BRANCH, BYTE):
        !          3473:            /*
        !          3474:             * We can't do a short jump to the next instruction,
        !          3475:             * so we force word mode.
        !          3476:             */
        !          3477:            if(fragP->fr_symbol != NULL &&
        !          3478:               fragP->fr_symbol->sy_value == 0 &&
        !          3479:               fragP->fr_symbol->sy_frag == fragP->fr_next) {
        !          3480:                fragP->fr_subtype = TAB(TABTYPE(fragP->fr_subtype), SHORT);
        !          3481:                fragP->fr_var += 2;
        !          3482:            }
        !          3483:            break;
        !          3484:        default:
        !          3485:            break;
        !          3486:        }
        !          3487:        return(fragP->fr_var + fragP->fr_fix - old_fix);
        !          3488: }
        !          3489: 
        !          3490: /*
        !          3491:  * *fragP has been relaxed to its final size, and now needs to have
        !          3492:  * the bytes inside it modified to conform to the new size.  There is UGLY
        !          3493:  * MAGIC here interms of changing the addressing mode of some instructions
        !          3494:  * and using other instructions in place of the original in the case of the
        !          3495:  * 68000 and 68010 where long pc-relative forms don't exist.
        !          3496:  */
        !          3497: void
        !          3498: md_convert_frag(
        !          3499: fragS *fragP)
        !          3500: {
        !          3501:     long disp;
        !          3502:     long ext;
        !          3503:     char *buffer_address;
        !          3504:     int object_address;
        !          3505: 
        !          3506:        ext = 0;
        !          3507: 
        !          3508:        /* Address in gas core of the place to store the displacement.  */
        !          3509:        buffer_address = fragP->fr_fix + fragP->fr_literal;
        !          3510: 
        !          3511:        /* Address in object code of the displacement.  */
        !          3512:        object_address = fragP->fr_fix + fragP->fr_address;
        !          3513: 
        !          3514:        know(fragP->fr_symbol);
        !          3515: 
        !          3516:        /* The displacement of the address, from current location.  */
        !          3517:        disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address;
        !          3518: 
        !          3519:        switch(fragP->fr_subtype){
        !          3520:        case TAB(BCC68000, BYTE):
        !          3521:        case TAB(BRANCH, BYTE):
        !          3522:            know(issbyte(disp));
        !          3523:            if(disp == 0){
        !          3524:                /* Replace this with a nop. */
        !          3525:                fragP->fr_opcode[0] = 0x4e;
        !          3526:                fragP->fr_opcode[1] = 0x71;
        !          3527:            }
        !          3528:            else{
        !          3529:                fragP->fr_opcode[1] = disp;
        !          3530:            }
        !          3531:            ext = 0;
        !          3532:            break;
        !          3533: 
        !          3534:        case TAB(DBCC, SHORT):
        !          3535:            know(issword(disp));
        !          3536:            ext=2;
        !          3537:            break;
        !          3538: 
        !          3539:        case TAB(BCC68000, SHORT):
        !          3540:        case TAB(BRANCH, SHORT):
        !          3541:            know(issword(disp));
        !          3542:            fragP->fr_opcode[1] = 0x00;
        !          3543:            ext = 2;
        !          3544:            break;
        !          3545: 
        !          3546:        case TAB(BRANCH,LONG):
        !          3547:            if(flagseen['m']){
        !          3548:                if(fragP->fr_opcode[0] == 0x61){
        !          3549:                    fragP->fr_opcode[0] = 0x4E;
        !          3550:                    fragP->fr_opcode[1] = 0xB9; /* JBSR with ABSL LONG offset */
        !          3551:                    fix_new(fragP,
        !          3552:                            fragP->fr_fix,
        !          3553:                            4,
        !          3554:                            fragP->fr_symbol,
        !          3555:                            0,
        !          3556:                            fragP->fr_offset,
        !          3557:                            0,
        !          3558:                            0,
        !          3559:                            0);
        !          3560:                    fragP->fr_fix += 4;
        !          3561:                    ext = 0;
        !          3562:                }
        !          3563:                else if(fragP->fr_opcode[0] == 0x60){
        !          3564:                    fragP->fr_opcode[0]= 0x4E;
        !          3565:                    fragP->fr_opcode[1]= 0xF9; /* JMP  with ABSL LONG offset */
        !          3566:                  fix_new(fragP,
        !          3567:                          fragP->fr_fix,
        !          3568:                          4,
        !          3569:                          fragP->fr_symbol,
        !          3570:                          0,
        !          3571:                          fragP->fr_offset,
        !          3572:                          0,
        !          3573:                          0,
        !          3574:                          0);
        !          3575:                  fragP->fr_fix += 4;
        !          3576:                  ext = 0;
        !          3577:                }
        !          3578:                else{
        !          3579:                    as_bad("Long branch offset not supported.");
        !          3580:                }
        !          3581:            }
        !          3582:            else{
        !          3583:                fragP->fr_opcode[1] = 0xff;
        !          3584:                ext = 4;
        !          3585:            }
        !          3586:            break;
        !          3587: 
        !          3588:        case TAB(BCC68000, LONG):
        !          3589:            /*
        !          3590:             * Only Bcc 68000 instructions can come here.
        !          3591:             * Change bcc into b!cc/jmp absl long.
        !          3592:             */
        !          3593:            fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
        !          3594:            fragP->fr_opcode[1] = 0x6;   /* branch offset = 6 */
        !          3595:            fragP->fr_opcode[2] = 0x4e;  /* put in jmp long (0x4ef9) */ 
        !          3596:            fragP->fr_opcode[3] = 0xf9;  
        !          3597:            fragP->fr_fix += 2;          /* account for jmp instruction */
        !          3598:            fix_new(fragP,
        !          3599:                    fragP->fr_fix,
        !          3600:                    4,
        !          3601:                    fragP->fr_symbol,
        !          3602:                    0,
        !          3603:                    fragP->fr_offset,
        !          3604:                    0,
        !          3605:                    0,
        !          3606:                    0);
        !          3607:            fragP->fr_fix += 4; /* account for jmp instruction's displacement */
        !          3608:            ext = 0;
        !          3609:            break;
        !          3610: 
        !          3611:        case TAB(DBCC, LONG):
        !          3612:            /*
        !          3613:             * Only DBcc 68000 instructions can come here.
        !          3614:             * Change dbcc into dbcc/jmp absl long.
        !          3615:             */
        !          3616:            fragP->fr_opcode[2] = 0x00;  /* branch offset = 4 */
        !          3617:            fragP->fr_opcode[3] = 0x04;  
        !          3618:            fragP->fr_opcode[4] = 0x60;  /* put in bra pc+6 */ 
        !          3619:            fragP->fr_opcode[5] = 0x06;  
        !          3620:            fragP->fr_opcode[6] = 0x4e;  /* put in jmp long (0x4ef9) */ 
        !          3621:            fragP->fr_opcode[7] = 0xf9;  
        !          3622:            fragP->fr_fix += 6;      /* account for bra/jmp instructions */
        !          3623:            fix_new(fragP,
        !          3624:                    fragP->fr_fix,
        !          3625:                    4,
        !          3626:                    fragP->fr_symbol,
        !          3627:                    0, 
        !          3628:                    fragP->fr_offset,
        !          3629:                    0,
        !          3630:                    0,
        !          3631:                    0);
        !          3632:            fragP->fr_fix += 4; /* account for jmp instruction's displacement */
        !          3633:            ext = 0;
        !          3634:            break;
        !          3635: 
        !          3636:        case TAB(FBRANCH, SHORT):
        !          3637:            know((fragP->fr_opcode[1] & 0x40) == 0);
        !          3638:            ext = 2;
        !          3639:            break;
        !          3640: 
        !          3641:        case TAB(FBRANCH, LONG):
        !          3642:            fragP->fr_opcode[1] |= 0x40;        /* Turn on LONG bit */
        !          3643:            ext = 4;
        !          3644:            break;
        !          3645: 
        !          3646:        case TAB(PCREL,SHORT):
        !          3647:            ext = 2;
        !          3648:            break;
        !          3649: 
        !          3650:        case TAB(PCREL,LONG):
        !          3651:            /*
        !          3652:             * The thing to do here is force it to ABSOLUTE LONG, since
        !          3653:             * PCREL is really trying to shorten an ABSOLUTE address anyway.
        !          3654:             */
        !          3655:            if((fragP->fr_opcode[1] & 0x3F) != 0x3A)
        !          3656:                as_bad("Internal error (long PC-relative operand) for insn "
        !          3657:                       "0x%04x at 0x%lx", fragP->fr_opcode[0],
        !          3658:                       fragP->fr_address);
        !          3659:            fragP->fr_opcode[1] &= ~0x3F;
        !          3660:            fragP->fr_opcode[1] |= 0x39;        /* Mode 7.1 */
        !          3661:            fix_new(fragP,
        !          3662:                    fragP->fr_fix,
        !          3663:                    4,
        !          3664:                    fragP->fr_symbol,
        !          3665:                    0,
        !          3666:                    fragP->fr_offset,
        !          3667:                    0,
        !          3668:                    0,
        !          3669:                    0);
        !          3670:            fragP->fr_fix += 4; /* account for the instruction's displacement */
        !          3671:            ext = 0;
        !          3672:            break;
        !          3673: 
        !          3674:        default:
        !          3675:            break;
        !          3676:        }
        !          3677: 
        !          3678:        if(ext != 0){
        !          3679:            md_number_to_chars(buffer_address, (long)disp, (int)ext);
        !          3680:            fragP->fr_fix += ext;
        !          3681:        }
        !          3682: }
        !          3683: 
        !          3684: /* Different values of OK tell what its OK to return.  Things that aren't OK are an error (what a shock, no?)
        !          3685: 
        !          3686:        0:  Everything is OK
        !          3687:        10:  Absolute 1:8       only
        !          3688:        20:  Absolute 0:7       only
        !          3689:        30:  absolute 0:15      only
        !          3690:        40:  Absolute 0:31      only
        !          3691:        50:  absolute 0:127     only
        !          3692:        55:  absolute -64:63    only
        !          3693:        60:  absolute -128:127  only
        !          3694:        70:  absolute 0:4095    only
        !          3695:        80:  No bignums
        !          3696: 
        !          3697: */
        !          3698: static
        !          3699: int
        !          3700: get_num(
        !          3701: struct m68k_exp *exp,
        !          3702: int ok)
        !          3703: {
        !          3704: #ifdef TEST2
        !          3705:        long    l = 0;
        !          3706: 
        !          3707:        if(!exp->e_beg)
        !          3708:                return 0;
        !          3709:        if(*exp->e_beg=='0') {
        !          3710:                if(exp->e_beg[1]=='x')
        !          3711:                        sscanf(exp->e_beg+2,"%x",&l);
        !          3712:                else
        !          3713:                        sscanf(exp->e_beg+1,"%O",&l);
        !          3714:                return l;
        !          3715:        }
        !          3716:        return atol(exp->e_beg);
        !          3717: #else /* !defined(TEST2) */
        !          3718:        char    *save_in;
        !          3719:        char    c_save;
        !          3720: 
        !          3721:        if(!exp) {
        !          3722:                /* Can't do anything */
        !          3723:                return 0;
        !          3724:        }
        !          3725:        if(!exp->e_beg || !exp->e_end) {
        !          3726:                seg(exp)=SEG_ABSOLUTE;
        !          3727:                adds(exp)=0;
        !          3728:                subs(exp)=0;
        !          3729:                offs(exp)= (ok==10) ? 1 : 0;
        !          3730:                as_warn("Null expression defaults to %ld",offs(exp));
        !          3731:                return 0;
        !          3732:        }
        !          3733: 
        !          3734:        exp->e_siz=0;
        !          3735:        if(/* ok!=80 && */exp->e_end[-1]==':' && (exp->e_end-exp->e_beg)>=2) {
        !          3736:                switch(exp->e_end[0]) {
        !          3737:                case 's':
        !          3738:                case 'b':
        !          3739:                        exp->e_siz=1;
        !          3740:                        break;
        !          3741:                case 'w':
        !          3742:                        exp->e_siz=2;
        !          3743:                        break;
        !          3744:                case 'l':
        !          3745:                        exp->e_siz=3;
        !          3746:                        break;
        !          3747:                default:
        !          3748:                        as_bad("Unknown size for expression \"%c\"",exp->e_end[0]);
        !          3749:                }
        !          3750:                exp->e_end-=2;
        !          3751:        }
        !          3752:        c_save=exp->e_end[1];
        !          3753:        exp->e_end[1]='\0';
        !          3754:        save_in=input_line_pointer;
        !          3755:        input_line_pointer=exp->e_beg;
        !          3756: #ifdef NeXT    /* feature to try to make expressions absolute */
        !          3757:        (void) expression (&(exp->e_exp));
        !          3758:        /* DJA -- we will try to make an absolute number here */
        !          3759:        switch(try_to_make_absolute(&(exp->e_exp))) {
        !          3760: #else /* !defined(NeXT) */
        !          3761:        switch(expression(&(exp->e_exp))) {
        !          3762: #endif /* NeXT */
        !          3763:        case SEG_NONE:
        !          3764:                /* Do the same thing the VAX asm does */
        !          3765:                seg(exp)=SEG_ABSOLUTE;
        !          3766:                adds(exp)=0;
        !          3767:                subs(exp)=0;
        !          3768:                offs(exp)=0;
        !          3769:                if(ok==10) {
        !          3770:                        as_warn("expression out of range: defaulting to 1");
        !          3771:                        offs(exp)=1;
        !          3772:                }
        !          3773:                break;
        !          3774:        case SEG_ABSOLUTE:
        !          3775:                switch(ok) {
        !          3776:                case 10:
        !          3777:                        if(offs(exp)<1 || offs(exp)>8) {
        !          3778:                                as_warn("expression out of range: defaulting to 1");
        !          3779:                                offs(exp)=1;
        !          3780:                        }
        !          3781:                        break;
        !          3782:                case 20:
        !          3783:                        if(offs(exp)<0 || offs(exp)>7)
        !          3784:                                goto outrange;
        !          3785:                        break;
        !          3786:                case 30:
        !          3787:                        if(offs(exp)<0 || offs(exp)>15)
        !          3788:                                goto outrange;
        !          3789:                        break;
        !          3790:                case 40:
        !          3791:                        if(offs(exp)<0 || offs(exp)>32)
        !          3792:                                goto outrange;
        !          3793:                        break;
        !          3794:                case 50:
        !          3795:                        if(offs(exp)<0 || offs(exp)>127)
        !          3796:                                goto outrange;
        !          3797:                        break;
        !          3798:                case 55:
        !          3799:                        if(offs(exp)<-64 || offs(exp)>63)
        !          3800:                                goto outrange;
        !          3801:                        break;
        !          3802:                case 60:
        !          3803:                        if(offs(exp)<-128 || offs(exp)>127)
        !          3804:                                goto outrange;
        !          3805:                        break;
        !          3806:                case 70:
        !          3807:                        if(offs(exp)<0 || offs(exp)>4095) {
        !          3808:                        outrange:
        !          3809:                                as_warn("expression out of range: defaulting to 0");
        !          3810:                                offs(exp)=0;
        !          3811:                        }
        !          3812:                        break;
        !          3813:                default:
        !          3814:                        break;
        !          3815:                }
        !          3816:                break;
        !          3817:        case SEG_SECT:
        !          3818:        case SEG_UNKNOWN:
        !          3819:        case SEG_DIFFSECT:
        !          3820:                if(ok>=10 && ok<=70) {
        !          3821:                        seg(exp)=SEG_ABSOLUTE;
        !          3822:                        adds(exp)=0;
        !          3823:                        subs(exp)=0;
        !          3824:                        offs(exp)= (ok==10) ? 1 : 0;
        !          3825:                        as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
        !          3826:                }
        !          3827:                break;
        !          3828:        case SEG_BIG:
        !          3829: #ifndef NeXT   /* fix for bug #8331 */ /* This hack is already done by expr */
        !          3830:                if(ok==80 && offs(exp)<0) {     /* HACK! Turn it into a long */
        !          3831:                        LITTLENUM_TYPE words[6];
        !          3832: 
        !          3833:                        gen_to_words(words,2,8L);/* These numbers are magic! */
        !          3834:                        seg(exp)=SEG_ABSOLUTE;
        !          3835:                        adds(exp)=0;
        !          3836:                        subs(exp)=0;
        !          3837:                        offs(exp)=words[1]|(words[0]<<16);
        !          3838:                } else if(ok!=0) {
        !          3839: #else /* defined(NeXT) */
        !          3840:                if(ok!=0) {
        !          3841: #endif /* NeXT */
        !          3842:                        seg(exp)=SEG_ABSOLUTE;
        !          3843:                        adds(exp)=0;
        !          3844:                        subs(exp)=0;
        !          3845:                        offs(exp)= (ok==10) ? 1 : 0;
        !          3846:                        as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
        !          3847:                }
        !          3848:                break;
        !          3849:        default:
        !          3850:                abort();
        !          3851:        }
        !          3852:        if(input_line_pointer!=exp->e_end+1)
        !          3853:                as_bad("Ignoring junk after expression");
        !          3854:        exp->e_end[1]=c_save;
        !          3855:        input_line_pointer=save_in;
        !          3856:        if(exp->e_siz) {
        !          3857:                switch(exp->e_siz) {
        !          3858:                case 1:
        !          3859:                        if(!isbyte(offs(exp)))
        !          3860:                                as_warn("expression doesn't fit in BYTE");
        !          3861:                        break;
        !          3862:                case 2:
        !          3863:                        if(!isword(offs(exp)))
        !          3864:                                as_warn("expression doesn't fit in WORD");
        !          3865:                        break;
        !          3866:                }
        !          3867:        }
        !          3868:        return offs(exp);
        !          3869: 
        !          3870: #endif /* !defined(TEST2) */
        !          3871: }
        !          3872: 
        !          3873: /* These are the back-ends for the various machine dependent pseudo-ops.  */
        !          3874: void demand_empty_rest_of_line();      /* Hate those extra verbose names */
        !          3875: 
        !          3876: static
        !          3877: void
        !          3878: s_even(
        !          3879: int value)
        !          3880: {
        !          3881:        register int temp;
        !          3882:        register long int temp_fill;
        !          3883: 
        !          3884:        temp = 1;               /* JF should be 2? */
        !          3885:        temp_fill = get_absolute_expression ();
        !          3886:        frag_align(temp, (int)temp_fill);
        !          3887:        /*
        !          3888:         * If this alignment is larger than any previous alignment then this
        !          3889:         * becomes the section's alignment.
        !          3890:         */
        !          3891:        if(frchain_now->frch_section.align < temp)
        !          3892:            frchain_now->frch_section.align = temp;
        !          3893:        demand_empty_rest_of_line();
        !          3894: }
        !          3895: 
        !          3896: static
        !          3897: void
        !          3898: s_proc(
        !          3899: int value)
        !          3900: {
        !          3901:        demand_empty_rest_of_line();
        !          3902: }
        !          3903: 
        !          3904: /* s_space is defined in read.c .skip is simply an alias to it. */
        !          3905: 
        !          3906: int
        !          3907: md_parse_option(
        !          3908: char **argP,
        !          3909: int *cntP,
        !          3910: char ***vecP)
        !          3911: {
        !          3912:        switch(**argP) {
        !          3913:        case 'l':       /* -l means keep external to 32 bit offset
        !          3914:                           rather than 16 bit one */
        !          3915:                break;
        !          3916: 
        !          3917:        case 'm':
        !          3918:                /* Gas simply ignores this option! */
        !          3919:                (*argP)++;
        !          3920:                if(**argP=='c')
        !          3921:                        (*argP)++;
        !          3922:                if(!strcmp(*argP,"68000"))
        !          3923:                        flagseen['m']=2;
        !          3924:                else if(!strcmp(*argP,"68010")) {
        !          3925:                        flagseen['m']=1;
        !          3926:                } else if(!strcmp(*argP,"68020"))
        !          3927:                        flagseen['m']=0;
        !          3928:                else
        !          3929:                        as_warn("Unknown -m option ignored");
        !          3930:                while(**argP)
        !          3931:                        (*argP)++;
        !          3932:                break;
        !          3933: 
        !          3934:        default:
        !          3935:                return 0;
        !          3936:        }
        !          3937:        return 1;
        !          3938: }
        !          3939: 
        !          3940: 
        !          3941: #ifdef TEST2
        !          3942: 
        !          3943: /* TEST2:  Test md_assemble() */
        !          3944: 
        !          3945: static
        !          3946: int
        !          3947: is_label(
        !          3948: char *str)
        !          3949: {
        !          3950:        while(*str == ' ')
        !          3951:            str++;
        !          3952:        while(*str && *str != ' ')
        !          3953:            str++;
        !          3954:        if(str[-1] == ':' || str[1] == '=')
        !          3955:            return(1);
        !          3956:        return(0);
        !          3957: }
        !          3958: 
        !          3959: void
        !          3960: main(
        !          3961: int argc,
        !          3962: char *argv[],
        !          3963: char *envp[])
        !          3964: {
        !          3965:     char buf[120];
        !          3966:     char *cp;
        !          3967:     int n;
        !          3968: 
        !          3969:        m68_ip_begin();
        !          3970:        for(;;){
        !          3971:            if(!gets(buf) || !*buf)
        !          3972:                break;
        !          3973:            if(buf[0] == '|' || buf[1] == '.')
        !          3974:                continue;
        !          3975:            for(cp = buf; *cp; cp++)
        !          3976:                if(*cp == '\t')
        !          3977:                    *cp = ' ';
        !          3978:            if(is_label(buf))
        !          3979:                continue;
        !          3980:            memset(&the_ins, '\0', sizeof(the_ins));
        !          3981:            m68_ip(buf);
        !          3982:            if(the_ins.error){
        !          3983:                printf("Error %s in %s\n", the_ins.error, buf);
        !          3984:            }
        !          3985:            else{
        !          3986:                printf("Opcode(%d.%s): ", the_ins.numo, the_ins.args);
        !          3987:                for(n = 0; n < the_ins.numo; n++)
        !          3988:                    printf(" 0x%x", the_ins.opcode[n] & 0xffff);
        !          3989:                printf("    ");
        !          3990:                print_the_insn(&the_ins.opcode[0], stdout);
        !          3991:                (void)putchar('\n');
        !          3992:            }
        !          3993:            for(n = 0; n < strlen(the_ins.args) / 2; n++){
        !          3994:                if(the_ins.operands[n].error){
        !          3995:                    printf("op%d Error %s in %s\n",
        !          3996:                           n, the_ins.operands[n].error, buf);
        !          3997:                    continue;
        !          3998:                }
        !          3999:                printf("mode %d, reg %d, ",
        !          4000:                       the_ins.operands[n].mode, the_ins.operands[n].reg);
        !          4001:                if(the_ins.operands[n].con1)
        !          4002:                    printf("con1: '%.*s', ",
        !          4003:                           1 + the_ins.operands[n].con1->e_end -
        !          4004:                               the_ins.operands[n].con1->e_beg,
        !          4005:                           the_ins.operands[n].con1->e_beg);
        !          4006:                printf("ireg %d, isiz %d, imul %d, ",
        !          4007:                       the_ins.operands[n].ireg,
        !          4008:                       the_ins.operands[n].isiz,
        !          4009:                       the_ins.operands[n].imul);
        !          4010:                if(the_ins.operands[n].con2)
        !          4011:                    printf("con2: '%.*s',",
        !          4012:                           1 + the_ins.operands[n].con2->e_end -
        !          4013:                               the_ins.operands[n].con2->e_beg,
        !          4014:                           the_ins.operands[n].con2->e_beg);
        !          4015:                (void)putchar('\n');
        !          4016:            }
        !          4017:        }
        !          4018:        m68_ip_end();
        !          4019: }
        !          4020: #endif /* TEST2 */

unix.superglobalmegacorp.com

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