Home | History | Annotate | Line # | Download | only in config
      1   1.1  christos /* tc-d10v.c -- Assembler code for the Mitsubishi D10V
      2  1.10  christos    Copyright (C) 1996-2025 Free Software Foundation, Inc.
      3   1.1  christos 
      4   1.1  christos    This file is part of GAS, the GNU Assembler.
      5   1.1  christos 
      6   1.1  christos    GAS is free software; you can redistribute it and/or modify
      7   1.1  christos    it under the terms of the GNU General Public License as published by
      8   1.1  christos    the Free Software Foundation; either version 3, or (at your option)
      9   1.1  christos    any later version.
     10   1.1  christos 
     11   1.1  christos    GAS is distributed in the hope that it will be useful,
     12   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1  christos    GNU General Public License for more details.
     15   1.1  christos 
     16   1.1  christos    You should have received a copy of the GNU General Public License
     17   1.1  christos    along with GAS; see the file COPYING.  If not, write to
     18   1.1  christos    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
     19   1.1  christos    Boston, MA 02110-1301, USA.  */
     20   1.1  christos 
     21   1.1  christos #include "as.h"
     22   1.1  christos #include "safe-ctype.h"
     23   1.1  christos #include "subsegs.h"
     24   1.1  christos #include "opcode/d10v.h"
     25   1.1  christos #include "elf/ppc.h"
     26   1.1  christos #include "dwarf2dbg.h"
     27   1.1  christos 
     28   1.1  christos const char comment_chars[]        = ";";
     29   1.1  christos const char line_comment_chars[]   = "#";
     30   1.1  christos const char line_separator_chars[] = "";
     31  1.10  christos const char md_shortopts[]         = "O";
     32   1.1  christos const char EXP_CHARS[]            = "eE";
     33   1.1  christos const char FLT_CHARS[]            = "dD";
     34   1.1  christos 
     35   1.1  christos int Optimizing = 0;
     36   1.1  christos 
     37   1.1  christos #define AT_WORD_P(X) ((X)->X_op == O_right_shift \
     38   1.1  christos 		      && (X)->X_op_symbol != NULL \
     39   1.1  christos 		      && symbol_constant_p ((X)->X_op_symbol) \
     40   1.1  christos 		      && S_GET_VALUE ((X)->X_op_symbol) == AT_WORD_RIGHT_SHIFT)
     41   1.1  christos #define AT_WORD_RIGHT_SHIFT 2
     42   1.1  christos 
     43   1.1  christos /* Fixups.  */
     44   1.1  christos #define MAX_INSN_FIXUPS  5
     45   1.1  christos 
     46   1.1  christos struct d10v_fixup
     47   1.1  christos {
     48   1.1  christos   expressionS exp;
     49   1.1  christos   int operand;
     50   1.1  christos   int pcrel;
     51   1.1  christos   int size;
     52   1.1  christos   bfd_reloc_code_real_type reloc;
     53   1.1  christos };
     54   1.1  christos 
     55   1.1  christos typedef struct _fixups
     56   1.1  christos {
     57   1.1  christos   int fc;
     58   1.1  christos   struct d10v_fixup fix[MAX_INSN_FIXUPS];
     59   1.1  christos   struct _fixups *next;
     60   1.1  christos } Fixups;
     61   1.1  christos 
     62   1.1  christos static Fixups FixUps[2];
     63   1.1  christos static Fixups *fixups;
     64   1.1  christos 
     65   1.1  christos static int do_not_ignore_hash = 0;
     66   1.1  christos 
     67   1.1  christos typedef int packing_type;
     68   1.1  christos #define PACK_UNSPEC 	(0)	/* Packing order not specified.  */
     69   1.1  christos #define PACK_PARALLEL	(1)	/* "||"  */
     70   1.1  christos #define PACK_LEFT_RIGHT (2)	/* "->"  */
     71   1.1  christos #define PACK_RIGHT_LEFT (3)	/* "<-"  */
     72   1.1  christos static packing_type etype = PACK_UNSPEC; /* Used by d10v_cleanup.  */
     73   1.1  christos 
     74   1.1  christos /* TRUE if instruction swapping warnings should be inhibited.
     75   1.1  christos    --nowarnswap.  */
     76   1.8  christos static bool flag_warn_suppress_instructionswap;
     77   1.1  christos 
     78   1.1  christos /* TRUE if instruction packing should be performed when --gstabs is specified.
     79   1.1  christos    --gstabs-packing, --no-gstabs-packing.  */
     80   1.8  christos static bool flag_allow_gstabs_packing = 1;
     81   1.1  christos 
     82   1.1  christos /* Local functions.  */
     83   1.1  christos 
     84   1.1  christos enum options
     85   1.1  christos {
     86   1.1  christos   OPTION_NOWARNSWAP = OPTION_MD_BASE,
     87   1.1  christos   OPTION_GSTABSPACKING,
     88   1.1  christos   OPTION_NOGSTABSPACKING
     89   1.1  christos };
     90   1.1  christos 
     91  1.10  christos const struct option md_longopts[] =
     92   1.1  christos {
     93   1.1  christos   {"nowarnswap", no_argument, NULL, OPTION_NOWARNSWAP},
     94   1.1  christos   {"gstabspacking",  no_argument, NULL, OPTION_GSTABSPACKING},
     95   1.1  christos   {"gstabs-packing", no_argument, NULL, OPTION_GSTABSPACKING},
     96   1.1  christos   {"nogstabspacking",   no_argument, NULL, OPTION_NOGSTABSPACKING},
     97   1.1  christos   {"no-gstabs-packing", no_argument, NULL, OPTION_NOGSTABSPACKING},
     98   1.1  christos   {NULL, no_argument, NULL, 0}
     99   1.1  christos };
    100   1.1  christos 
    101  1.10  christos const size_t md_longopts_size = sizeof (md_longopts);
    102   1.1  christos 
    103   1.1  christos /* Opcode hash table.  */
    104   1.8  christos static htab_t d10v_hash;
    105   1.1  christos 
    106   1.1  christos /* Do a binary search of the d10v_predefined_registers array to see if
    107   1.6  christos    NAME is a valid register name.  Return the register number from the
    108   1.1  christos    array on success, or -1 on failure.  */
    109   1.1  christos 
    110   1.1  christos static int
    111   1.1  christos reg_name_search (char *name)
    112   1.1  christos {
    113   1.1  christos   int middle, low, high;
    114   1.1  christos   int cmp;
    115   1.1  christos 
    116   1.1  christos   low = 0;
    117   1.1  christos   high = d10v_reg_name_cnt () - 1;
    118   1.1  christos 
    119   1.1  christos   do
    120   1.1  christos     {
    121   1.1  christos       middle = (low + high) / 2;
    122   1.1  christos       cmp = strcasecmp (name, d10v_predefined_registers[middle].name);
    123   1.1  christos       if (cmp < 0)
    124   1.1  christos 	high = middle - 1;
    125   1.1  christos       else if (cmp > 0)
    126   1.1  christos 	low = middle + 1;
    127   1.1  christos       else
    128   1.1  christos 	return d10v_predefined_registers[middle].value;
    129   1.1  christos     }
    130   1.1  christos   while (low <= high);
    131   1.1  christos   return -1;
    132   1.1  christos }
    133   1.1  christos 
    134   1.1  christos /* Check the string at input_line_pointer
    135   1.1  christos    to see if it is a valid register name.  */
    136   1.1  christos 
    137   1.1  christos static int
    138   1.1  christos register_name (expressionS *expressionP)
    139   1.1  christos {
    140   1.1  christos   int reg_number;
    141   1.1  christos   char c, *p = input_line_pointer;
    142   1.1  christos 
    143  1.10  christos   while (!is_end_of_stmt (*p) && *p != ',' && !is_whitespace (*p) && *p != ')')
    144   1.1  christos     p++;
    145   1.1  christos 
    146   1.1  christos   c = *p;
    147   1.1  christos   if (c)
    148   1.1  christos     *p++ = 0;
    149   1.1  christos 
    150   1.1  christos   /* Look to see if it's in the register table.  */
    151   1.1  christos   reg_number = reg_name_search (input_line_pointer);
    152   1.1  christos   if (reg_number >= 0)
    153   1.1  christos     {
    154   1.1  christos       expressionP->X_op = O_register;
    155   1.1  christos       /* Temporarily store a pointer to the string here.  */
    156   1.1  christos       expressionP->X_op_symbol = (symbolS *) input_line_pointer;
    157   1.1  christos       expressionP->X_add_number = reg_number;
    158   1.1  christos       input_line_pointer = p;
    159   1.1  christos       return 1;
    160   1.1  christos     }
    161   1.1  christos   if (c)
    162   1.1  christos     *(p - 1) = c;
    163   1.1  christos   return 0;
    164   1.1  christos }
    165   1.1  christos 
    166   1.1  christos static int
    167   1.1  christos check_range (unsigned long num, int bits, int flags)
    168   1.1  christos {
    169   1.1  christos   long min, max;
    170   1.1  christos   int retval = 0;
    171   1.1  christos 
    172   1.1  christos   /* Don't bother checking 16-bit values.  */
    173   1.1  christos   if (bits == 16)
    174   1.1  christos     return 0;
    175   1.1  christos 
    176   1.1  christos   if (flags & OPERAND_SHIFT)
    177   1.1  christos     {
    178   1.1  christos       /* All special shift operands are unsigned and <= 16.
    179   1.1  christos 	 We allow 0 for now.  */
    180   1.1  christos       if (num > 16)
    181   1.1  christos 	return 1;
    182   1.1  christos       else
    183   1.1  christos 	return 0;
    184   1.1  christos     }
    185   1.1  christos 
    186   1.1  christos   if (flags & OPERAND_SIGNED)
    187   1.1  christos     {
    188   1.1  christos       /* Signed 3-bit integers are restricted to the (-2, 3) range.  */
    189   1.1  christos       if (flags & RESTRICTED_NUM3)
    190   1.1  christos 	{
    191   1.1  christos 	  if ((long) num < -2 || (long) num > 3)
    192   1.1  christos 	    retval = 1;
    193   1.1  christos 	}
    194   1.1  christos       else
    195   1.1  christos 	{
    196   1.1  christos 	  max = (1 << (bits - 1)) - 1;
    197   1.1  christos 	  min = - (1 << (bits - 1));
    198   1.1  christos 	  if (((long) num > max) || ((long) num < min))
    199   1.1  christos 	    retval = 1;
    200   1.1  christos 	}
    201   1.1  christos     }
    202   1.1  christos   else
    203   1.1  christos     {
    204   1.1  christos       max = (1 << bits) - 1;
    205   1.1  christos       min = 0;
    206   1.1  christos       if (((long) num > max) || ((long) num < min))
    207   1.1  christos 	retval = 1;
    208   1.1  christos     }
    209   1.1  christos   return retval;
    210   1.1  christos }
    211   1.1  christos 
    212   1.1  christos void
    213   1.1  christos md_show_usage (FILE *stream)
    214   1.1  christos {
    215   1.1  christos   fprintf (stream, _("D10V options:\n\
    216   1.1  christos -O                      Optimize.  Will do some operations in parallel.\n\
    217   1.1  christos --gstabs-packing        Pack adjacent short instructions together even\n\
    218   1.1  christos                         when --gstabs is specified.  On by default.\n\
    219   1.1  christos --no-gstabs-packing     If --gstabs is specified, do not pack adjacent\n\
    220   1.1  christos                         instructions together.\n"));
    221   1.1  christos }
    222   1.1  christos 
    223   1.1  christos int
    224   1.5  christos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
    225   1.1  christos {
    226   1.1  christos   switch (c)
    227   1.1  christos     {
    228   1.1  christos     case 'O':
    229   1.1  christos       /* Optimize. Will attempt to parallelize operations.  */
    230   1.1  christos       Optimizing = 1;
    231   1.1  christos       break;
    232   1.1  christos     case OPTION_NOWARNSWAP:
    233   1.1  christos       flag_warn_suppress_instructionswap = 1;
    234   1.1  christos       break;
    235   1.1  christos     case OPTION_GSTABSPACKING:
    236   1.1  christos       flag_allow_gstabs_packing = 1;
    237   1.1  christos       break;
    238   1.1  christos     case OPTION_NOGSTABSPACKING:
    239   1.1  christos       flag_allow_gstabs_packing = 0;
    240   1.1  christos       break;
    241   1.1  christos     default:
    242   1.1  christos       return 0;
    243   1.1  christos     }
    244   1.1  christos   return 1;
    245   1.1  christos }
    246   1.1  christos 
    247   1.1  christos symbolS *
    248   1.1  christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
    249   1.1  christos {
    250   1.1  christos   return 0;
    251   1.1  christos }
    252   1.1  christos 
    253   1.5  christos const char *
    254   1.1  christos md_atof (int type, char *litP, int *sizeP)
    255   1.1  christos {
    256   1.8  christos   return ieee_md_atof (type, litP, sizeP, true);
    257   1.1  christos }
    258   1.1  christos 
    259   1.1  christos void
    260   1.1  christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
    261   1.1  christos 		 asection *sec ATTRIBUTE_UNUSED,
    262   1.1  christos 		 fragS *fragP ATTRIBUTE_UNUSED)
    263   1.1  christos {
    264   1.1  christos   abort ();
    265   1.1  christos }
    266   1.1  christos 
    267   1.1  christos valueT
    268   1.1  christos md_section_align (asection *seg, valueT addr)
    269   1.1  christos {
    270   1.7  christos   int align = bfd_section_alignment (seg);
    271   1.3  christos   return ((addr + (1 << align) - 1) & -(1 << align));
    272   1.1  christos }
    273   1.1  christos 
    274   1.1  christos void
    275   1.1  christos md_begin (void)
    276   1.1  christos {
    277   1.5  christos   const char *prev_name = "";
    278  1.10  christos   const struct d10v_opcode *opcode;
    279   1.8  christos   d10v_hash = str_htab_create ();
    280   1.1  christos 
    281   1.1  christos   /* Insert unique names into hash table.  The D10v instruction set
    282   1.1  christos      has many identical opcode names that have different opcodes based
    283   1.1  christos      on the operands.  This hash table then provides a quick index to
    284   1.1  christos      the first opcode with a particular name in the opcode table.  */
    285   1.1  christos 
    286  1.10  christos   for (opcode = d10v_opcodes; opcode->name; opcode++)
    287   1.1  christos     {
    288   1.1  christos       if (strcmp (prev_name, opcode->name))
    289   1.1  christos 	{
    290  1.10  christos 	  prev_name = opcode->name;
    291   1.8  christos 	  str_hash_insert (d10v_hash, opcode->name, opcode, 0);
    292   1.1  christos 	}
    293   1.1  christos     }
    294   1.1  christos 
    295   1.1  christos   fixups = &FixUps[0];
    296   1.1  christos   FixUps[0].next = &FixUps[1];
    297   1.1  christos   FixUps[1].next = &FixUps[0];
    298   1.1  christos }
    299   1.1  christos 
    300   1.1  christos /* Remove the postincrement or postdecrement operator ( '+' or '-' )
    301   1.1  christos    from an expression.  */
    302   1.1  christos 
    303   1.1  christos static int
    304   1.1  christos postfix (char *p)
    305   1.1  christos {
    306   1.1  christos   while (*p != '-' && *p != '+')
    307   1.1  christos     {
    308   1.1  christos       if (*p == 0 || *p == '\n' || *p == '\r')
    309   1.1  christos 	break;
    310   1.1  christos       p++;
    311   1.1  christos     }
    312   1.1  christos 
    313   1.1  christos   if (*p == '-')
    314   1.1  christos     {
    315   1.1  christos       *p = ' ';
    316   1.1  christos       return -1;
    317   1.1  christos     }
    318   1.1  christos   if (*p == '+')
    319   1.1  christos     {
    320   1.1  christos       *p = ' ';
    321   1.1  christos       return 1;
    322   1.1  christos     }
    323   1.1  christos 
    324   1.1  christos   return 0;
    325   1.1  christos }
    326   1.1  christos 
    327   1.1  christos static bfd_reloc_code_real_type
    328  1.10  christos get_reloc (const struct d10v_operand *op)
    329   1.1  christos {
    330   1.1  christos   int bits = op->bits;
    331   1.1  christos 
    332   1.1  christos   if (bits <= 4)
    333   1.1  christos     return 0;
    334   1.1  christos 
    335   1.1  christos   if (op->flags & OPERAND_ADDR)
    336   1.1  christos     {
    337   1.1  christos       if (bits == 8)
    338   1.1  christos 	return BFD_RELOC_D10V_10_PCREL_R;
    339   1.1  christos       else
    340   1.1  christos 	return BFD_RELOC_D10V_18_PCREL;
    341   1.1  christos     }
    342   1.1  christos 
    343   1.1  christos   return BFD_RELOC_16;
    344   1.1  christos }
    345   1.1  christos 
    346   1.1  christos /* Parse a string of operands.  Return an array of expressions.  */
    347   1.1  christos 
    348   1.1  christos static int
    349   1.1  christos get_operands (expressionS exp[])
    350   1.1  christos {
    351   1.1  christos   char *p = input_line_pointer;
    352   1.1  christos   int numops = 0;
    353   1.1  christos   int post = 0;
    354   1.1  christos   int uses_at = 0;
    355   1.1  christos 
    356   1.1  christos   while (*p)
    357   1.1  christos     {
    358  1.10  christos       while (is_whitespace (*p) || *p == ',')
    359   1.1  christos 	p++;
    360  1.10  christos       if (is_end_of_stmt (*p))
    361   1.1  christos 	break;
    362   1.1  christos 
    363   1.1  christos       if (*p == '@')
    364   1.1  christos 	{
    365   1.1  christos 	  uses_at = 1;
    366   1.1  christos 
    367   1.1  christos 	  p++;
    368   1.1  christos 	  exp[numops].X_op = O_absent;
    369   1.1  christos 	  if (*p == '(')
    370   1.1  christos 	    {
    371   1.1  christos 	      p++;
    372   1.1  christos 	      exp[numops].X_add_number = OPERAND_ATPAR;
    373   1.1  christos 	    }
    374   1.1  christos 	  else if (*p == '-')
    375   1.1  christos 	    {
    376   1.1  christos 	      p++;
    377   1.1  christos 	      exp[numops].X_add_number = OPERAND_ATMINUS;
    378   1.1  christos 	    }
    379   1.1  christos 	  else
    380   1.1  christos 	    {
    381   1.1  christos 	      exp[numops].X_add_number = OPERAND_ATSIGN;
    382   1.1  christos 	      if (*p == '+')
    383   1.1  christos 		{
    384   1.1  christos 		  numops++;
    385   1.1  christos 		  exp[numops].X_op = O_absent;
    386   1.1  christos 		  exp[numops].X_add_number = OPERAND_PLUS;
    387   1.1  christos 		  p++;
    388   1.1  christos 		}
    389   1.1  christos 	      post = postfix (p);
    390   1.1  christos 	    }
    391   1.1  christos 	  numops++;
    392   1.1  christos 	  continue;
    393   1.1  christos 	}
    394   1.1  christos 
    395   1.1  christos       if (*p == ')')
    396   1.1  christos 	{
    397   1.1  christos 	  /* Just skip the trailing paren.  */
    398   1.1  christos 	  p++;
    399   1.1  christos 	  continue;
    400   1.1  christos 	}
    401   1.1  christos 
    402   1.1  christos       input_line_pointer = p;
    403   1.1  christos 
    404   1.1  christos       /* Check to see if it might be a register name.  */
    405   1.1  christos       if (!register_name (&exp[numops]))
    406   1.1  christos 	{
    407   1.1  christos 	  /* Parse as an expression.  */
    408   1.1  christos 	  if (uses_at)
    409   1.1  christos 	    {
    410   1.1  christos 	      /* Any expression that involves the indirect addressing
    411   1.1  christos 		 cannot also involve immediate addressing.  Therefore
    412   1.1  christos 		 the use of the hash character is illegal.  */
    413   1.1  christos 	      int save = do_not_ignore_hash;
    414   1.1  christos 	      do_not_ignore_hash = 1;
    415   1.1  christos 
    416   1.1  christos 	      expression (&exp[numops]);
    417   1.1  christos 
    418   1.1  christos 	      do_not_ignore_hash = save;
    419   1.1  christos 	    }
    420   1.1  christos 	  else
    421   1.1  christos 	    expression (&exp[numops]);
    422   1.1  christos 	}
    423   1.1  christos 
    424   1.1  christos       if (strncasecmp (input_line_pointer, "@word", 5) == 0)
    425   1.1  christos 	{
    426   1.1  christos 	  input_line_pointer += 5;
    427   1.1  christos 	  if (exp[numops].X_op == O_register)
    428   1.1  christos 	    {
    429   1.1  christos 	      /* If it looked like a register name but was followed by
    430   1.1  christos                  "@word" then it was really a symbol, so change it to
    431   1.1  christos                  one.  */
    432   1.1  christos 	      exp[numops].X_op = O_symbol;
    433   1.1  christos 	      exp[numops].X_add_symbol =
    434   1.1  christos 		symbol_find_or_make ((char *) exp[numops].X_op_symbol);
    435   1.1  christos 	    }
    436   1.1  christos 
    437   1.1  christos 	  /* Check for identifier@word+constant.  */
    438   1.1  christos 	  if (*input_line_pointer == '-' || *input_line_pointer == '+')
    439   1.1  christos 	    {
    440   1.1  christos 	      expressionS new_exp;
    441   1.1  christos 	      expression (&new_exp);
    442   1.1  christos 	      exp[numops].X_add_number = new_exp.X_add_number;
    443   1.1  christos 	    }
    444   1.1  christos 
    445   1.1  christos 	  /* Convert expr into a right shift by AT_WORD_RIGHT_SHIFT.  */
    446   1.1  christos 	  {
    447   1.1  christos 	    expressionS new_exp;
    448   1.1  christos 	    memset (&new_exp, 0, sizeof new_exp);
    449   1.1  christos 	    new_exp.X_add_number = AT_WORD_RIGHT_SHIFT;
    450   1.1  christos 	    new_exp.X_op = O_constant;
    451   1.1  christos 	    new_exp.X_unsigned = 1;
    452   1.1  christos 	    exp[numops].X_op_symbol = make_expr_symbol (&new_exp);
    453   1.1  christos 	    exp[numops].X_op = O_right_shift;
    454   1.1  christos 	  }
    455   1.1  christos 
    456   1.1  christos 	  know (AT_WORD_P (&exp[numops]));
    457   1.1  christos 	}
    458   1.1  christos 
    459   1.1  christos       if (exp[numops].X_op == O_illegal)
    460   1.1  christos 	as_bad (_("illegal operand"));
    461   1.1  christos       else if (exp[numops].X_op == O_absent)
    462   1.1  christos 	as_bad (_("missing operand"));
    463   1.1  christos 
    464   1.1  christos       numops++;
    465   1.1  christos       p = input_line_pointer;
    466   1.1  christos     }
    467   1.1  christos 
    468   1.1  christos   switch (post)
    469   1.1  christos     {
    470   1.1  christos     case -1:	/* Postdecrement mode.  */
    471   1.1  christos       exp[numops].X_op = O_absent;
    472   1.1  christos       exp[numops++].X_add_number = OPERAND_MINUS;
    473   1.1  christos       break;
    474   1.1  christos     case 1:	/* Postincrement mode.  */
    475   1.1  christos       exp[numops].X_op = O_absent;
    476   1.1  christos       exp[numops++].X_add_number = OPERAND_PLUS;
    477   1.1  christos       break;
    478   1.1  christos     }
    479   1.1  christos 
    480   1.1  christos   exp[numops].X_op = 0;
    481   1.1  christos   return numops;
    482   1.1  christos }
    483   1.1  christos 
    484   1.1  christos static unsigned long
    485   1.1  christos d10v_insert_operand (unsigned long insn,
    486   1.1  christos 		     int op_type,
    487   1.1  christos 		     offsetT value,
    488   1.1  christos 		     int left,
    489   1.1  christos 		     fixS *fix)
    490   1.1  christos {
    491   1.1  christos   int shift, bits;
    492   1.1  christos 
    493   1.1  christos   shift = d10v_operands[op_type].shift;
    494   1.1  christos   if (left)
    495   1.1  christos     shift += 15;
    496   1.1  christos 
    497   1.1  christos   bits = d10v_operands[op_type].bits;
    498   1.1  christos 
    499   1.1  christos   /* Truncate to the proper number of bits.  */
    500   1.1  christos   if (check_range (value, bits, d10v_operands[op_type].flags))
    501   1.1  christos     as_bad_where (fix->fx_file, fix->fx_line,
    502   1.1  christos 		  _("operand out of range: %ld"), (long) value);
    503   1.1  christos 
    504   1.1  christos   value &= 0x7FFFFFFF >> (31 - bits);
    505   1.1  christos   insn |= (value << shift);
    506   1.1  christos 
    507   1.1  christos   return insn;
    508   1.1  christos }
    509   1.1  christos 
    510   1.1  christos /* Take a pointer to the opcode entry in the opcode table and the
    511   1.1  christos    array of operand expressions.  Return the instruction.  */
    512   1.1  christos 
    513   1.1  christos static unsigned long
    514   1.1  christos build_insn (struct d10v_opcode *opcode,
    515   1.1  christos 	    expressionS *opers,
    516   1.1  christos 	    unsigned long insn)
    517   1.1  christos {
    518   1.1  christos   int i, bits, shift, flags, format;
    519   1.1  christos   unsigned long number;
    520   1.1  christos 
    521   1.1  christos   /* The insn argument is only used for the DIVS kludge.  */
    522   1.1  christos   if (insn)
    523   1.1  christos     format = LONG_R;
    524   1.1  christos   else
    525   1.1  christos     {
    526   1.1  christos       insn = opcode->opcode;
    527   1.1  christos       format = opcode->format;
    528   1.1  christos     }
    529   1.1  christos 
    530   1.1  christos   for (i = 0; opcode->operands[i]; i++)
    531   1.1  christos     {
    532   1.1  christos       flags = d10v_operands[opcode->operands[i]].flags;
    533   1.1  christos       bits = d10v_operands[opcode->operands[i]].bits;
    534   1.1  christos       shift = d10v_operands[opcode->operands[i]].shift;
    535   1.1  christos       number = opers[i].X_add_number;
    536   1.1  christos 
    537   1.1  christos       if (flags & OPERAND_REG)
    538   1.1  christos 	{
    539   1.1  christos 	  number &= REGISTER_MASK;
    540   1.1  christos 	  if (format == LONG_L)
    541   1.1  christos 	    shift += 15;
    542   1.1  christos 	}
    543   1.1  christos 
    544   1.1  christos       if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
    545   1.1  christos 	{
    546   1.1  christos 	  /* Now create a fixup.  */
    547   1.1  christos 
    548   1.1  christos 	  if (fixups->fc >= MAX_INSN_FIXUPS)
    549   1.1  christos 	    as_fatal (_("too many fixups"));
    550   1.1  christos 
    551   1.1  christos 	  if (AT_WORD_P (&opers[i]))
    552   1.1  christos 	    {
    553   1.1  christos 	      /* Recognize XXX>>1+N aka XXX@word+N as special (AT_WORD).  */
    554   1.1  christos 	      fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18;
    555   1.1  christos 	      opers[i].X_op = O_symbol;
    556   1.1  christos 	      opers[i].X_op_symbol = NULL; /* Should free it.  */
    557   1.1  christos 	      /* number is left shifted by AT_WORD_RIGHT_SHIFT so
    558   1.1  christos                  that, it is aligned with the symbol's value.  Later,
    559   1.1  christos                  BFD_RELOC_D10V_18 will right shift (symbol_value +
    560   1.1  christos                  X_add_number).  */
    561   1.1  christos 	      number <<= AT_WORD_RIGHT_SHIFT;
    562   1.1  christos 	      opers[i].X_add_number = number;
    563   1.1  christos 	    }
    564   1.1  christos 	  else
    565   1.1  christos 	    {
    566   1.1  christos 	      fixups->fix[fixups->fc].reloc =
    567  1.10  christos 		get_reloc (&d10v_operands[opcode->operands[i]]);
    568   1.1  christos 
    569   1.1  christos 	      /* Check that an immediate was passed to ops that expect one.  */
    570   1.1  christos 	      if ((flags & OPERAND_NUM)
    571   1.1  christos 		  && (fixups->fix[fixups->fc].reloc == 0))
    572   1.1  christos 		as_bad (_("operand is not an immediate"));
    573   1.1  christos 	    }
    574   1.1  christos 
    575   1.1  christos 	  if (fixups->fix[fixups->fc].reloc == BFD_RELOC_16 ||
    576   1.1  christos 	      fixups->fix[fixups->fc].reloc == BFD_RELOC_D10V_18)
    577   1.1  christos 	    fixups->fix[fixups->fc].size = 2;
    578   1.1  christos 	  else
    579   1.1  christos 	    fixups->fix[fixups->fc].size = 4;
    580   1.1  christos 
    581   1.1  christos 	  fixups->fix[fixups->fc].exp = opers[i];
    582   1.1  christos 	  fixups->fix[fixups->fc].operand = opcode->operands[i];
    583   1.8  christos 	  fixups->fix[fixups->fc].pcrel = (flags & OPERAND_ADDR) != 0;
    584   1.1  christos 	  (fixups->fc)++;
    585   1.1  christos 	}
    586   1.1  christos 
    587   1.1  christos       /* Truncate to the proper number of bits.  */
    588   1.1  christos       if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
    589   1.1  christos 	as_bad (_("operand out of range: %lu"), number);
    590   1.1  christos       number &= 0x7FFFFFFF >> (31 - bits);
    591   1.1  christos       insn = insn | (number << shift);
    592   1.1  christos     }
    593   1.1  christos 
    594   1.1  christos   /* kludge: for DIVS, we need to put the operands in twice on the second
    595   1.1  christos      pass, format is changed to LONG_R to force the second set of operands
    596   1.1  christos      to not be shifted over 15.  */
    597   1.1  christos   if ((opcode->opcode == OPCODE_DIVS) && (format == LONG_L))
    598   1.1  christos     insn = build_insn (opcode, opers, insn);
    599   1.1  christos 
    600   1.1  christos   return insn;
    601   1.1  christos }
    602   1.1  christos 
    603   1.1  christos /* Write out a long form instruction.  */
    604   1.1  christos 
    605   1.1  christos static void
    606   1.1  christos write_long (unsigned long insn, Fixups *fx)
    607   1.1  christos {
    608   1.1  christos   int i, where;
    609   1.1  christos   char *f = frag_more (4);
    610   1.1  christos 
    611   1.1  christos   dwarf2_emit_insn (4);
    612   1.1  christos   insn |= FM11;
    613   1.1  christos   number_to_chars_bigendian (f, insn, 4);
    614   1.1  christos 
    615   1.1  christos   for (i = 0; i < fx->fc; i++)
    616   1.1  christos     {
    617   1.1  christos       if (fx->fix[i].reloc)
    618   1.1  christos 	{
    619   1.1  christos 	  where = f - frag_now->fr_literal;
    620   1.1  christos 	  if (fx->fix[i].size == 2)
    621   1.1  christos 	    where += 2;
    622   1.1  christos 
    623   1.1  christos 	  if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
    624   1.1  christos 	    fx->fix[i].operand |= 4096;
    625   1.1  christos 
    626   1.1  christos 	  fix_new_exp (frag_now,
    627   1.1  christos 		       where,
    628   1.1  christos 		       fx->fix[i].size,
    629   1.1  christos 		       &(fx->fix[i].exp),
    630   1.1  christos 		       fx->fix[i].pcrel,
    631   1.1  christos 		       fx->fix[i].operand|2048);
    632   1.1  christos 	}
    633   1.1  christos     }
    634   1.1  christos   fx->fc = 0;
    635   1.1  christos }
    636   1.1  christos 
    637   1.1  christos /* Write out a short form instruction by itself.  */
    638   1.1  christos 
    639   1.1  christos static void
    640   1.1  christos write_1_short (struct d10v_opcode *opcode,
    641   1.1  christos 	       unsigned long insn,
    642   1.1  christos 	       Fixups *fx)
    643   1.1  christos {
    644   1.1  christos   char *f = frag_more (4);
    645   1.1  christos   int i, where;
    646   1.1  christos 
    647   1.1  christos   dwarf2_emit_insn (4);
    648   1.1  christos   if (opcode->exec_type & PARONLY)
    649   1.1  christos     as_fatal (_("Instruction must be executed in parallel with another instruction."));
    650   1.1  christos 
    651   1.1  christos   /* The other container needs to be NOP.
    652   1.1  christos      According to 4.3.1: for FM=00, sub-instructions performed only by IU
    653   1.1  christos      cannot be encoded in L-container.  */
    654   1.1  christos   if (opcode->unit == IU)
    655   1.1  christos     insn |= FM00 | (NOP << 15);		/* Right container.  */
    656   1.1  christos   else
    657   1.1  christos     insn = FM00 | (insn << 15) | NOP;	/* Left container.  */
    658   1.1  christos 
    659   1.1  christos   number_to_chars_bigendian (f, insn, 4);
    660   1.1  christos   for (i = 0; i < fx->fc; i++)
    661   1.1  christos     {
    662   1.1  christos       if (fx->fix[i].reloc)
    663   1.1  christos 	{
    664   1.1  christos 	  where = f - frag_now->fr_literal;
    665   1.1  christos 	  if (fx->fix[i].size == 2)
    666   1.1  christos 	    where += 2;
    667   1.1  christos 
    668   1.1  christos 	  if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
    669   1.1  christos 	    fx->fix[i].operand |= 4096;
    670   1.1  christos 
    671   1.1  christos 	  /* If it's an R reloc, we may have to switch it to L.  */
    672   1.1  christos 	  if ((fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R)
    673   1.1  christos 	      && (opcode->unit != IU))
    674   1.1  christos 	    fx->fix[i].operand |= 1024;
    675   1.1  christos 
    676   1.1  christos 	  fix_new_exp (frag_now,
    677   1.1  christos 		       where,
    678   1.1  christos 		       fx->fix[i].size,
    679   1.1  christos 		       &(fx->fix[i].exp),
    680   1.1  christos 		       fx->fix[i].pcrel,
    681   1.1  christos 		       fx->fix[i].operand|2048);
    682   1.1  christos 	}
    683   1.1  christos     }
    684   1.1  christos   fx->fc = 0;
    685   1.1  christos }
    686   1.1  christos 
    687   1.1  christos /* Determine if there are any resource conflicts among two manually
    688   1.1  christos    parallelized instructions.  Some of this was lifted from parallel_ok.  */
    689   1.1  christos 
    690   1.1  christos static void
    691   1.1  christos check_resource_conflict (struct d10v_opcode *op1,
    692   1.1  christos 			 unsigned long insn1,
    693   1.1  christos 			 struct d10v_opcode *op2,
    694   1.1  christos 			 unsigned long insn2)
    695   1.1  christos {
    696   1.1  christos   int i, j, flags, mask, shift, regno;
    697   1.1  christos   unsigned long ins, mod[2];
    698   1.1  christos   struct d10v_opcode *op;
    699   1.1  christos 
    700   1.1  christos   if ((op1->exec_type & SEQ)
    701   1.1  christos       || ! ((op1->exec_type & PAR) || (op1->exec_type & PARONLY)))
    702   1.1  christos     {
    703   1.1  christos       as_warn (_("packing conflict: %s must dispatch sequentially"),
    704   1.1  christos 	      op1->name);
    705   1.1  christos       return;
    706   1.1  christos     }
    707   1.1  christos 
    708   1.1  christos   if ((op2->exec_type & SEQ)
    709   1.1  christos       || ! ((op2->exec_type & PAR) || (op2->exec_type & PARONLY)))
    710   1.1  christos     {
    711   1.1  christos       as_warn (_("packing conflict: %s must dispatch sequentially"),
    712   1.1  christos 	      op2->name);
    713   1.1  christos       return;
    714   1.1  christos     }
    715   1.1  christos 
    716   1.1  christos    /* See if both instructions write to the same resource.
    717   1.1  christos 
    718   1.1  christos       The idea here is to create two sets of bitmasks (mod and used) which
    719   1.1  christos       indicate which registers are modified or used by each instruction.
    720   1.1  christos       The operation can only be done in parallel if neither instruction
    721   1.1  christos       modifies the same register. Accesses to control registers and memory
    722   1.1  christos       are treated as accesses to a single register. So if both instructions
    723   1.1  christos       write memory or if the first instruction writes memory and the second
    724   1.1  christos       reads, then they cannot be done in parallel. We treat reads to the PSW
    725   1.1  christos       (which includes C, F0, and F1) in isolation. So simultaneously writing
    726   1.1  christos       C and F0 in two different sub-instructions is permitted.  */
    727   1.1  christos 
    728   1.1  christos   /* The bitmasks (mod and used) look like this (bit 31 = MSB).
    729   1.1  christos      r0-r15	  0-15
    730   1.1  christos      a0-a1	  16-17
    731   1.1  christos      cr (not psw) 18
    732   1.1  christos      psw(other)   19
    733   1.1  christos      mem	  20
    734   1.1  christos      psw(C flag)  21
    735   1.1  christos      psw(F0 flag) 22  */
    736   1.1  christos 
    737   1.1  christos   for (j = 0; j < 2; j++)
    738   1.1  christos     {
    739   1.1  christos       if (j == 0)
    740   1.1  christos 	{
    741   1.1  christos 	  op = op1;
    742   1.1  christos 	  ins = insn1;
    743   1.1  christos 	}
    744   1.1  christos       else
    745   1.1  christos 	{
    746   1.1  christos 	  op = op2;
    747   1.1  christos 	  ins = insn2;
    748   1.1  christos 	}
    749   1.1  christos       mod[j] = 0;
    750   1.1  christos       if (op->exec_type & BRANCH_LINK)
    751   1.1  christos 	mod[j] |= 1 << 13;
    752   1.1  christos 
    753   1.1  christos       for (i = 0; op->operands[i]; i++)
    754   1.1  christos 	{
    755   1.1  christos 	  flags = d10v_operands[op->operands[i]].flags;
    756   1.1  christos 	  shift = d10v_operands[op->operands[i]].shift;
    757   1.1  christos 	  mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
    758   1.1  christos 	  if (flags & OPERAND_REG)
    759   1.1  christos 	    {
    760   1.1  christos 	      regno = (ins >> shift) & mask;
    761   1.1  christos 	      if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
    762   1.1  christos 		regno += 16;
    763   1.1  christos 	      else if (flags & OPERAND_CONTROL)	/* mvtc or mvfc */
    764   1.1  christos 		{
    765   1.1  christos 		  if (regno == 0)
    766   1.1  christos 		    regno = 19;
    767   1.1  christos 		  else
    768   1.1  christos 		    regno = 18;
    769   1.1  christos 		}
    770   1.1  christos 	      else if (flags & OPERAND_FFLAG)
    771   1.1  christos 		regno = 22;
    772   1.1  christos 	      else if (flags & OPERAND_CFLAG)
    773   1.1  christos 		regno = 21;
    774   1.1  christos 
    775   1.1  christos 	      if (flags & OPERAND_DEST
    776   1.1  christos 		  /* Auto inc/dec also modifies the register.  */
    777   1.1  christos 		  || (op->operands[i + 1] != 0
    778   1.1  christos 		      && (d10v_operands[op->operands[i + 1]].flags
    779   1.1  christos 			  & (OPERAND_PLUS | OPERAND_MINUS)) != 0))
    780   1.1  christos 		{
    781   1.1  christos 		  mod[j] |= 1 << regno;
    782   1.1  christos 		  if (flags & OPERAND_EVEN)
    783   1.1  christos 		    mod[j] |= 1 << (regno + 1);
    784   1.1  christos 		}
    785   1.1  christos 	    }
    786   1.1  christos 	  else if (flags & OPERAND_ATMINUS)
    787   1.1  christos 	    {
    788   1.1  christos 	      /* SP implicitly used/modified.  */
    789   1.1  christos 	      mod[j] |= 1 << 15;
    790   1.1  christos 	    }
    791   1.1  christos 	}
    792   1.1  christos 
    793   1.1  christos       if (op->exec_type & WMEM)
    794   1.1  christos 	mod[j] |= 1 << 20;
    795   1.1  christos       else if (op->exec_type & WF0)
    796   1.1  christos 	mod[j] |= 1 << 22;
    797   1.1  christos       else if (op->exec_type & WCAR)
    798   1.1  christos 	mod[j] |= 1 << 21;
    799   1.1  christos     }
    800   1.1  christos 
    801   1.1  christos   if ((mod[0] & mod[1]) == 0)
    802   1.1  christos     return;
    803   1.1  christos   else
    804   1.1  christos     {
    805   1.1  christos       unsigned long x;
    806   1.1  christos       x = mod[0] & mod[1];
    807   1.1  christos 
    808   1.1  christos       for (j = 0; j <= 15; j++)
    809   1.1  christos 	if (x & (1 << j))
    810   1.1  christos 	  as_warn (_("resource conflict (R%d)"), j);
    811   1.1  christos       for (j = 16; j <= 17; j++)
    812   1.1  christos 	if (x & (1 << j))
    813   1.1  christos 	  as_warn (_("resource conflict (A%d)"), j - 16);
    814   1.1  christos       if (x & (1 << 19))
    815   1.1  christos 	as_warn (_("resource conflict (PSW)"));
    816   1.1  christos       if (x & (1 << 21))
    817   1.1  christos 	as_warn (_("resource conflict (C flag)"));
    818   1.1  christos       if (x & (1 << 22))
    819   1.1  christos 	as_warn (_("resource conflict (F flag)"));
    820   1.1  christos     }
    821   1.1  christos }
    822   1.1  christos 
    823   1.1  christos /* Check 2 instructions and determine if they can be safely
    824   1.1  christos    executed in parallel.  Return 1 if they can be.  */
    825   1.1  christos 
    826   1.1  christos static int
    827   1.1  christos parallel_ok (struct d10v_opcode *op1,
    828   1.1  christos 	     unsigned long insn1,
    829   1.1  christos 	     struct d10v_opcode *op2,
    830   1.1  christos 	     unsigned long insn2,
    831   1.1  christos 	     packing_type exec_type)
    832   1.1  christos {
    833   1.1  christos   int i, j, flags, mask, shift, regno;
    834   1.1  christos   unsigned long ins, mod[2], used[2];
    835   1.1  christos   struct d10v_opcode *op;
    836   1.1  christos 
    837   1.1  christos   if ((op1->exec_type & SEQ) != 0 || (op2->exec_type & SEQ) != 0
    838   1.1  christos       || (op1->exec_type & PAR) == 0 || (op2->exec_type & PAR) == 0
    839   1.1  christos       || (op1->unit == BOTH) || (op2->unit == BOTH)
    840   1.1  christos       || (op1->unit == IU && op2->unit == IU)
    841   1.1  christos       || (op1->unit == MU && op2->unit == MU))
    842   1.1  christos     return 0;
    843   1.1  christos 
    844   1.1  christos   /* If this is auto parallelization, and the first instruction is a
    845   1.1  christos      branch or should not be packed, then don't parallelize.  */
    846   1.1  christos   if (exec_type == PACK_UNSPEC
    847   1.1  christos       && (op1->exec_type & (ALONE | BRANCH)))
    848   1.1  christos     return 0;
    849   1.1  christos 
    850   1.1  christos   /* The idea here is to create two sets of bitmasks (mod and used)
    851   1.1  christos      which indicate which registers are modified or used by each
    852   1.1  christos      instruction.  The operation can only be done in parallel if
    853   1.1  christos      instruction 1 and instruction 2 modify different registers, and
    854   1.1  christos      the first instruction does not modify registers that the second
    855   1.1  christos      is using (The second instruction can modify registers that the
    856   1.1  christos      first is using as they are only written back after the first
    857   1.1  christos      instruction has completed).  Accesses to control registers, PSW,
    858   1.1  christos      and memory are treated as accesses to a single register.  So if
    859   1.1  christos      both instructions write memory or if the first instruction writes
    860   1.1  christos      memory and the second reads, then they cannot be done in
    861   1.1  christos      parallel.  Likewise, if the first instruction mucks with the psw
    862   1.1  christos      and the second reads the PSW (which includes C, F0, and F1), then
    863   1.1  christos      they cannot operate safely in parallel.  */
    864   1.1  christos 
    865   1.1  christos   /* The bitmasks (mod and used) look like this (bit 31 = MSB).
    866   1.1  christos      r0-r15	  0-15
    867   1.1  christos      a0-a1	  16-17
    868   1.1  christos      cr (not psw) 18
    869   1.1  christos      psw	  19
    870   1.1  christos      mem	  20  */
    871   1.1  christos 
    872   1.1  christos   for (j = 0; j < 2; j++)
    873   1.1  christos     {
    874   1.1  christos       if (j == 0)
    875   1.1  christos 	{
    876   1.1  christos 	  op = op1;
    877   1.1  christos 	  ins = insn1;
    878   1.1  christos 	}
    879   1.1  christos       else
    880   1.1  christos 	{
    881   1.1  christos 	  op = op2;
    882   1.1  christos 	  ins = insn2;
    883   1.1  christos 	}
    884   1.1  christos       mod[j] = used[j] = 0;
    885   1.1  christos       if (op->exec_type & BRANCH_LINK)
    886   1.1  christos 	mod[j] |= 1 << 13;
    887   1.1  christos 
    888   1.1  christos       for (i = 0; op->operands[i]; i++)
    889   1.1  christos 	{
    890   1.1  christos 	  flags = d10v_operands[op->operands[i]].flags;
    891   1.1  christos 	  shift = d10v_operands[op->operands[i]].shift;
    892   1.1  christos 	  mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
    893   1.1  christos 	  if (flags & OPERAND_REG)
    894   1.1  christos 	    {
    895   1.1  christos 	      regno = (ins >> shift) & mask;
    896   1.1  christos 	      if (flags & (OPERAND_ACC0 | OPERAND_ACC1))
    897   1.1  christos 		regno += 16;
    898   1.1  christos 	      else if (flags & OPERAND_CONTROL)	/* mvtc or mvfc.  */
    899   1.1  christos 		{
    900   1.1  christos 		  if (regno == 0)
    901   1.1  christos 		    regno = 19;
    902   1.1  christos 		  else
    903   1.1  christos 		    regno = 18;
    904   1.1  christos 		}
    905   1.1  christos 	      else if (flags & (OPERAND_FFLAG | OPERAND_CFLAG))
    906   1.1  christos 		regno = 19;
    907   1.1  christos 
    908   1.1  christos 	      if (flags & OPERAND_DEST)
    909   1.1  christos 		{
    910   1.1  christos 		  mod[j] |= 1 << regno;
    911   1.1  christos 		  if (flags & OPERAND_EVEN)
    912   1.1  christos 		    mod[j] |= 1 << (regno + 1);
    913   1.1  christos 		}
    914   1.1  christos 	      else
    915   1.1  christos 		{
    916   1.1  christos 		  used[j] |= 1 << regno;
    917   1.1  christos 		  if (flags & OPERAND_EVEN)
    918   1.1  christos 		    used[j] |= 1 << (regno + 1);
    919   1.1  christos 
    920   1.1  christos 		  /* Auto inc/dec also modifies the register.  */
    921   1.1  christos 		  if (op->operands[i + 1] != 0
    922   1.1  christos 		      && (d10v_operands[op->operands[i + 1]].flags
    923   1.1  christos 			  & (OPERAND_PLUS | OPERAND_MINUS)) != 0)
    924   1.1  christos 		    mod[j] |= 1 << regno;
    925   1.1  christos 		}
    926   1.1  christos 	    }
    927   1.1  christos 	  else if (flags & OPERAND_ATMINUS)
    928   1.1  christos 	    {
    929   1.1  christos 	      /* SP implicitly used/modified.  */
    930   1.1  christos 	      mod[j] |= 1 << 15;
    931   1.1  christos 	      used[j] |= 1 << 15;
    932   1.1  christos 	    }
    933   1.1  christos 	}
    934   1.1  christos       if (op->exec_type & RMEM)
    935   1.1  christos 	used[j] |= 1 << 20;
    936   1.1  christos       else if (op->exec_type & WMEM)
    937   1.1  christos 	mod[j] |= 1 << 20;
    938   1.1  christos       else if (op->exec_type & RF0)
    939   1.1  christos 	used[j] |= 1 << 19;
    940   1.1  christos       else if (op->exec_type & WF0)
    941   1.1  christos 	mod[j] |= 1 << 19;
    942   1.1  christos       else if (op->exec_type & WCAR)
    943   1.1  christos 	mod[j] |= 1 << 19;
    944   1.1  christos     }
    945   1.1  christos   if ((mod[0] & mod[1]) == 0 && (mod[0] & used[1]) == 0)
    946   1.1  christos     return 1;
    947   1.1  christos   return 0;
    948   1.1  christos }
    949   1.1  christos 
    950   1.1  christos /* Expects two short instructions.
    951   1.1  christos    If possible, writes out both as a single packed instruction.
    952   1.1  christos    Otherwise, writes out the first one, packed with a NOP.
    953   1.1  christos    Returns number of instructions not written out.  */
    954   1.1  christos 
    955   1.1  christos static int
    956   1.1  christos write_2_short (struct d10v_opcode *opcode1,
    957   1.1  christos 	       unsigned long insn1,
    958   1.1  christos 	       struct d10v_opcode *opcode2,
    959   1.1  christos 	       unsigned long insn2,
    960   1.1  christos 	       packing_type exec_type,
    961   1.1  christos 	       Fixups *fx)
    962   1.1  christos {
    963   1.1  christos   unsigned long insn;
    964   1.1  christos   char *f;
    965   1.1  christos   int i, j, where;
    966   1.1  christos 
    967   1.1  christos   if ((exec_type != PACK_PARALLEL)
    968   1.1  christos       && ((opcode1->exec_type & PARONLY) || (opcode2->exec_type & PARONLY)))
    969   1.1  christos     as_fatal (_("Instruction must be executed in parallel"));
    970   1.1  christos 
    971   1.1  christos   if ((opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
    972   1.1  christos     as_fatal (_("Long instructions may not be combined."));
    973   1.1  christos 
    974   1.1  christos   switch (exec_type)
    975   1.1  christos     {
    976   1.1  christos     case PACK_UNSPEC:	/* Order not specified.  */
    977   1.1  christos       if (opcode1->exec_type & ALONE)
    978   1.1  christos 	{
    979   1.1  christos 	  /* Case of a short branch on a separate GAS line.  Pack with NOP.  */
    980   1.1  christos 	  write_1_short (opcode1, insn1, fx->next);
    981   1.1  christos 	  return 1;
    982   1.1  christos 	}
    983   1.1  christos       if (Optimizing
    984   1.1  christos 	  && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
    985   1.1  christos 	{
    986   1.1  christos 	  /* Parallel.  */
    987   1.1  christos 	  if (opcode1->unit == IU)
    988   1.1  christos 	    insn = FM00 | (insn2 << 15) | insn1;
    989   1.1  christos 	  else if (opcode2->unit == MU)
    990   1.1  christos 	    insn = FM00 | (insn2 << 15) | insn1;
    991   1.1  christos 	  else
    992   1.1  christos 	    insn = FM00 | (insn1 << 15) | insn2;
    993   1.1  christos 	}
    994   1.1  christos       else if (opcode1->unit == IU)
    995   1.1  christos 	/* Reverse sequential with IU opcode1 on right and done first.  */
    996   1.1  christos 	insn = FM10 | (insn2 << 15) | insn1;
    997   1.1  christos       else
    998   1.1  christos 	/* Sequential with non-IU opcode1 on left and done first.  */
    999   1.1  christos 	insn = FM01 | (insn1 << 15) | insn2;
   1000   1.1  christos       break;
   1001   1.1  christos 
   1002   1.1  christos     case PACK_PARALLEL:
   1003   1.1  christos       if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
   1004   1.1  christos 	as_fatal
   1005   1.1  christos 	  (_("One of these instructions may not be executed in parallel."));
   1006   1.1  christos       if (opcode1->unit == IU)
   1007   1.1  christos 	{
   1008   1.1  christos 	  if (opcode2->unit == IU)
   1009   1.1  christos 	    as_fatal (_("Two IU instructions may not be executed in parallel"));
   1010   1.1  christos 	  if (!flag_warn_suppress_instructionswap)
   1011   1.1  christos 	    as_warn (_("Swapping instruction order"));
   1012   1.1  christos 	  insn = FM00 | (insn2 << 15) | insn1;
   1013   1.1  christos 	}
   1014   1.1  christos       else if (opcode2->unit == MU)
   1015   1.1  christos 	{
   1016   1.1  christos 	  if (opcode1->unit == MU)
   1017   1.1  christos 	    as_fatal (_("Two MU instructions may not be executed in parallel"));
   1018   1.1  christos 	  if (!flag_warn_suppress_instructionswap)
   1019   1.1  christos 	    as_warn (_("Swapping instruction order"));
   1020   1.1  christos 	  insn = FM00 | (insn2 << 15) | insn1;
   1021   1.1  christos 	}
   1022   1.1  christos       else
   1023   1.1  christos 	insn = FM00 | (insn1 << 15) | insn2;
   1024   1.1  christos       check_resource_conflict (opcode1, insn1, opcode2, insn2);
   1025   1.1  christos       break;
   1026   1.1  christos 
   1027   1.1  christos     case PACK_LEFT_RIGHT:
   1028   1.1  christos       if (opcode1->unit != IU)
   1029   1.1  christos 	insn = FM01 | (insn1 << 15) | insn2;
   1030   1.1  christos       else if (opcode2->unit == MU || opcode2->unit == EITHER)
   1031   1.1  christos 	{
   1032   1.1  christos 	  if (!flag_warn_suppress_instructionswap)
   1033   1.1  christos 	    as_warn (_("Swapping instruction order"));
   1034   1.1  christos 	  insn = FM10 | (insn2 << 15) | insn1;
   1035   1.1  christos 	}
   1036   1.1  christos       else
   1037   1.1  christos 	as_fatal (_("IU instruction may not be in the left container"));
   1038   1.1  christos       if (opcode1->exec_type & ALONE)
   1039   1.1  christos 	as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
   1040   1.1  christos       break;
   1041   1.1  christos 
   1042   1.1  christos     case PACK_RIGHT_LEFT:
   1043   1.1  christos       if (opcode2->unit != MU)
   1044   1.1  christos 	insn = FM10 | (insn1 << 15) | insn2;
   1045   1.1  christos       else if (opcode1->unit == IU || opcode1->unit == EITHER)
   1046   1.1  christos 	{
   1047   1.1  christos 	  if (!flag_warn_suppress_instructionswap)
   1048   1.1  christos 	    as_warn (_("Swapping instruction order"));
   1049   1.1  christos 	  insn = FM01 | (insn2 << 15) | insn1;
   1050   1.1  christos 	}
   1051   1.1  christos       else
   1052   1.1  christos 	as_fatal (_("MU instruction may not be in the right container"));
   1053   1.1  christos       if (opcode2->exec_type & ALONE)
   1054   1.1  christos 	as_warn (_("Instruction in R container is squashed by flow control instruction in L container."));
   1055   1.1  christos       break;
   1056   1.1  christos 
   1057   1.1  christos     default:
   1058   1.1  christos       as_fatal (_("unknown execution type passed to write_2_short()"));
   1059   1.1  christos     }
   1060   1.1  christos 
   1061   1.1  christos   f = frag_more (4);
   1062   1.1  christos   dwarf2_emit_insn (4);
   1063   1.1  christos   number_to_chars_bigendian (f, insn, 4);
   1064   1.1  christos 
   1065   1.1  christos   /* Process fixup chains.  fx refers to insn2 when j == 0, and to
   1066   1.1  christos      insn1 when j == 1.  Yes, it's reversed.  */
   1067   1.1  christos 
   1068   1.1  christos   for (j = 0; j < 2; j++)
   1069   1.1  christos     {
   1070   1.1  christos       for (i = 0; i < fx->fc; i++)
   1071   1.1  christos 	{
   1072   1.1  christos 	  if (fx->fix[i].reloc)
   1073   1.1  christos 	    {
   1074   1.1  christos 	      where = f - frag_now->fr_literal;
   1075   1.1  christos 	      if (fx->fix[i].size == 2)
   1076   1.1  christos 		where += 2;
   1077   1.1  christos 
   1078   1.1  christos 	      if (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R
   1079   1.1  christos 		  /* A BFD_RELOC_D10V_10_PCREL_R relocation applied to
   1080   1.1  christos 		     the instruction in the L container has to be
   1081   1.1  christos 		     adjusted to BDF_RELOC_D10V_10_PCREL_L.  When
   1082   1.1  christos 		     j==0, we're processing insn2's operands, so we
   1083   1.1  christos 		     want to mark the operand if insn2 is *not* in the
   1084   1.1  christos 		     R container.  When j==1, we're processing insn1's
   1085   1.1  christos 		     operands, so we want to mark the operand if insn2
   1086   1.1  christos 		     *is* in the R container.  Note that, if two
   1087   1.1  christos 		     instructions are identical, we're never going to
   1088   1.1  christos 		     swap them, so the test is safe.  */
   1089   1.1  christos 		  && j == ((insn & 0x7fff) == insn2))
   1090   1.1  christos 		fx->fix[i].operand |= 1024;
   1091   1.1  christos 
   1092   1.1  christos 	      if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
   1093   1.1  christos 		fx->fix[i].operand |= 4096;
   1094   1.1  christos 
   1095   1.1  christos 	      fix_new_exp (frag_now,
   1096   1.1  christos 			   where,
   1097   1.1  christos 			   fx->fix[i].size,
   1098   1.1  christos 			   &(fx->fix[i].exp),
   1099   1.1  christos 			   fx->fix[i].pcrel,
   1100   1.1  christos 			   fx->fix[i].operand|2048);
   1101   1.1  christos 	    }
   1102   1.1  christos 	}
   1103   1.1  christos       fx->fc = 0;
   1104   1.1  christos       fx = fx->next;
   1105   1.1  christos     }
   1106   1.1  christos   return 0;
   1107   1.1  christos }
   1108   1.1  christos 
   1109   1.1  christos /* This is the main entry point for the machine-dependent assembler.
   1110   1.1  christos    str points to a machine-dependent instruction.  This function is
   1111   1.1  christos    supposed to emit the frags/bytes it assembles to.  For the D10V, it
   1112   1.1  christos    mostly handles the special VLIW parsing and packing and leaves the
   1113   1.1  christos    difficult stuff to do_assemble().  */
   1114   1.1  christos 
   1115   1.1  christos static unsigned long prev_insn;
   1116   1.1  christos static struct d10v_opcode *prev_opcode = 0;
   1117   1.1  christos static subsegT prev_subseg;
   1118   1.3  christos static segT prev_seg = 0;
   1119   1.1  christos 
   1120   1.1  christos /* Find the symbol which has the same name as the register in exp.  */
   1121   1.1  christos 
   1122   1.1  christos static symbolS *
   1123   1.1  christos find_symbol_matching_register (expressionS *exp)
   1124   1.1  christos {
   1125   1.1  christos   int i;
   1126   1.1  christos 
   1127   1.1  christos   if (exp->X_op != O_register)
   1128   1.1  christos     return NULL;
   1129   1.1  christos 
   1130   1.1  christos   /* Find the name of the register.  */
   1131   1.1  christos   for (i = d10v_reg_name_cnt (); i--;)
   1132   1.1  christos     if (d10v_predefined_registers[i].value == exp->X_add_number)
   1133   1.1  christos       break;
   1134   1.1  christos 
   1135   1.1  christos   if (i < 0)
   1136   1.1  christos     abort ();
   1137   1.1  christos 
   1138   1.1  christos   /* Now see if a symbol has been defined with the same name.  */
   1139   1.1  christos   return symbol_find (d10v_predefined_registers[i].name);
   1140   1.1  christos }
   1141   1.1  christos 
   1142   1.1  christos /* Get a pointer to an entry in the opcode table.
   1143   1.1  christos    The function must look at all opcodes with the same name and use
   1144   1.1  christos    the operands to choose the correct opcode.  */
   1145   1.1  christos 
   1146   1.1  christos static struct d10v_opcode *
   1147   1.1  christos find_opcode (struct d10v_opcode *opcode, expressionS myops[])
   1148   1.1  christos {
   1149   1.1  christos   int i, match;
   1150   1.1  christos   struct d10v_opcode *next_opcode;
   1151   1.1  christos 
   1152   1.1  christos   /* Get all the operands and save them as expressions.  */
   1153   1.1  christos   get_operands (myops);
   1154   1.1  christos 
   1155   1.1  christos   /* Now see if the operand is a fake.  If so, find the correct size
   1156   1.1  christos      instruction, if possible.  */
   1157   1.1  christos   if (opcode->format == OPCODE_FAKE)
   1158   1.1  christos     {
   1159   1.1  christos       int opnum = opcode->operands[0];
   1160   1.1  christos       int flags;
   1161   1.1  christos 
   1162   1.1  christos       if (myops[opnum].X_op == O_register)
   1163   1.1  christos 	{
   1164   1.1  christos 	  myops[opnum].X_op = O_symbol;
   1165   1.1  christos 	  myops[opnum].X_add_symbol =
   1166   1.1  christos 	    symbol_find_or_make ((char *) myops[opnum].X_op_symbol);
   1167   1.1  christos 	  myops[opnum].X_add_number = 0;
   1168   1.1  christos 	  myops[opnum].X_op_symbol = NULL;
   1169   1.1  christos 	}
   1170   1.1  christos 
   1171   1.1  christos       next_opcode = opcode + 1;
   1172   1.1  christos 
   1173   1.1  christos       /* If the first operand is supposed to be a register, make sure
   1174   1.1  christos 	 we got a valid one.  */
   1175   1.1  christos       flags = d10v_operands[next_opcode->operands[0]].flags;
   1176   1.1  christos       if (flags & OPERAND_REG)
   1177   1.1  christos 	{
   1178   1.1  christos 	  int X_op = myops[0].X_op;
   1179   1.1  christos 	  int num = myops[0].X_add_number;
   1180   1.1  christos 
   1181   1.1  christos 	  if (X_op != O_register
   1182   1.1  christos 	      || (num & ~flags
   1183   1.1  christos 		  & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
   1184   1.1  christos 		     | OPERAND_FFLAG | OPERAND_CFLAG | OPERAND_CONTROL))
   1185   1.1  christos 	      || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
   1186   1.1  christos 	    {
   1187   1.1  christos 	      as_bad (_("bad opcode or operands"));
   1188   1.1  christos 	      return 0;
   1189   1.1  christos 	    }
   1190   1.1  christos 	}
   1191   1.1  christos 
   1192   1.1  christos       if (myops[opnum].X_op == O_constant
   1193   1.1  christos 	  || (myops[opnum].X_op == O_symbol
   1194   1.1  christos 	      && S_IS_DEFINED (myops[opnum].X_add_symbol)
   1195   1.1  christos 	      && (S_GET_SEGMENT (myops[opnum].X_add_symbol) == now_seg)))
   1196   1.1  christos 	{
   1197   1.1  christos 	  for (i = 0; opcode->operands[i + 1]; i++)
   1198   1.1  christos 	    {
   1199   1.1  christos 	      int bits = d10v_operands[next_opcode->operands[opnum]].bits;
   1200   1.1  christos 
   1201   1.1  christos 	      flags = d10v_operands[next_opcode->operands[opnum]].flags;
   1202   1.1  christos 
   1203   1.1  christos 	      if (flags & OPERAND_ADDR)
   1204   1.1  christos 		bits += 2;
   1205   1.1  christos 
   1206   1.1  christos 	      if (myops[opnum].X_op == O_constant)
   1207   1.1  christos 		{
   1208   1.1  christos 		  if (!check_range (myops[opnum].X_add_number, bits, flags))
   1209   1.1  christos 		    break;
   1210   1.1  christos 		}
   1211   1.1  christos 	      else
   1212   1.1  christos 		{
   1213   1.1  christos 		  fragS *sym_frag;
   1214   1.1  christos 		  fragS *f;
   1215   1.1  christos 		  unsigned long current_position;
   1216   1.1  christos 		  unsigned long symbol_position;
   1217   1.1  christos 		  unsigned long value;
   1218   1.8  christos 		  bool found_symbol;
   1219   1.1  christos 
   1220   1.1  christos 		  /* Calculate the address of the current instruction
   1221   1.1  christos 		     and the address of the symbol.  Do this by summing
   1222   1.1  christos 		     the offsets of previous frags until we reach the
   1223   1.1  christos 		     frag containing the symbol, and the current frag.  */
   1224   1.1  christos 		  sym_frag = symbol_get_frag (myops[opnum].X_add_symbol);
   1225   1.8  christos 		  found_symbol = false;
   1226   1.1  christos 
   1227   1.3  christos 		  current_position = frag_now_fix_octets ();
   1228   1.1  christos 		  symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol);
   1229   1.1  christos 
   1230   1.1  christos 		  for (f = frchain_now->frch_root; f; f = f->fr_next)
   1231   1.1  christos 		    {
   1232   1.1  christos 		      current_position += f->fr_fix + f->fr_offset;
   1233   1.1  christos 
   1234   1.1  christos 		      if (f == sym_frag)
   1235   1.8  christos 			found_symbol = true;
   1236   1.1  christos 
   1237   1.1  christos 		      if (! found_symbol)
   1238   1.1  christos 			symbol_position += f->fr_fix + f->fr_offset;
   1239   1.1  christos 		    }
   1240   1.1  christos 
   1241   1.1  christos 		  value = symbol_position;
   1242   1.1  christos 
   1243   1.1  christos 		  if (flags & OPERAND_ADDR)
   1244   1.1  christos 		    value -= current_position;
   1245   1.1  christos 
   1246   1.1  christos 		  if (AT_WORD_P (&myops[opnum]))
   1247   1.1  christos 		    {
   1248   1.1  christos 		      if (bits > 4)
   1249   1.1  christos 			{
   1250   1.1  christos 			  bits += 2;
   1251   1.1  christos 			  if (!check_range (value, bits, flags))
   1252   1.1  christos 			    break;
   1253   1.1  christos 			}
   1254   1.1  christos 		    }
   1255   1.1  christos 		  else if (!check_range (value, bits, flags))
   1256   1.1  christos 		    break;
   1257   1.1  christos 		}
   1258   1.1  christos 	      next_opcode++;
   1259   1.1  christos 	    }
   1260   1.1  christos 
   1261   1.1  christos 	  if (opcode->operands [i + 1] == 0)
   1262   1.1  christos 	    as_fatal (_("value out of range"));
   1263   1.1  christos 	  else
   1264   1.1  christos 	    opcode = next_opcode;
   1265   1.1  christos 	}
   1266   1.1  christos       else
   1267   1.1  christos 	/* Not a constant, so use a long instruction.  */
   1268   1.1  christos 	opcode += 2;
   1269   1.1  christos     }
   1270   1.1  christos 
   1271   1.1  christos   match = 0;
   1272   1.1  christos 
   1273   1.1  christos   /* Now search the opcode table table for one with operands
   1274   1.1  christos      that matches what we've got.  */
   1275   1.1  christos   while (!match)
   1276   1.1  christos     {
   1277   1.1  christos       match = 1;
   1278   1.1  christos       for (i = 0; opcode->operands[i]; i++)
   1279   1.1  christos 	{
   1280   1.1  christos 	  int flags = d10v_operands[opcode->operands[i]].flags;
   1281   1.1  christos 	  int X_op = myops[i].X_op;
   1282   1.1  christos 	  int num = myops[i].X_add_number;
   1283   1.1  christos 
   1284   1.1  christos 	  if (X_op == 0)
   1285   1.1  christos 	    {
   1286   1.1  christos 	      match = 0;
   1287   1.1  christos 	      break;
   1288   1.1  christos 	    }
   1289   1.1  christos 
   1290   1.1  christos 	  if (flags & OPERAND_REG)
   1291   1.1  christos 	    {
   1292   1.1  christos 	      if ((X_op != O_register)
   1293   1.1  christos 		  || (num & ~flags
   1294   1.1  christos 		      & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
   1295   1.1  christos 			 | OPERAND_FFLAG | OPERAND_CFLAG
   1296   1.1  christos 			 | OPERAND_CONTROL))
   1297   1.1  christos 		  || ((flags & OPERAND_SP) && ! (num & OPERAND_SP)))
   1298   1.1  christos 		{
   1299   1.1  christos 		  match = 0;
   1300   1.1  christos 		  break;
   1301   1.1  christos 		}
   1302   1.1  christos 	    }
   1303   1.1  christos 
   1304   1.1  christos 	  if (((flags & OPERAND_MINUS)   && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
   1305   1.1  christos 	      ((flags & OPERAND_PLUS)    && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
   1306   1.1  christos 	      ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
   1307   1.1  christos 	      ((flags & OPERAND_ATPAR)   && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
   1308   1.1  christos 	      ((flags & OPERAND_ATSIGN)  && ((X_op != O_absent) || ((num != OPERAND_ATSIGN) && (num != OPERAND_ATPAR)))))
   1309   1.1  christos 	    {
   1310   1.1  christos 	      match = 0;
   1311   1.1  christos 	      break;
   1312   1.1  christos 	    }
   1313   1.1  christos 
   1314   1.1  christos 	  /* Unfortunately, for the indirect operand in instructions such
   1315   1.1  christos 	     as ``ldb r1, @(c,r14)'' this function can be passed
   1316   1.1  christos 	     X_op == O_register (because 'c' is a valid register name).
   1317   1.1  christos 	     However we cannot just ignore the case when X_op == O_register
   1318   1.1  christos 	     but flags & OPERAND_REG is null, so we check to see if a symbol
   1319   1.1  christos 	     of the same name as the register exists.  If the symbol does
   1320   1.1  christos 	     exist, then the parser was unable to distinguish the two cases
   1321   1.1  christos 	     and we fix things here. (Ref: PR14826)  */
   1322   1.1  christos 
   1323   1.1  christos 	  if (!(flags & OPERAND_REG) && (X_op == O_register))
   1324   1.1  christos 	    {
   1325   1.1  christos 	      symbolS * sym;
   1326   1.1  christos 
   1327   1.1  christos 	      sym = find_symbol_matching_register (& myops[i]);
   1328   1.1  christos 
   1329   1.1  christos 	      if (sym != NULL)
   1330   1.1  christos 		{
   1331   1.1  christos 		  myops[i].X_op = X_op = O_symbol;
   1332   1.1  christos 		  myops[i].X_add_symbol = sym;
   1333   1.1  christos 		}
   1334   1.1  christos 	      else
   1335   1.1  christos 		as_bad
   1336   1.1  christos 		  (_("illegal operand - register name found where none expected"));
   1337   1.1  christos 	    }
   1338   1.1  christos 	}
   1339   1.1  christos 
   1340   1.1  christos       /* We're only done if the operands matched so far AND there
   1341   1.1  christos 	     are no more to check.  */
   1342   1.1  christos       if (match && myops[i].X_op == 0)
   1343   1.1  christos 	break;
   1344   1.1  christos       else
   1345   1.1  christos 	match = 0;
   1346   1.1  christos 
   1347   1.1  christos       next_opcode = opcode + 1;
   1348   1.1  christos 
   1349   1.1  christos       if (next_opcode->opcode == 0)
   1350   1.1  christos 	break;
   1351   1.1  christos 
   1352   1.1  christos       if (strcmp (next_opcode->name, opcode->name))
   1353   1.1  christos 	break;
   1354   1.1  christos 
   1355   1.1  christos       opcode = next_opcode;
   1356   1.1  christos     }
   1357   1.1  christos 
   1358   1.1  christos   if (!match)
   1359   1.1  christos     {
   1360   1.1  christos       as_bad (_("bad opcode or operands"));
   1361   1.1  christos       return 0;
   1362   1.1  christos     }
   1363   1.1  christos 
   1364   1.1  christos   /* Check that all registers that are required to be even are.
   1365   1.1  christos      Also, if any operands were marked as registers, but were really symbols,
   1366   1.1  christos      fix that here.  */
   1367   1.1  christos   for (i = 0; opcode->operands[i]; i++)
   1368   1.1  christos     {
   1369   1.1  christos       if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
   1370   1.1  christos 	  (myops[i].X_add_number & 1))
   1371   1.1  christos 	as_fatal (_("Register number must be EVEN"));
   1372   1.1  christos       if ((d10v_operands[opcode->operands[i]].flags & OPERAND_NOSP)
   1373   1.1  christos 	  && (myops[i].X_add_number & OPERAND_SP))
   1374   1.1  christos 	as_bad (_("Unsupported use of sp"));
   1375   1.1  christos       if (myops[i].X_op == O_register)
   1376   1.1  christos 	{
   1377   1.1  christos 	  if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
   1378   1.1  christos 	    {
   1379   1.1  christos 	      myops[i].X_op = O_symbol;
   1380   1.1  christos 	      myops[i].X_add_symbol =
   1381   1.1  christos 		symbol_find_or_make ((char *) myops[i].X_op_symbol);
   1382   1.1  christos 	      myops[i].X_add_number = 0;
   1383   1.1  christos 	      myops[i].X_op_symbol = NULL;
   1384   1.1  christos 	    }
   1385   1.1  christos 	}
   1386   1.1  christos       if ((d10v_operands[opcode->operands[i]].flags & OPERAND_CONTROL)
   1387   1.1  christos 	  && (myops[i].X_add_number == OPERAND_CONTROL + 4
   1388   1.1  christos 	      || myops[i].X_add_number == OPERAND_CONTROL + 5
   1389   1.1  christos 	      || myops[i].X_add_number == OPERAND_CONTROL + 6
   1390   1.1  christos 	      || myops[i].X_add_number == OPERAND_CONTROL + 12
   1391   1.1  christos 	      || myops[i].X_add_number == OPERAND_CONTROL + 13
   1392   1.1  christos 	      || myops[i].X_add_number == OPERAND_CONTROL + 15))
   1393   1.9  christos 	as_warn (_("cr%d is a reserved control register"),
   1394   1.9  christos 		 (int) myops[i].X_add_number - OPERAND_CONTROL);
   1395   1.1  christos     }
   1396   1.1  christos   return opcode;
   1397   1.1  christos }
   1398   1.1  christos 
   1399   1.1  christos /* Assemble a single instruction.
   1400   1.1  christos    Return an opcode, or -1 (an invalid opcode) on error.  */
   1401   1.1  christos 
   1402   1.1  christos static unsigned long
   1403   1.1  christos do_assemble (char *str, struct d10v_opcode **opcode)
   1404   1.1  christos {
   1405   1.1  christos   unsigned char *op_start, *op_end;
   1406   1.1  christos   char *save;
   1407   1.1  christos   char name[20];
   1408   1.1  christos   int nlen = 0;
   1409   1.1  christos   expressionS myops[6];
   1410   1.1  christos 
   1411   1.1  christos   /* Drop leading whitespace.  */
   1412  1.10  christos   while (is_whitespace (*str))
   1413   1.1  christos     str++;
   1414   1.1  christos 
   1415   1.1  christos   /* Find the opcode end.  */
   1416   1.1  christos   for (op_start = op_end = (unsigned char *) str;
   1417  1.10  christos        !is_end_of_stmt (*op_end) && !is_whitespace (*op_end);
   1418   1.1  christos        op_end++)
   1419   1.1  christos     {
   1420   1.1  christos       name[nlen] = TOLOWER (op_start[nlen]);
   1421   1.1  christos       nlen++;
   1422   1.1  christos       if (nlen == sizeof (name) - 1)
   1423   1.1  christos 	break;
   1424   1.1  christos     }
   1425   1.1  christos   name[nlen] = 0;
   1426   1.1  christos 
   1427   1.1  christos   if (nlen == 0)
   1428   1.1  christos     return -1;
   1429   1.1  christos 
   1430   1.1  christos   /* Find the first opcode with the proper name.  */
   1431  1.10  christos   *opcode = str_hash_find (d10v_hash, name);
   1432   1.1  christos   if (*opcode == NULL)
   1433   1.1  christos     return -1;
   1434   1.1  christos 
   1435   1.1  christos   save = input_line_pointer;
   1436   1.1  christos   input_line_pointer = (char *) op_end;
   1437   1.1  christos   *opcode = find_opcode (*opcode, myops);
   1438   1.1  christos   if (*opcode == 0)
   1439   1.1  christos     return -1;
   1440   1.1  christos   input_line_pointer = save;
   1441   1.1  christos 
   1442   1.1  christos   return build_insn ((*opcode), myops, 0);
   1443   1.1  christos }
   1444   1.1  christos 
   1445   1.1  christos /* If while processing a fixup, a reloc really needs to be created.
   1446   1.1  christos    Then it is done here.  */
   1447   1.1  christos 
   1448   1.1  christos arelent *
   1449   1.1  christos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
   1450   1.1  christos {
   1451   1.1  christos   arelent *reloc;
   1452  1.10  christos   reloc = notes_alloc (sizeof (arelent));
   1453  1.10  christos   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   1454   1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1455   1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   1456   1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   1457  1.10  christos   if (reloc->howto == NULL)
   1458   1.1  christos     {
   1459   1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   1460   1.1  christos 		    _("reloc %d not supported by object file format"),
   1461   1.1  christos 		    (int) fixp->fx_r_type);
   1462   1.1  christos       return NULL;
   1463   1.1  christos     }
   1464   1.1  christos 
   1465   1.1  christos   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   1466   1.1  christos     reloc->address = fixp->fx_offset;
   1467   1.1  christos 
   1468   1.1  christos   reloc->addend = 0;
   1469   1.1  christos 
   1470   1.1  christos   return reloc;
   1471   1.1  christos }
   1472   1.1  christos 
   1473   1.1  christos int
   1474   1.1  christos md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
   1475   1.1  christos 			       asection *seg ATTRIBUTE_UNUSED)
   1476   1.1  christos {
   1477   1.1  christos   abort ();
   1478   1.1  christos   return 0;
   1479   1.1  christos }
   1480   1.1  christos 
   1481   1.1  christos long
   1482   1.1  christos md_pcrel_from_section (fixS *fixp, segT sec)
   1483   1.1  christos {
   1484  1.10  christos   if (fixp->fx_addsy != NULL
   1485   1.1  christos       && (!S_IS_DEFINED (fixp->fx_addsy)
   1486   1.1  christos 	  || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
   1487   1.1  christos     return 0;
   1488   1.1  christos   return fixp->fx_frag->fr_address + fixp->fx_where;
   1489   1.1  christos }
   1490   1.1  christos 
   1491   1.1  christos void
   1492   1.1  christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   1493   1.1  christos {
   1494   1.1  christos   char *where;
   1495   1.1  christos   unsigned long insn;
   1496   1.1  christos   long value = *valP;
   1497   1.1  christos   int op_type;
   1498   1.1  christos   int left = 0;
   1499   1.1  christos 
   1500  1.10  christos   if (fixP->fx_addsy == NULL)
   1501   1.1  christos     fixP->fx_done = 1;
   1502   1.1  christos 
   1503   1.1  christos   /* We don't actually support subtracting a symbol.  */
   1504  1.10  christos   if (fixP->fx_subsy != NULL)
   1505   1.8  christos     as_bad_subtract (fixP);
   1506   1.1  christos 
   1507   1.1  christos   op_type = fixP->fx_r_type;
   1508   1.1  christos   if (op_type & 2048)
   1509   1.1  christos     {
   1510   1.1  christos       op_type -= 2048;
   1511   1.1  christos       if (op_type & 1024)
   1512   1.1  christos 	{
   1513   1.1  christos 	  op_type -= 1024;
   1514   1.1  christos 	  fixP->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
   1515   1.1  christos 	  left = 1;
   1516   1.1  christos 	}
   1517   1.1  christos       else if (op_type & 4096)
   1518   1.1  christos 	{
   1519   1.1  christos 	  op_type -= 4096;
   1520   1.1  christos 	  fixP->fx_r_type = BFD_RELOC_D10V_18;
   1521   1.1  christos 	}
   1522   1.1  christos       else
   1523   1.1  christos 	fixP->fx_r_type =
   1524  1.10  christos 	  get_reloc (&d10v_operands[op_type]);
   1525   1.1  christos     }
   1526   1.1  christos 
   1527   1.1  christos   /* Fetch the instruction, insert the fully resolved operand
   1528   1.1  christos      value, and stuff the instruction back again.  */
   1529   1.1  christos   where = fixP->fx_frag->fr_literal + fixP->fx_where;
   1530  1.10  christos   insn = bfd_getb32 (where);
   1531   1.1  christos 
   1532   1.1  christos   switch (fixP->fx_r_type)
   1533   1.1  christos     {
   1534   1.1  christos     case BFD_RELOC_D10V_10_PCREL_L:
   1535   1.1  christos     case BFD_RELOC_D10V_10_PCREL_R:
   1536   1.1  christos     case BFD_RELOC_D10V_18_PCREL:
   1537   1.1  christos       /* If the fix is relative to a global symbol, not a section
   1538   1.1  christos 	 symbol, then ignore the offset.
   1539   1.1  christos          XXX - Do we have to worry about branches to a symbol + offset ?  */
   1540   1.1  christos       if (fixP->fx_addsy != NULL
   1541   1.1  christos 	  && S_IS_EXTERNAL (fixP->fx_addsy) )
   1542   1.1  christos         {
   1543   1.1  christos           segT fseg = S_GET_SEGMENT (fixP->fx_addsy);
   1544   1.1  christos           segment_info_type *segf = seg_info(fseg);
   1545   1.1  christos 
   1546   1.1  christos 	  if ( segf && segf->sym != fixP->fx_addsy)
   1547   1.1  christos 	    value = 0;
   1548   1.1  christos         }
   1549   1.6  christos       /* Fall through.  */
   1550   1.1  christos     case BFD_RELOC_D10V_18:
   1551   1.1  christos       /* Instruction addresses are always right-shifted by 2.  */
   1552   1.1  christos       value >>= AT_WORD_RIGHT_SHIFT;
   1553   1.1  christos       if (fixP->fx_size == 2)
   1554  1.10  christos 	bfd_putb16 (value, where);
   1555   1.1  christos       else
   1556   1.1  christos 	{
   1557   1.1  christos 	  struct d10v_opcode *rep, *repi;
   1558   1.1  christos 
   1559  1.10  christos 	  rep = str_hash_find (d10v_hash, "rep");
   1560  1.10  christos 	  repi = str_hash_find (d10v_hash, "repi");
   1561   1.1  christos 	  if ((insn & FM11) == FM11
   1562   1.1  christos 	      && ((repi != NULL
   1563   1.1  christos 		   && (insn & repi->mask) == (unsigned) repi->opcode)
   1564   1.1  christos 		  || (rep != NULL
   1565   1.1  christos 		      && (insn & rep->mask) == (unsigned) rep->opcode))
   1566   1.1  christos 	      && value < 4)
   1567   1.1  christos 	    as_fatal
   1568   1.1  christos 	      (_("line %d: rep or repi must include at least 4 instructions"),
   1569   1.1  christos 	       fixP->fx_line);
   1570   1.1  christos 	  insn =
   1571   1.1  christos 	    d10v_insert_operand (insn, op_type, (offsetT) value, left, fixP);
   1572  1.10  christos 	  bfd_putb32 (insn, where);
   1573   1.1  christos 	}
   1574   1.1  christos       break;
   1575   1.1  christos     case BFD_RELOC_32:
   1576  1.10  christos       bfd_putb32 (value, where);
   1577   1.1  christos       break;
   1578   1.1  christos     case BFD_RELOC_16:
   1579  1.10  christos       bfd_putb16 (value, where);
   1580   1.1  christos       break;
   1581   1.7  christos     case BFD_RELOC_8:
   1582   1.7  christos       *where = value;
   1583   1.7  christos       break;
   1584   1.1  christos 
   1585   1.1  christos     case BFD_RELOC_VTABLE_INHERIT:
   1586   1.1  christos     case BFD_RELOC_VTABLE_ENTRY:
   1587   1.1  christos       fixP->fx_done = 0;
   1588   1.1  christos       return;
   1589   1.1  christos 
   1590   1.1  christos     default:
   1591   1.1  christos       as_fatal (_("line %d: unknown relocation type: 0x%x"),
   1592   1.1  christos 		fixP->fx_line, fixP->fx_r_type);
   1593   1.1  christos     }
   1594   1.1  christos }
   1595   1.1  christos 
   1596   1.1  christos /* d10v_cleanup() is called after the assembler has finished parsing
   1597   1.1  christos    the input file, when a label is read from the input file, or when a
   1598   1.1  christos    stab directive is output.  Because the D10V assembler sometimes
   1599   1.1  christos    saves short instructions to see if it can package them with the
   1600   1.1  christos    next instruction, there may be a short instruction that still needs
   1601   1.1  christos    to be written.
   1602   1.1  christos 
   1603   1.1  christos    NOTE: accesses a global, etype.
   1604   1.1  christos    NOTE: invoked by various macros such as md_cleanup: see.  */
   1605   1.1  christos 
   1606   1.1  christos int
   1607   1.1  christos d10v_cleanup (void)
   1608   1.1  christos {
   1609   1.1  christos   segT seg;
   1610   1.1  christos   subsegT subseg;
   1611   1.1  christos 
   1612   1.1  christos   /* If cleanup was invoked because the assembler encountered, e.g., a
   1613   1.1  christos      user label, we write out the pending instruction, if any.  If it
   1614   1.1  christos      was invoked because the assembler is outputting a piece of line
   1615   1.1  christos      debugging information, though, we write out the pending
   1616   1.1  christos      instruction only if the --no-gstabs-packing command line switch
   1617   1.1  christos      has been specified.  */
   1618   1.1  christos   if (prev_opcode
   1619   1.1  christos       && etype == PACK_UNSPEC
   1620   1.1  christos       && (! outputting_stabs_line_debug || ! flag_allow_gstabs_packing))
   1621   1.1  christos     {
   1622   1.1  christos       seg = now_seg;
   1623   1.1  christos       subseg = now_subseg;
   1624   1.1  christos 
   1625   1.1  christos       if (prev_seg)
   1626   1.1  christos 	subseg_set (prev_seg, prev_subseg);
   1627   1.1  christos 
   1628   1.1  christos       write_1_short (prev_opcode, prev_insn, fixups->next);
   1629   1.1  christos       subseg_set (seg, subseg);
   1630   1.1  christos       prev_opcode = NULL;
   1631   1.1  christos     }
   1632   1.1  christos   return 1;
   1633   1.1  christos }
   1634   1.1  christos 
   1635   1.1  christos void
   1636   1.1  christos d10v_frob_label (symbolS *lab)
   1637   1.1  christos {
   1638   1.1  christos   d10v_cleanup ();
   1639   1.1  christos   symbol_set_frag (lab, frag_now);
   1640   1.1  christos   S_SET_VALUE (lab, (valueT) frag_now_fix ());
   1641   1.1  christos   dwarf2_emit_label (lab);
   1642   1.1  christos }
   1643   1.1  christos 
   1644   1.1  christos /* Like normal .word, except support @word.
   1645   1.1  christos    Clobbers input_line_pointer, checks end-of-line.  */
   1646   1.1  christos 
   1647   1.1  christos static void
   1648   1.1  christos d10v_dot_word (int dummy ATTRIBUTE_UNUSED)
   1649   1.1  christos {
   1650   1.1  christos   expressionS exp;
   1651   1.1  christos   char *p;
   1652   1.1  christos 
   1653   1.1  christos   if (is_it_end_of_statement ())
   1654   1.1  christos     {
   1655   1.1  christos       demand_empty_rest_of_line ();
   1656   1.1  christos       return;
   1657   1.1  christos     }
   1658   1.1  christos 
   1659   1.1  christos   do
   1660   1.1  christos     {
   1661   1.1  christos       expression (&exp);
   1662   1.1  christos       if (!strncasecmp (input_line_pointer, "@word", 5))
   1663   1.1  christos 	{
   1664   1.1  christos 	  exp.X_add_number = 0;
   1665   1.1  christos 	  input_line_pointer += 5;
   1666   1.1  christos 
   1667   1.1  christos 	  p = frag_more (2);
   1668   1.1  christos 	  fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
   1669   1.1  christos 		       &exp, 0, BFD_RELOC_D10V_18);
   1670   1.1  christos 	}
   1671   1.1  christos       else
   1672   1.1  christos 	emit_expr (&exp, 2);
   1673   1.1  christos     }
   1674   1.1  christos   while (*input_line_pointer++ == ',');
   1675   1.1  christos 
   1676   1.1  christos   input_line_pointer--;		/* Put terminator back into stream.  */
   1677   1.1  christos   demand_empty_rest_of_line ();
   1678   1.1  christos }
   1679   1.1  christos 
   1680   1.1  christos /* Mitsubishi asked that we support some old syntax that apparently
   1681   1.1  christos    had immediate operands starting with '#'.  This is in some of their
   1682   1.1  christos    sample code but is not documented (although it appears in some
   1683   1.1  christos    examples in their assembler manual). For now, we'll solve this
   1684   1.1  christos    compatibility problem by simply ignoring any '#' at the beginning
   1685   1.1  christos    of an operand.  */
   1686   1.1  christos 
   1687   1.1  christos /* Operands that begin with '#' should fall through to here.
   1688   1.1  christos    From expr.c.  */
   1689   1.1  christos 
   1690   1.1  christos void
   1691   1.1  christos md_operand (expressionS *expressionP)
   1692   1.1  christos {
   1693   1.1  christos   if (*input_line_pointer == '#' && ! do_not_ignore_hash)
   1694   1.1  christos     {
   1695   1.1  christos       input_line_pointer++;
   1696   1.1  christos       expression (expressionP);
   1697   1.1  christos     }
   1698   1.1  christos }
   1699   1.1  christos 
   1700   1.8  christos bool
   1701   1.1  christos d10v_fix_adjustable (fixS *fixP)
   1702   1.1  christos {
   1703   1.1  christos   /* We need the symbol name for the VTABLE entries.  */
   1704   1.1  christos   if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
   1705   1.1  christos       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   1706   1.1  christos     return 0;
   1707   1.1  christos 
   1708   1.1  christos   return 1;
   1709   1.1  christos }
   1710   1.1  christos 
   1711   1.1  christos /* The target specific pseudo-ops which we support.  */
   1712   1.1  christos const pseudo_typeS md_pseudo_table[] =
   1713   1.1  christos {
   1714   1.1  christos   { "word",	d10v_dot_word,	2 },
   1715   1.1  christos   { NULL,       NULL,           0 }
   1716   1.1  christos };
   1717   1.1  christos 
   1718   1.1  christos void
   1719   1.1  christos md_assemble (char *str)
   1720   1.1  christos {
   1721   1.1  christos   /* etype is saved extype.  For multi-line instructions.  */
   1722   1.1  christos   packing_type extype = PACK_UNSPEC;		/* Parallel, etc.  */
   1723   1.1  christos   struct d10v_opcode *opcode;
   1724   1.1  christos   unsigned long insn;
   1725   1.1  christos   char *str2;
   1726   1.1  christos 
   1727   1.1  christos   if (etype == PACK_UNSPEC)
   1728   1.1  christos     {
   1729   1.1  christos       /* Look for the special multiple instruction separators.  */
   1730   1.1  christos       str2 = strstr (str, "||");
   1731   1.1  christos       if (str2)
   1732   1.1  christos 	extype = PACK_PARALLEL;
   1733   1.1  christos       else
   1734   1.1  christos 	{
   1735   1.1  christos 	  str2 = strstr (str, "->");
   1736   1.1  christos 	  if (str2)
   1737   1.1  christos 	    extype = PACK_LEFT_RIGHT;
   1738   1.1  christos 	  else
   1739   1.1  christos 	    {
   1740   1.1  christos 	      str2 = strstr (str, "<-");
   1741   1.1  christos 	      if (str2)
   1742   1.1  christos 		extype = PACK_RIGHT_LEFT;
   1743   1.1  christos 	    }
   1744   1.1  christos 	}
   1745   1.1  christos 
   1746   1.1  christos       /* str2 points to the separator, if there is one.  */
   1747   1.1  christos       if (str2)
   1748   1.1  christos 	{
   1749   1.1  christos 	  *str2 = 0;
   1750   1.1  christos 
   1751   1.1  christos 	  /* If two instructions are present and we already have one saved,
   1752   1.1  christos 	     then first write out the saved one.  */
   1753   1.1  christos 	  d10v_cleanup ();
   1754   1.1  christos 
   1755   1.1  christos 	  /* Assemble first instruction and save it.  */
   1756   1.1  christos 	  prev_insn = do_assemble (str, &prev_opcode);
   1757   1.1  christos 	  prev_seg = now_seg;
   1758   1.1  christos 	  prev_subseg = now_subseg;
   1759   1.1  christos 	  if (prev_insn == (unsigned long) -1)
   1760   1.1  christos 	    as_fatal (_("can't find previous opcode "));
   1761   1.1  christos 	  fixups = fixups->next;
   1762   1.1  christos 	  str = str2 + 2;
   1763   1.1  christos 	}
   1764   1.1  christos     }
   1765   1.1  christos 
   1766   1.1  christos   insn = do_assemble (str, &opcode);
   1767   1.1  christos   if (insn == (unsigned long) -1)
   1768   1.1  christos     {
   1769   1.1  christos       if (extype != PACK_UNSPEC)
   1770   1.1  christos 	etype = extype;
   1771   1.1  christos       else
   1772   1.1  christos 	as_bad (_("could not assemble: %s"), str);
   1773   1.1  christos       return;
   1774   1.1  christos     }
   1775   1.1  christos 
   1776   1.1  christos   if (etype != PACK_UNSPEC)
   1777   1.1  christos     {
   1778   1.1  christos       extype = etype;
   1779   1.1  christos       etype = PACK_UNSPEC;
   1780   1.1  christos     }
   1781   1.1  christos 
   1782   1.1  christos   /* If this is a long instruction, write it and any previous short
   1783   1.1  christos      instruction.  */
   1784   1.1  christos   if (opcode->format & LONG_OPCODE)
   1785   1.1  christos     {
   1786   1.1  christos       if (extype != PACK_UNSPEC)
   1787   1.1  christos 	as_fatal (_("Unable to mix instructions as specified"));
   1788   1.1  christos       d10v_cleanup ();
   1789   1.1  christos       write_long (insn, fixups);
   1790   1.1  christos       prev_opcode = NULL;
   1791   1.1  christos       return;
   1792   1.1  christos     }
   1793   1.1  christos 
   1794   1.1  christos   if (prev_opcode
   1795   1.1  christos       && prev_seg
   1796   1.1  christos       && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
   1797   1.1  christos     d10v_cleanup ();
   1798   1.1  christos 
   1799   1.1  christos   if (prev_opcode
   1800   1.1  christos       && (0 == write_2_short (prev_opcode, prev_insn, opcode, insn, extype,
   1801   1.1  christos 			      fixups)))
   1802   1.1  christos     {
   1803   1.1  christos       /* No instructions saved.  */
   1804   1.1  christos       prev_opcode = NULL;
   1805   1.1  christos     }
   1806   1.1  christos   else
   1807   1.1  christos     {
   1808   1.1  christos       if (extype != PACK_UNSPEC)
   1809   1.1  christos 	as_fatal (_("Unable to mix instructions as specified"));
   1810   1.1  christos       /* Save last instruction so it may be packed on next pass.  */
   1811   1.1  christos       prev_opcode = opcode;
   1812   1.1  christos       prev_insn = insn;
   1813   1.1  christos       prev_seg = now_seg;
   1814   1.1  christos       prev_subseg = now_subseg;
   1815   1.1  christos       fixups = fixups->next;
   1816   1.1  christos     }
   1817   1.1  christos }
   1818   1.1  christos 
   1819