Back to index

cell-binutils  2.17cvs20070401
tc-z8k.c
Go to the documentation of this file.
00001 /* tc-z8k.c -- Assemble code for the Zilog Z800n
00002    Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003,
00003    2005, 2006 Free Software Foundation, Inc.
00004 
00005    This file is part of GAS, the GNU Assembler.
00006 
00007    GAS is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2, or (at your option)
00010    any later version.
00011 
00012    GAS is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with GAS; see the file COPYING.  If not, write to the Free
00019    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00020    02110-1301, USA.  */
00021 
00022 /* Written By Steve Chamberlain <sac@cygnus.com>.  */
00023 
00024 #include "as.h"
00025 #include "safe-ctype.h"
00026 #define DEFINE_TABLE
00027 #include "opcodes/z8k-opc.h"
00028 
00029 const char comment_chars[] = "!";
00030 const char line_comment_chars[] = "#";
00031 const char line_separator_chars[] = ";";
00032 
00033 extern int machine;
00034 extern int coff_flags;
00035 int segmented_mode;
00036 
00037 /* This is non-zero if target was set from the command line.  */
00038 static int z8k_target_from_cmdline;
00039 
00040 static void
00041 s_segm (int segm)
00042 {
00043   if (segm)
00044     {
00045       segmented_mode = 1;
00046       bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8001);
00047     }
00048   else
00049     {
00050       segmented_mode = 0;
00051       bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8002);
00052     }
00053 }
00054 
00055 static void
00056 even (int ignore ATTRIBUTE_UNUSED)
00057 {
00058   frag_align (1, 0, 0);
00059   record_alignment (now_seg, 1);
00060 }
00061 
00062 static int
00063 tohex (int c)
00064 {
00065   if (ISDIGIT (c))
00066     return c - '0';
00067   if (ISLOWER (c))
00068     return c - 'a' + 10;
00069   return c - 'A' + 10;
00070 }
00071 
00072 static void
00073 sval (int ignore ATTRIBUTE_UNUSED)
00074 {
00075   SKIP_WHITESPACE ();
00076   if (*input_line_pointer == '\'')
00077     {
00078       int c;
00079       input_line_pointer++;
00080       c = *input_line_pointer++;
00081       while (c != '\'')
00082        {
00083          if (c == '%')
00084            {
00085              c = (tohex (input_line_pointer[0]) << 4)
00086               | tohex (input_line_pointer[1]);
00087              input_line_pointer += 2;
00088            }
00089          FRAG_APPEND_1_CHAR (c);
00090          c = *input_line_pointer++;
00091        }
00092       demand_empty_rest_of_line ();
00093     }
00094 }
00095 
00096 /* This table describes all the machine specific pseudo-ops the assembler
00097    has to support.  The fields are:
00098    pseudo-op name without dot
00099    function to call to execute this pseudo-op
00100    Integer arg to pass to the function
00101    */
00102 
00103 const pseudo_typeS md_pseudo_table[] = {
00104   {"int"    , cons            , 2},
00105   {"data.b" , cons            , 1},
00106   {"data.w" , cons            , 2},
00107   {"data.l" , cons            , 4},
00108   {"form"   , listing_psize   , 0},
00109   {"heading", listing_title   , 0},
00110   {"import" , s_ignore        , 0},
00111   {"page"   , listing_eject   , 0},
00112   {"program", s_ignore        , 0},
00113   {"z8001"  , s_segm          , 1},
00114   {"z8002"  , s_segm          , 0},
00115 
00116   {"segm"   , s_segm          , 1},
00117   {"unsegm" , s_segm          , 0},
00118   {"unseg"  , s_segm          , 0},
00119   {"name"   , s_app_file      , 0},
00120   {"global" , s_globl         , 0},
00121   {"wval"   , cons            , 2},
00122   {"lval"   , cons            , 4},
00123   {"bval"   , cons            , 1},
00124   {"sval"   , sval            , 0},
00125   {"rsect"  , obj_coff_section, 0},
00126   {"sect"   , obj_coff_section, 0},
00127   {"block"  , s_space         , 0},
00128   {"even"   , even            , 0},
00129   {0        , 0               , 0}
00130 };
00131 
00132 const char EXP_CHARS[] = "eE";
00133 
00134 /* Chars that mean this number is a floating point constant.
00135    As in 0f12.456
00136    or    0d1.2345e12  */
00137 const char FLT_CHARS[] = "rRsSfFdDxXpP";
00138 
00139 /* Opcode mnemonics.  */
00140 static struct hash_control *opcode_hash_control;
00141 
00142 void
00143 md_begin (void)
00144 {
00145   const opcode_entry_type *opcode;
00146   int idx = -1;
00147 
00148   opcode_hash_control = hash_new ();
00149 
00150   for (opcode = z8k_table; opcode->name; opcode++)
00151     {
00152       /* Only enter unique codes into the table.  */
00153       if (idx != opcode->idx)
00154        hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
00155       idx = opcode->idx;
00156     }
00157 
00158   /* Default to z8002.  */
00159   if (! z8k_target_from_cmdline)
00160     s_segm (0);
00161 
00162   /* Insert the pseudo ops, too.  */
00163   for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
00164     {
00165       opcode_entry_type *fake_opcode;
00166       fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
00167       fake_opcode->name = md_pseudo_table[idx].poc_name;
00168       fake_opcode->func = (void *) (md_pseudo_table + idx);
00169       fake_opcode->opcode = 250;
00170       hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
00171     }
00172 }
00173 
00174 typedef struct z8k_op {
00175   /* CLASS_REG_xxx.  */
00176   int regsize;
00177 
00178   /* 0 .. 15.  */
00179   unsigned int reg;
00180 
00181   int mode;
00182 
00183   /* Any other register associated with the mode.  */
00184   unsigned int x_reg;
00185 
00186   /* Any expression.  */
00187   expressionS exp;
00188 } op_type;
00189 
00190 static expressionS *da_operand;
00191 static expressionS *imm_operand;
00192 
00193 static int reg[16];
00194 static int the_cc;
00195 static int the_ctrl;
00196 static int the_flags;
00197 static int the_interrupt;
00198 
00199 /* Determine register number.  src points to the ascii number
00200    (after "rl", "rh", "r", "rr", or "rq").  If a character
00201    outside the set of {0,',',')','('} follows the number,
00202    return NULL to indicate that it's not a valid register
00203    number.  */
00204 
00205 static char *
00206 whatreg (unsigned int *reg, char *src)
00207 {
00208   unsigned int new_reg;
00209 
00210   /* src[0] is already known to be a digit.  */
00211   if (ISDIGIT (src[1]))
00212     {
00213       new_reg = (src[0] - '0') * 10 + src[1] - '0';
00214       src += 2;
00215     }
00216   else
00217     {
00218       new_reg = (src[0] - '0');
00219       src += 1;
00220     }
00221 
00222   if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')')
00223     return NULL;
00224 
00225   *reg = new_reg;
00226   return src;
00227 }
00228 
00229 /* Parse operands
00230 
00231    rh0-rh7, rl0-rl7
00232    r0-r15
00233    rr0-rr14
00234    rq0--rq12
00235    WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
00236    r0l,r0h,..r7l,r7h
00237    @WREG
00238    @WREG+
00239    @-WREG
00240    #const
00241 */
00242 
00243 /* Try to parse a reg name.  Return a pointer to the first character
00244    in SRC after the reg name.  */
00245 
00246 static char *
00247 parse_reg (char *src, int *mode, unsigned int *reg)
00248 {
00249   char *res = NULL;
00250   char regno;
00251 
00252   /* Check for stack pointer "sp" alias.  */
00253   if ((src[0] == 's' || src[0] == 'S')
00254       && (src[1] == 'p' || src[1] == 'P')
00255       && (src[2] == 0 || src[2] == ','))
00256     {
00257       if (segmented_mode)
00258        {
00259          *mode = CLASS_REG_LONG;
00260          *reg = 14;
00261        }
00262       else
00263        {
00264          *mode = CLASS_REG_WORD;
00265          *reg = 15;
00266        }
00267       return src + 2;
00268     }
00269 
00270   if (src[0] == 'r' || src[0] == 'R')
00271     {
00272       if (src[1] == 'r' || src[1] == 'R')
00273        {
00274          if (src[2] < '0' || src[2] > '9')
00275            return NULL;     /* Assume no register name but a label starting with 'rr'.  */
00276          *mode = CLASS_REG_LONG;
00277          res = whatreg (reg, src + 2);
00278          if (res == NULL)
00279            return NULL;     /* Not a valid register name.  */
00280          regno = *reg;
00281          if (regno > 14)
00282            as_bad (_("register rr%d out of range"), regno);
00283          if (regno & 1)
00284            as_bad (_("register rr%d does not exist"), regno);
00285        }
00286       else if (src[1] == 'h' || src[1] == 'H')
00287        {
00288          if (src[2] < '0' || src[2] > '9')
00289            return NULL;     /* Assume no register name but a label starting with 'rh'.  */
00290          *mode = CLASS_REG_BYTE;
00291          res = whatreg (reg, src + 2);
00292          if (res == NULL)
00293            return NULL;     /* Not a valid register name.  */
00294          regno = *reg;
00295          if (regno > 7)
00296            as_bad (_("register rh%d out of range"), regno);
00297        }
00298       else if (src[1] == 'l' || src[1] == 'L')
00299        {
00300          if (src[2] < '0' || src[2] > '9')
00301            return NULL;     /* Assume no register name but a label starting with 'rl'.  */
00302          *mode = CLASS_REG_BYTE;
00303          res = whatreg (reg, src + 2);
00304          if (res == NULL)
00305            return NULL;     /* Not a valid register name.  */
00306          regno = *reg;
00307          if (regno > 7)
00308            as_bad (_("register rl%d out of range"), regno);
00309          *reg += 8;
00310        }
00311       else if (src[1] == 'q' || src[1] == 'Q')
00312        {
00313          if (src[2] < '0' || src[2] > '9')
00314            return NULL;     /* Assume no register name but a label starting with 'rq'.  */
00315          *mode = CLASS_REG_QUAD;
00316          res = whatreg (reg, src + 2);
00317          if (res == NULL)
00318            return NULL;     /* Not a valid register name.  */
00319          regno = *reg;
00320          if (regno > 12)
00321            as_bad (_("register rq%d out of range"), regno);
00322          if (regno & 3)
00323            as_bad (_("register rq%d does not exist"), regno);
00324        }
00325       else
00326        {
00327          if (src[1] < '0' || src[1] > '9')
00328            return NULL;     /* Assume no register name but a label starting with 'r'.  */
00329          *mode = CLASS_REG_WORD;
00330          res = whatreg (reg, src + 1);
00331          if (res == NULL)
00332            return NULL;     /* Not a valid register name.  */
00333          regno = *reg;
00334          if (regno > 15)
00335            as_bad (_("register r%d out of range"), regno);
00336        }
00337     }
00338   return res;
00339 }
00340 
00341 static char *
00342 parse_exp (char *s, expressionS *op)
00343 {
00344   char *save = input_line_pointer;
00345   char *new;
00346 
00347   input_line_pointer = s;
00348   expression (op);
00349   if (op->X_op == O_absent)
00350     as_bad (_("missing operand"));
00351   new = input_line_pointer;
00352   input_line_pointer = save;
00353   return new;
00354 }
00355 
00356 /* The many forms of operand:
00357 
00358    <rb>
00359    <r>
00360    <rr>
00361    <rq>
00362    @r
00363    #exp
00364    exp
00365    exp(r)
00366    r(#exp)
00367    r(r)
00368    */
00369 
00370 static char *
00371 checkfor (char *ptr, char what)
00372 {
00373   if (*ptr == what)
00374     ptr++;
00375   else
00376     as_bad (_("expected %c"), what);
00377 
00378   return ptr;
00379 }
00380 
00381 /* Make sure the mode supplied is the size of a word.  */
00382 
00383 static void
00384 regword (int mode, char *string)
00385 {
00386   int ok;
00387 
00388   ok = CLASS_REG_WORD;
00389   if (ok != mode)
00390     {
00391       as_bad (_("register is wrong size for a word %s"), string);
00392     }
00393 }
00394 
00395 /* Make sure the mode supplied is the size of an address.  */
00396 
00397 static void
00398 regaddr (int mode, char *string)
00399 {
00400   int ok;
00401 
00402   ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
00403   if (ok != mode)
00404     {
00405       as_bad (_("register is wrong size for address %s"), string);
00406     }
00407 }
00408 
00409 struct ctrl_names {
00410   int value;
00411   char *name;
00412 };
00413 
00414 static struct ctrl_names ctrl_table[] = {
00415   { 0x1, "flags" },   /* ldctlb only.  */
00416   { 0x2, "fcw" },     /* ldctl only.  Applies to all remaining control registers.  */
00417   { 0x3, "refresh" },
00418   { 0x4, "psapseg" },
00419   { 0x5, "psapoff" },
00420   { 0x5, "psap" },
00421   { 0x6, "nspseg" },
00422   { 0x7, "nspoff" },
00423   { 0x7, "nsp" },
00424   { 0  , 0 }
00425 };
00426 
00427 static void
00428 get_ctrl_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
00429 {
00430   char *src = *ptr;
00431   int i, l;
00432 
00433   while (*src == ' ')
00434     src++;
00435 
00436   mode->mode = CLASS_CTRL;
00437   for (i = 0; ctrl_table[i].name; i++)
00438     {
00439       l = strlen (ctrl_table[i].name);
00440       if (! strncasecmp (ctrl_table[i].name, src, l))
00441         {
00442           the_ctrl = ctrl_table[i].value;
00443           if (*(src + l) && *(src + l) != ',')
00444             break;
00445           *ptr = src + l;  /* Valid control name found: "consume" it.  */
00446           return;
00447         }
00448     }
00449   the_ctrl = 0;
00450 }
00451 
00452 struct flag_names {
00453   int value;
00454   char *name;
00455 };
00456 
00457 static struct flag_names flag_table[] = {
00458   { 0x1, "P" },
00459   { 0x1, "V" },
00460   { 0x2, "S" },
00461   { 0x4, "Z" },
00462   { 0x8, "C" },
00463   { 0x0, "+" },
00464   { 0x0, "," },
00465   { 0, 0 }
00466 };
00467 
00468 static void
00469 get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
00470 {
00471   char *src = *ptr;
00472   char c;
00473   int i;
00474   int j;
00475 
00476   while (*src == ' ')
00477     src++;
00478 
00479   mode->mode = CLASS_FLAGS;
00480   the_flags = 0;
00481   for (j = 0; j <= 9; j++)
00482     {
00483       if (!src[j])
00484        goto done;
00485       c = TOUPPER(src[j]);
00486       for (i = 0; flag_table[i].name; i++)
00487        {
00488          if (flag_table[i].name[0] == c)
00489            {
00490              the_flags = the_flags | flag_table[i].value;
00491              goto match;
00492            }
00493        }
00494       goto done;
00495     match:
00496       ;
00497     }
00498  done:
00499   *ptr = src + j;
00500 }
00501 
00502 struct interrupt_names {
00503   int value;
00504   char *name;
00505 };
00506 
00507 static struct interrupt_names intr_table[] = {
00508   { 0x1, "nvi" },
00509   { 0x2, "vi" },
00510   { 0x3, "both" },
00511   { 0x3, "all" },
00512   { 0, 0 }
00513 };
00514 
00515 static void
00516 get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
00517 {
00518   char *src = *ptr;
00519   int i, l;
00520 
00521   while (*src == ' ')
00522     src++;
00523 
00524   mode->mode = CLASS_IMM;
00525   the_interrupt = 0;
00526 
00527   while (*src)
00528     {
00529       for (i = 0; intr_table[i].name; i++)
00530        {
00531          l = strlen (intr_table[i].name);
00532          if (! strncasecmp (intr_table[i].name, src, l))
00533            {
00534              the_interrupt |= intr_table[i].value;
00535              if (*(src + l) && *(src + l) != ',')
00536               {
00537                 *ptr = src + l;
00538               invalid:
00539                 as_bad (_("unknown interrupt %s"), src);
00540                 while (**ptr && ! is_end_of_line[(unsigned char) **ptr])
00541                   (*ptr)++;  /* Consume rest of line.  */
00542                 return;
00543               }
00544              src += l;
00545              if (! *src)
00546               {
00547                 *ptr = src;
00548                 return;
00549               }
00550            }
00551        }
00552       if (*src == ',')
00553        src++;
00554       else
00555        {
00556          *ptr = src;
00557          goto invalid;
00558        }
00559     }
00560 
00561   /* No interrupt type specified, opcode won't do anything.  */
00562   as_warn (_("opcode has no effect"));
00563   the_interrupt = 0x0;
00564 }
00565 
00566 struct cc_names {
00567   int value;
00568   char *name;
00569 };
00570 
00571 static struct cc_names table[] = {
00572   { 0x0, "f" },
00573   { 0x1, "lt" },
00574   { 0x2, "le" },
00575   { 0x3, "ule" },
00576   { 0x4, "ov/pe" },
00577   { 0x4, "ov" },
00578   { 0x4, "pe/ov" },
00579   { 0x4, "pe" },
00580   { 0x5, "mi" },
00581   { 0x6, "eq" },
00582   { 0x6, "z" },
00583   { 0x7, "c/ult" },
00584   { 0x7, "c" },
00585   { 0x7, "ult/c" },
00586   { 0x7, "ult" },
00587   { 0x8, "t" },
00588   { 0x9, "ge" },
00589   { 0xa, "gt" },
00590   { 0xb, "ugt" },
00591   { 0xc, "nov/po" },
00592   { 0xc, "nov" },
00593   { 0xc, "po/nov" },
00594   { 0xc, "po" },
00595   { 0xd, "pl" },
00596   { 0xe, "ne" },
00597   { 0xe, "nz" },
00598   { 0xf, "nc/uge" },
00599   { 0xf, "nc" },
00600   { 0xf, "uge/nc" },
00601   { 0xf, "uge" },
00602   { 0  ,  0 }
00603 };
00604 
00605 static void
00606 get_cc_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
00607 {
00608   char *src = *ptr;
00609   int i, l;
00610 
00611   while (*src == ' ')
00612     src++;
00613 
00614   mode->mode = CLASS_CC;
00615   for (i = 0; table[i].name; i++)
00616     {
00617       l = strlen (table[i].name);
00618       if (! strncasecmp (table[i].name, src, l))
00619         {
00620           the_cc = table[i].value;
00621           if (*(src + l) && *(src + l) != ',')
00622             break;
00623           *ptr = src + l;  /* Valid cc found: "consume" it.  */
00624           return;
00625         }
00626     }
00627   the_cc = 0x8;  /* Not recognizing the cc defaults to t.  (Assuming no cc present.)  */
00628 }
00629 
00630 static void
00631 get_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
00632 {
00633   char *src = *ptr;
00634   char *end;
00635 
00636   mode->mode = 0;
00637 
00638   while (*src == ' ')
00639     src++;
00640   if (*src == '#')
00641     {
00642       mode->mode = CLASS_IMM;
00643       imm_operand = &(mode->exp);
00644       src = parse_exp (src + 1, &(mode->exp));
00645     }
00646   else if (*src == '@')
00647     {
00648       mode->mode = CLASS_IR;
00649       src = parse_reg (src + 1, &mode->regsize, &mode->reg);
00650     }
00651   else
00652     {
00653       unsigned int regn;
00654 
00655       end = parse_reg (src, &mode->mode, &regn);
00656 
00657       if (end)
00658        {
00659          int nw;
00660          unsigned int nr;
00661 
00662          src = end;
00663          if (*src == '(')
00664            {
00665              src++;
00666              end = parse_reg (src, &nw, &nr);
00667              if (end)
00668               {
00669                 /* Got Ra(Rb).  */
00670                 src = end;
00671 
00672                 if (*src != ')')
00673                   as_bad (_("Missing ) in ra(rb)"));
00674                 else
00675                   src++;
00676 
00677                 regaddr (mode->mode, "ra(rb) ra");
00678                 mode->mode = CLASS_BX;
00679                 mode->reg = regn;
00680                 mode->x_reg = nr;
00681                 reg[ARG_RX] = nr;
00682               }
00683              else
00684               {
00685                 /* Got Ra(disp).  */
00686                 if (*src == '#')
00687                   src++;
00688                 src = parse_exp (src, &(mode->exp));
00689                 src = checkfor (src, ')');
00690                 mode->mode = CLASS_BA;
00691                 mode->reg = regn;
00692                 mode->x_reg = 0;
00693                 imm_operand = &(mode->exp);
00694               }
00695            }
00696          else
00697            {
00698              mode->reg = regn;
00699              mode->x_reg = 0;
00700            }
00701        }
00702       else
00703        {
00704          /* No initial reg.  */
00705          src = parse_exp (src, &(mode->exp));
00706          if (*src == '(')
00707            {
00708              src++;
00709              end = parse_reg (src, &(mode->mode), &regn);
00710              regword (mode->mode, "addr(Ra) ra");
00711              mode->mode = CLASS_X;
00712              mode->reg = regn;
00713              mode->x_reg = 0;
00714              da_operand = &(mode->exp);
00715              src = checkfor (end, ')');
00716            }
00717          else
00718            {
00719              /* Just an address.  */
00720              mode->mode = CLASS_DA;
00721              mode->reg = 0;
00722              mode->x_reg = 0;
00723              da_operand = &(mode->exp);
00724            }
00725        }
00726     }
00727   *ptr = src;
00728 }
00729 
00730 static char *
00731 get_operands (const opcode_entry_type *opcode, char *op_end, op_type *operand)
00732 {
00733   char *ptr = op_end;
00734   char *savptr;
00735 
00736   switch (opcode->noperands)
00737     {
00738     case 0:
00739       operand[0].mode = 0;
00740       operand[1].mode = 0;
00741       while (*ptr == ' ')
00742         ptr++;
00743       break;
00744 
00745     case 1:
00746       if (opcode->arg_info[0] == CLASS_CC)
00747         {
00748           get_cc_operand (&ptr, operand + 0, 0);
00749           while (*ptr == ' ')
00750             ptr++;
00751           if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
00752             {
00753               as_bad (_("invalid condition code '%s'"), ptr);
00754               while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
00755                 ptr++;   /* Consume rest of line.  */
00756             }
00757         }
00758       else if (opcode->arg_info[0] == CLASS_FLAGS)
00759        {
00760          get_flags_operand (&ptr, operand + 0, 0);
00761          while (*ptr == ' ')
00762            ptr++;
00763          if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
00764            {
00765              as_bad (_("invalid flag '%s'"), ptr);
00766              while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
00767               ptr++;  /* Consume rest of line.  */
00768            }
00769        }
00770       else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))
00771        get_interrupt_operand (&ptr, operand + 0, 0);
00772       else
00773        get_operand (&ptr, operand + 0, 0);
00774 
00775       operand[1].mode = 0;
00776       break;
00777 
00778     case 2:
00779       savptr = ptr;
00780       if (opcode->arg_info[0] == CLASS_CC)
00781         {
00782           get_cc_operand (&ptr, operand + 0, 0);
00783           while (*ptr == ' ')
00784             ptr++;
00785           if (*ptr != ',' && strchr (ptr + 1, ','))
00786             {
00787               savptr = ptr;
00788               while (*ptr != ',')
00789                 ptr++;
00790               *ptr = 0;
00791               ptr++;
00792               as_bad (_("invalid condition code '%s'"), savptr);
00793             }
00794         }
00795       else if (opcode->arg_info[0] == CLASS_CTRL)
00796        {
00797          get_ctrl_operand (&ptr, operand + 0, 0);
00798 
00799          if (the_ctrl == 0)
00800            {
00801              ptr = savptr;
00802              get_operand (&ptr, operand + 0, 0);
00803 
00804              if (ptr == 0)
00805               return NULL;
00806              if (*ptr == ',')
00807               ptr++;
00808              get_ctrl_operand (&ptr, operand + 1, 1);
00809              if (the_ctrl == 0)
00810               return NULL;
00811              return ptr;
00812            }
00813        }
00814       else
00815        get_operand (&ptr, operand + 0, 0);
00816 
00817       if (ptr == 0)
00818        return NULL;
00819       if (*ptr == ',')
00820        ptr++;
00821       get_operand (&ptr, operand + 1, 1);
00822       break;
00823 
00824     case 3:
00825       get_operand (&ptr, operand + 0, 0);
00826       if (*ptr == ',')
00827        ptr++;
00828       get_operand (&ptr, operand + 1, 1);
00829       if (*ptr == ',')
00830        ptr++;
00831       get_operand (&ptr, operand + 2, 2);
00832       break;
00833 
00834     case 4:
00835       get_operand (&ptr, operand + 0, 0);
00836       if (*ptr == ',')
00837        ptr++;
00838       get_operand (&ptr, operand + 1, 1);
00839       if (*ptr == ',')
00840        ptr++;
00841       get_operand (&ptr, operand + 2, 2);
00842       if (*ptr == ',')
00843        ptr++;
00844       get_cc_operand (&ptr, operand + 3, 3);
00845       break;
00846 
00847     default:
00848       abort ();
00849     }
00850 
00851   return ptr;
00852 }
00853 
00854 /* Passed a pointer to a list of opcodes which use different
00855    addressing modes.  Return the opcode which matches the opcodes
00856    provided.  */
00857 
00858 static opcode_entry_type *
00859 get_specific (opcode_entry_type *opcode, op_type *operands)
00860 {
00861   opcode_entry_type *this_try = opcode;
00862   int found = 0;
00863   unsigned int noperands = opcode->noperands;
00864 
00865   int this_index = opcode->idx;
00866 
00867   while (this_index == opcode->idx && !found)
00868     {
00869       unsigned int i;
00870 
00871       this_try = opcode++;
00872       for (i = 0; i < noperands; i++)
00873        {
00874          unsigned int mode = operands[i].mode;
00875 
00876           if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO))
00877             {
00878               mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO;
00879             }
00880 
00881          if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
00882            {
00883              /* It could be a pc rel operand, if this is a da mode
00884                and we like disps, then insert it.  */
00885 
00886              if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
00887               {
00888                 /* This is the case.  */
00889                 operands[i].mode = CLASS_DISP;
00890               }
00891              else if (mode == CLASS_BA && this_try->arg_info[i])
00892               {
00893                 /* Can't think of a way to turn what we've been
00894                    given into something that's OK.  */
00895                 goto fail;
00896               }
00897              else if (this_try->arg_info[i] & CLASS_PR)
00898               {
00899                 if (mode == CLASS_REG_LONG && segmented_mode)
00900                   {
00901                     /* OK.  */
00902                   }
00903                 else if (mode == CLASS_REG_WORD && !segmented_mode)
00904                   {
00905                     /* OK.  */
00906                   }
00907                 else
00908                   goto fail;
00909               }
00910              else
00911               goto fail;
00912            }
00913          switch (mode & CLASS_MASK)
00914            {
00915            default:
00916              break;
00917            case CLASS_IRO:
00918              if (operands[i].regsize != CLASS_REG_WORD)
00919               as_bad (_("invalid indirect register size"));
00920              reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
00921              break;
00922            case CLASS_IR:
00923              if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG)
00924                 || (!segmented_mode && operands[i].regsize != CLASS_REG_WORD))
00925               as_bad (_("invalid indirect register size"));
00926              reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
00927              break;
00928            case CLASS_X:
00929            case CLASS_BA:
00930            case CLASS_BX:
00931            case CLASS_DISP:
00932            case CLASS_REG:
00933            case CLASS_REG_WORD:
00934            case CLASS_REG_BYTE:
00935            case CLASS_REG_QUAD:
00936            case CLASS_REG_LONG:
00937            case CLASS_REGN0:
00938              reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
00939              break;
00940            case CLASS_CTRL:
00941              if (this_try->opcode == OPC_ldctlb && the_ctrl != 1)
00942               as_bad (_("invalid control register name"));
00943              break;
00944            }
00945        }
00946 
00947       found = 1;
00948     fail:
00949       ;
00950     }
00951   if (found)
00952     return this_try;
00953   else
00954     return 0;
00955 }
00956 
00957 static char buffer[20];
00958 
00959 static void
00960 newfix (int ptr, int type, int size, expressionS *operand)
00961 {
00962   int is_pcrel = 0;
00963   fixS *fixP;
00964 
00965   /* Size is in nibbles.  */
00966   if (operand->X_add_symbol
00967       || operand->X_op_symbol
00968       || operand->X_add_number)
00969     {
00970       switch(type)
00971         {
00972         case BFD_RELOC_8_PCREL:
00973         case BFD_RELOC_Z8K_CALLR:
00974         case BFD_RELOC_Z8K_DISP7:
00975           is_pcrel = 1;
00976         }
00977       fixP = fix_new_exp (frag_now, ptr, size / 2,
00978                           operand, is_pcrel, type);
00979       if (is_pcrel)
00980        fixP->fx_no_overflow = 1;
00981     }
00982 }
00983 
00984 static char *
00985 apply_fix (char *ptr, int type, expressionS *operand, int size)
00986 {
00987   long n = operand->X_add_number;
00988 
00989   /* size is in nibbles.  */
00990 
00991   newfix ((ptr - buffer) / 2, type, size + 1, operand);
00992   switch (size)
00993     {
00994     case 8:                 /* 8 nibbles == 32 bits.  */
00995       *ptr++ = n >> 28;
00996       *ptr++ = n >> 24;
00997       *ptr++ = n >> 20;
00998       *ptr++ = n >> 16;
00999     case 4:                 /* 4 nibbles == 16 bits.  */
01000       *ptr++ = n >> 12;
01001       *ptr++ = n >> 8;
01002     case 2:
01003       *ptr++ = n >> 4;
01004     case 1:
01005       *ptr++ = n >> 0;
01006       break;
01007     }
01008   return ptr;
01009 }
01010 
01011 /* Now we know what sort of opcodes it is.  Let's build the bytes.  */
01012 
01013 static void
01014 build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED)
01015 {
01016   char *output_ptr = buffer;
01017   int c;
01018   int nibble;
01019   unsigned int *class_ptr;
01020 
01021   frag_wane (frag_now);
01022   frag_new (0);
01023 
01024   if (frag_room () < 8)
01025     frag_grow (8);  /* Make room for maximum instruction size.  */
01026 
01027   memset (buffer, 0, sizeof (buffer));
01028   class_ptr = this_try->byte_info;
01029 
01030   for (nibble = 0; (c = *class_ptr++); nibble++)
01031     {
01032 
01033       switch (c & CLASS_MASK)
01034        {
01035        default:
01036          abort ();
01037 
01038        case CLASS_ADDRESS:
01039          /* Direct address, we don't cope with the SS mode right now.  */
01040          if (segmented_mode)
01041            {
01042              /* da_operand->X_add_number |= 0x80000000;  --  Now set at relocation time.  */
01043              output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8);
01044            }
01045          else
01046            {
01047              output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
01048            }
01049          da_operand = 0;
01050          break;
01051        case CLASS_DISP8:
01052          /* pc rel 8 bit  */
01053          output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2);
01054          da_operand = 0;
01055          break;
01056 
01057        case CLASS_0DISP7:
01058          /* pc rel 7 bit  */
01059          *output_ptr = 0;
01060          output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
01061          da_operand = 0;
01062          break;
01063 
01064        case CLASS_1DISP7:
01065          /* pc rel 7 bit  */
01066          *output_ptr = 0x80;
01067          output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
01068          output_ptr[-2] = 0x8;
01069          da_operand = 0;
01070          break;
01071 
01072        case CLASS_BIT_1OR2:
01073          *output_ptr = c & 0xf;
01074          if (imm_operand)
01075            {
01076              if (imm_operand->X_add_number == 2)
01077               *output_ptr |= 2;
01078              else if (imm_operand->X_add_number != 1)
01079               as_bad (_("immediate must be 1 or 2"));
01080            }
01081          else
01082            as_bad (_("immediate 1 or 2 expected"));
01083          output_ptr++;
01084          break;
01085        case CLASS_CC:
01086          *output_ptr++ = the_cc;
01087          break;
01088        case CLASS_0CCC:
01089          if (the_ctrl < 2 || the_ctrl > 7)
01090            as_bad (_("invalid control register name"));
01091          *output_ptr++ = the_ctrl;
01092          break;
01093        case CLASS_1CCC:
01094          if (the_ctrl < 2 || the_ctrl > 7)
01095            as_bad (_("invalid control register name"));
01096          *output_ptr++ = the_ctrl | 0x8;
01097          break;
01098        case CLASS_00II:
01099          *output_ptr++ = (~the_interrupt & 0x3);
01100          break;
01101        case CLASS_01II:
01102          *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
01103          break;
01104        case CLASS_FLAGS:
01105          *output_ptr++ = the_flags;
01106          break;
01107        case CLASS_IGNORE:
01108        case CLASS_BIT:
01109          *output_ptr++ = c & 0xf;
01110          break;
01111        case CLASS_REGN0:
01112          if (reg[c & 0xf] == 0)
01113            as_bad (_("can't use R0 here"));
01114          /* Fall through.  */
01115        case CLASS_REG:
01116        case CLASS_REG_BYTE:
01117        case CLASS_REG_WORD:
01118        case CLASS_REG_LONG:
01119        case CLASS_REG_QUAD:
01120          /* Insert bit mattern of right reg.  */
01121          *output_ptr++ = reg[c & 0xf];
01122          break;
01123        case CLASS_DISP:
01124           switch (c & ARG_MASK)
01125             {
01126             case ARG_DISP12:
01127               output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4);
01128               break;
01129             case ARG_DISP16:
01130              output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4);
01131              break;
01132            default:
01133              output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
01134            }
01135          da_operand = 0;
01136          break;
01137 
01138        case CLASS_IMM:
01139          {
01140            switch (c & ARG_MASK)
01141              {
01142              case ARG_NIM4:
01143                 if (imm_operand->X_add_number > 15)
01144                 as_bad (_("immediate value out of range"));
01145               imm_operand->X_add_number = -imm_operand->X_add_number;
01146               output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
01147               break;
01148               /*case ARG_IMMNMINUS1: not used.  */
01149              case ARG_IMM4M1:
01150               imm_operand->X_add_number--;
01151                 /* Drop through.  */
01152              case ARG_IMM4:
01153                 if (imm_operand->X_add_number > 15)
01154                 as_bad (_("immediate value out of range"));
01155               output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
01156               break;
01157              case ARG_NIM8:
01158               imm_operand->X_add_number = -imm_operand->X_add_number;
01159                 /* Drop through.  */
01160              case ARG_IMM8:
01161               output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2);
01162               break;
01163              case ARG_IMM16:
01164               output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4);
01165               break;
01166              case ARG_IMM32:
01167               output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8);
01168               break;
01169              default:
01170               abort ();
01171              }
01172          }
01173        }
01174     }
01175 
01176   /* Copy from the nibble buffer into the frag.  */
01177   {
01178     int length = (output_ptr - buffer) / 2;
01179     char *src = buffer;
01180     char *fragp = frag_more (length);
01181 
01182     while (src < output_ptr)
01183       {
01184        *fragp = (src[0] << 4) | src[1];
01185        src += 2;
01186        fragp++;
01187       }
01188   }
01189 }
01190 
01191 /* This is the guts of the machine-dependent assembler.  STR points to a
01192    machine dependent instruction.  This function is supposed to emit
01193    the frags/bytes it assembles to.  */
01194 
01195 void
01196 md_assemble (char *str)
01197 {
01198   char c;
01199   char *op_start;
01200   char *op_end;
01201   struct z8k_op operand[4];
01202   opcode_entry_type *opcode;
01203 
01204   /* Drop leading whitespace.  */
01205   while (*str == ' ')
01206     str++;
01207 
01208   /* Find the op code end.  */
01209   for (op_start = op_end = str;
01210        *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end];
01211        op_end++)
01212     ;
01213 
01214   if (op_end == op_start)
01215     {
01216       as_bad (_("can't find opcode "));
01217     }
01218   c = *op_end;
01219 
01220   *op_end = 0;  /* Zero-terminate op code string for hash_find() call.  */
01221 
01222   opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);
01223 
01224   if (opcode == NULL)
01225     {
01226       as_bad (_("unknown opcode"));
01227       return;
01228     }
01229 
01230   *op_end = c;  /* Restore original string.  */
01231 
01232   if (opcode->opcode == 250)
01233     {
01234       pseudo_typeS *p;
01235       char oc;
01236       char *old = input_line_pointer;
01237 
01238       /* Was really a pseudo op.  */
01239 
01240       input_line_pointer = op_end;
01241 
01242       oc = *old;
01243       *old = '\n';
01244       while (*input_line_pointer == ' ')
01245        input_line_pointer++;
01246       p = (pseudo_typeS *) (opcode->func);
01247 
01248       (p->poc_handler) (p->poc_val);
01249       input_line_pointer = old;
01250       *old = oc;
01251     }
01252   else
01253     {
01254       char *new_input_line_pointer;
01255 
01256       new_input_line_pointer = get_operands (opcode, op_end, operand);
01257       if (new_input_line_pointer)
01258         {
01259           input_line_pointer = new_input_line_pointer;
01260           opcode = get_specific (opcode, operand);
01261         }
01262 
01263       if (new_input_line_pointer == NULL || opcode == NULL)
01264        {
01265          /* Couldn't find an opcode which matched the operands.  */
01266          char *where = frag_more (2);
01267 
01268          where[0] = 0x0;
01269          where[1] = 0x0;
01270 
01271          as_bad (_("Can't find opcode to match operands"));
01272          return;
01273        }
01274 
01275       build_bytes (opcode, operand);
01276     }
01277 }
01278 
01279 /* We have no need to default values of symbols.  */
01280 
01281 symbolS *
01282 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
01283 {
01284   return 0;
01285 }
01286 
01287 /* Various routines to kill one day.  */
01288 /* Equal to MAX_PRECISION in atof-ieee.c.  */
01289 #define MAX_LITTLENUMS 6
01290 
01291 /* Turn a string in input_line_pointer into a floating point constant
01292    of type TYPE, and store the appropriate bytes in *LITP.  The number
01293    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
01294    returned, or NULL on OK.  */
01295 
01296 char *
01297 md_atof (int type, char *litP, int *sizeP)
01298 {
01299   int prec;
01300   LITTLENUM_TYPE words[MAX_LITTLENUMS];
01301   LITTLENUM_TYPE *wordP;
01302   char *t;
01303 
01304   switch (type)
01305     {
01306     case 'f':
01307     case 'F':
01308     case 's':
01309     case 'S':
01310       prec = 2;
01311       break;
01312 
01313     case 'd':
01314     case 'D':
01315     case 'r':
01316     case 'R':
01317       prec = 4;
01318       break;
01319 
01320     case 'x':
01321     case 'X':
01322       prec = 6;
01323       break;
01324 
01325     case 'p':
01326     case 'P':
01327       prec = 6;
01328       break;
01329 
01330     default:
01331       *sizeP = 0;
01332       return _("Bad call to MD_ATOF()");
01333     }
01334   t = atof_ieee (input_line_pointer, type, words);
01335   if (t)
01336     input_line_pointer = t;
01337 
01338   *sizeP = prec * sizeof (LITTLENUM_TYPE);
01339   for (wordP = words; prec--;)
01340     {
01341       md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
01342       litP += sizeof (LITTLENUM_TYPE);
01343     }
01344   return 0;
01345 }
01346 
01347 const char *md_shortopts = "z:";
01348 
01349 struct option md_longopts[] =
01350   {
01351 #define OPTION_RELAX  (OPTION_MD_BASE)
01352     {"linkrelax", no_argument, NULL, OPTION_RELAX},
01353     {NULL, no_argument, NULL, 0}
01354   };
01355 
01356 size_t md_longopts_size = sizeof (md_longopts);
01357 
01358 int
01359 md_parse_option (int c, char *arg)
01360 {
01361   switch (c)
01362     {
01363     case 'z':
01364       if (!strcmp (arg, "8001"))
01365        s_segm (1);
01366       else if (!strcmp (arg, "8002"))
01367        s_segm (0);
01368       else
01369        {
01370          as_bad (_("invalid architecture -z%s"), arg);
01371          return 0;
01372        }
01373       z8k_target_from_cmdline = 1;
01374       break;
01375 
01376     case OPTION_RELAX:
01377       linkrelax = 1;
01378       break;
01379 
01380     default:
01381       return 0;
01382     }
01383 
01384   return 1;
01385 }
01386 
01387 void
01388 md_show_usage (FILE *stream)
01389 {
01390   fprintf (stream, _("\
01391  Z8K options:\n\
01392   -z8001                  generate segmented code\n\
01393   -z8002                  generate unsegmented code\n\
01394   -linkrelax              create linker relaxable code\n"));
01395 }
01396 
01397 void
01398 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
01399                  segT sec ATTRIBUTE_UNUSED,
01400                  fragS *fragP ATTRIBUTE_UNUSED)
01401 {
01402   printf (_("call to md_convert_frag\n"));
01403   abort ();
01404 }
01405 
01406 /* Generate a machine dependent reloc from a fixup.  */
01407 
01408 arelent*
01409 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
01410              fixS *fixp      ATTRIBUTE_UNUSED)
01411 {
01412   arelent *reloc;
01413 
01414   reloc = xmalloc (sizeof (*reloc));
01415   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
01416   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
01417   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
01418   reloc->addend = fixp->fx_offset;
01419   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
01420 
01421   if (! reloc->howto)
01422     {
01423       as_bad_where (fixp->fx_file, fixp->fx_line,
01424                     "Cannot represent %s relocation in object file",
01425                     bfd_get_reloc_code_name (fixp->fx_r_type));
01426       abort ();
01427     }
01428   return reloc;
01429 }
01430 
01431 valueT
01432 md_section_align (segT seg, valueT size)
01433 {
01434   int align = bfd_get_section_alignment (stdoutput, seg);
01435   valueT mask = ((valueT) 1 << align) - 1;
01436 
01437   return (size + mask) & ~mask;
01438 }
01439 
01440 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
01441    has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
01442    we will have to generate a reloc entry.  */
01443 void
01444 md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
01445 {
01446   long val = * (long *) valP;
01447   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
01448 
01449   switch (fixP->fx_r_type)
01450     {
01451     case BFD_RELOC_Z8K_IMM4L:
01452       if (fixP->fx_addsy)
01453         {
01454           fixP->fx_no_overflow = 1;
01455           fixP->fx_done = 0;
01456         }
01457       else
01458        buf[0] = (buf[0] & 0xf0) | (val & 0xf);
01459       break;
01460 
01461     case BFD_RELOC_8:
01462       if (fixP->fx_addsy)
01463         {
01464           fixP->fx_no_overflow = 1;
01465           fixP->fx_done = 0;
01466         }
01467       else
01468        *buf++ = val;
01469       break;
01470 
01471     case BFD_RELOC_16:
01472       if (fixP->fx_addsy)
01473         {
01474           fixP->fx_no_overflow = 1;
01475           fixP->fx_done = 0;
01476         }
01477       else
01478         {
01479           *buf++ = (val >> 8);
01480           *buf++ = val;
01481         }
01482       break;
01483 
01484     case BFD_RELOC_32:
01485       if (fixP->fx_addsy)
01486         {
01487           fixP->fx_no_overflow = 1;
01488           fixP->fx_done = 0;
01489         }
01490       else
01491         {
01492           *buf++ = (val >> 24);
01493           *buf++ = (val >> 16);
01494           *buf++ = (val >> 8);
01495           *buf++ = val;
01496         }
01497       break;
01498 
01499     case BFD_RELOC_8_PCREL:
01500       if (fixP->fx_addsy)
01501         {
01502           fixP->fx_no_overflow = 1;
01503           fixP->fx_done = 0;
01504         }
01505       else
01506         {
01507           if (val & 1)
01508             as_bad_where (fixP->fx_file, fixP->fx_line,
01509                           _("cannot branch to odd address"));
01510           val /= 2;
01511           if (val > 127 || val < -128)
01512             as_bad_where (fixP->fx_file, fixP->fx_line,
01513                           _("relative jump out of range"));
01514           *buf++ = val;
01515           fixP->fx_no_overflow = 1;
01516           fixP->fx_done = 1;
01517         }
01518       break;
01519 
01520     case BFD_RELOC_16_PCREL:
01521       if (fixP->fx_addsy)
01522         {
01523           fixP->fx_no_overflow = 1;
01524           fixP->fx_done = 0;
01525         }
01526       else
01527         {
01528           val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
01529           if (val > 32767 || val < -32768)
01530             as_bad_where (fixP->fx_file, fixP->fx_line,
01531                           _("relative address out of range"));
01532           *buf++ = (val >> 8);
01533           *buf++ = val;
01534           fixP->fx_no_overflow = 1;
01535           fixP->fx_done = 1;
01536         }
01537       break;
01538 
01539     case BFD_RELOC_Z8K_CALLR:
01540       if (fixP->fx_addsy)
01541         {
01542           fixP->fx_no_overflow = 1;
01543           fixP->fx_done = 0;
01544         }
01545       else
01546         {
01547           if (val & 1)
01548             as_bad_where (fixP->fx_file, fixP->fx_line,
01549                           _("cannot branch to odd address"));
01550           if (val > 4096 || val < -4095)
01551             as_bad_where (fixP->fx_file, fixP->fx_line,
01552                           _("relative call out of range"));
01553           val = -val / 2;
01554           *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
01555           buf++;
01556           *buf++ = val & 0xff;
01557           fixP->fx_no_overflow = 1;
01558           fixP->fx_done = 1;
01559         }
01560       break;
01561 
01562     case BFD_RELOC_Z8K_DISP7:
01563       if (fixP->fx_addsy)
01564         {
01565           fixP->fx_no_overflow = 1;
01566           fixP->fx_done = 0;
01567         }
01568       else
01569         {
01570           if (val & 1)
01571             as_bad_where (fixP->fx_file, fixP->fx_line,
01572                           _("cannot branch to odd address"));
01573           val /= 2;
01574           if (val > 0 || val < -127)
01575             as_bad_where (fixP->fx_file, fixP->fx_line,
01576                           _("relative jump out of range"));
01577           *buf = (*buf & 0x80) | (-val & 0x7f);
01578           fixP->fx_no_overflow = 1;
01579           fixP->fx_done = 1;
01580         }
01581       break;
01582 
01583     default:
01584       printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
01585       abort ();
01586     }
01587 
01588   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
01589     fixP->fx_done = 1;
01590 }
01591 
01592 int
01593 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
01594                                segT segment_type ATTRIBUTE_UNUSED)
01595 {
01596   printf (_("call to md_estimate_size_before_relax\n"));
01597   abort ();
01598 }
01599 
01600 /* Put number into target byte order.  */
01601 
01602 void
01603 md_number_to_chars (char *ptr, valueT use, int nbytes)
01604 {
01605   number_to_chars_bigendian (ptr, use, nbytes);
01606 }
01607 
01608 /* On the Z8000, a PC-relative offset is relative to the address of the
01609    instruction plus its size.  */
01610 long
01611 md_pcrel_from (fixS *fixP)
01612 {
01613   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
01614 }
01615 
01616 void
01617 tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED)
01618 {
01619 }