Annotation of GNUtools/cctools/as/m68k.c, revision 1.1.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.