Home | History | Annotate | Line # | Download | only in config
tc-kvx.c revision 1.1.1.3
      1      1.1  christos /* tc-kvx.c -- Assemble for the KVX ISA
      2      1.1  christos 
      3  1.1.1.3  christos    Copyright (C) 2009-2026 Free Software Foundation, Inc.
      4      1.1  christos    Contributed by Kalray SA.
      5      1.1  christos 
      6      1.1  christos    This file is part of GAS.
      7      1.1  christos 
      8      1.1  christos    GAS is free software; you can redistribute it and/or modify
      9      1.1  christos    it under the terms of the GNU General Public License as published by
     10      1.1  christos    the Free Software Foundation; either version 3 of the license, or
     11      1.1  christos    (at your option) any later version.
     12      1.1  christos 
     13      1.1  christos    GAS is distributed in the hope that it will be useful,
     14      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16      1.1  christos    GNU General Public License for more details.
     17      1.1  christos 
     18      1.1  christos    You should have received a copy of the GNU General Public License
     19      1.1  christos    along with this program; see the file COPYING3. If not,
     20      1.1  christos    see <http://www.gnu.org/licenses/>.  */
     21      1.1  christos 
     22      1.1  christos #include "as.h"
     23      1.1  christos #include "obstack.h"
     24      1.1  christos #include "subsegs.h"
     25      1.1  christos #include "tc-kvx.h"
     26      1.1  christos #include "libiberty.h"
     27      1.1  christos 
     28      1.1  christos #include <assert.h>
     29      1.1  christos #include <stdio.h>
     30      1.1  christos #include <stdint.h>
     31      1.1  christos #include <string.h>
     32      1.1  christos #include <ctype.h>
     33      1.1  christos 
     34      1.1  christos #ifdef OBJ_ELF
     35      1.1  christos #include "elf/kvx.h"
     36      1.1  christos #include "dwarf2dbg.h"
     37      1.1  christos #include "dw2gencfi.h"
     38      1.1  christos #endif
     39      1.1  christos 
     40      1.1  christos #define D(args...) do { if(debug) fprintf(args); } while(0)
     41      1.1  christos 
     42      1.1  christos static void supported_cores (char buf[], size_t buflen);
     43      1.1  christos 
     44      1.1  christos #define NELEMS(a) ((int) (sizeof (a)/sizeof ((a)[0])))
     45      1.1  christos 
     46      1.1  christos #define STREQ(x,y) !strcmp(((x) ? (x) : ""), ((y) ? (y) : ""))
     47      1.1  christos #define STRNEQ(x,y,n) !strncmp(((x) ? (x) : ""), ((y) ? (y) : ""),(n))
     48      1.1  christos 
     49      1.1  christos /* The PARALLEL_BIT is set to 0 when an instruction is the last of a bundle. */
     50      1.1  christos #define PARALLEL_BIT (1u << 31)
     51      1.1  christos 
     52      1.1  christos /*TB begin*/
     53      1.1  christos int size_type_function = 1;
     54      1.1  christos /*TB end */
     55      1.1  christos 
     56      1.1  christos struct kvx_as_env env = {
     57      1.1  christos   .params = {
     58      1.1  christos     .abi = ELF_KVX_ABI_UNDEF,
     59      1.1  christos     .osabi = ELFOSABI_NONE,
     60      1.1  christos     .core = -1,
     61      1.1  christos     .core_set = 0,
     62      1.1  christos     .abi_set = 0,
     63      1.1  christos     .osabi_set = 0,
     64      1.1  christos     .pic_flags = 0,
     65      1.1  christos     .arch_size = 64
     66      1.1  christos   },
     67      1.1  christos   .opts = {
     68      1.1  christos     .march = NULL,
     69      1.1  christos     .check_resource_usage = 1,
     70      1.1  christos     .generate_illegal_code = 0,
     71      1.1  christos     .dump_table = 0,
     72      1.1  christos     .dump_insn = 0,
     73      1.1  christos     .diagnostics = 1,
     74      1.1  christos     .more = 1,
     75      1.1  christos     .allow_all_sfr = 0
     76      1.1  christos   }
     77      1.1  christos };
     78      1.1  christos 
     79      1.1  christos /* This string should contain position in string where error occured. */
     80      1.1  christos 
     81      1.1  christos /* Default kvx_registers array. */
     82      1.1  christos const struct kvx_Register *kvx_registers = NULL;
     83      1.1  christos /* Default kvx_modifiers array. */
     84      1.1  christos const char ***kvx_modifiers = NULL;
     85      1.1  christos /* Default kvx_regfiles array. */
     86      1.1  christos const int *kvx_regfiles = NULL;
     87      1.1  christos /* Default values used if no assume directive is given */
     88      1.1  christos const struct kvx_core_info *kvx_core_info = NULL;
     89      1.1  christos 
     90      1.1  christos /***********************************************/
     91      1.1  christos /*    Generic Globals for GAS                  */
     92      1.1  christos /***********************************************/
     93      1.1  christos 
     94      1.1  christos const char comment_chars[]        = "#";
     95      1.1  christos const char line_comment_chars[]   = "#";
     96      1.1  christos const char line_separator_chars[] = ";";
     97      1.1  christos const char EXP_CHARS[]            = "eE";
     98      1.1  christos const char FLT_CHARS[]            = "dD";
     99      1.1  christos const int md_short_jump_size      = 0;
    100      1.1  christos const int md_long_jump_size       = 0;
    101      1.1  christos 
    102      1.1  christos /***********************************************/
    103      1.1  christos /*           Local Types                       */
    104      1.1  christos /***********************************************/
    105      1.1  christos 
    106      1.1  christos /* a fix up record                       */
    107      1.1  christos 
    108      1.1  christos struct kvx_fixup
    109      1.1  christos {
    110      1.1  christos   /* The expression used.  */
    111      1.1  christos   expressionS exp;
    112      1.1  christos   /* The place in the frag where this goes.  */
    113      1.1  christos   int where;
    114      1.1  christos   /* The relocation.  */
    115      1.1  christos   bfd_reloc_code_real_type reloc;
    116      1.1  christos };
    117      1.1  christos 
    118      1.1  christos /* a single assembled instruction record */
    119      1.1  christos /* may include immediate extension words  */
    120      1.1  christos struct kvxinsn
    121      1.1  christos {
    122      1.1  christos   /* written out?  */
    123      1.1  christos   int written;
    124      1.1  christos   /* Opcode table entry for this insn */
    125      1.1  christos   const struct kvxopc *opdef;
    126      1.1  christos   /* length of instruction in words (1 or 2) */
    127      1.1  christos   int len;
    128      1.1  christos   /* insn is extended */
    129      1.1  christos   int immx0;
    130      1.1  christos   /* insn has two immx */
    131      1.1  christos   int immx1;
    132      1.1  christos   /* order to stabilize sort */
    133      1.1  christos   int order;
    134      1.1  christos   /* instruction words */
    135      1.1  christos   uint32_t words[KVXMAXBUNDLEWORDS];
    136      1.1  christos   /* the number of fixups [0,2] */
    137      1.1  christos   int nfixups;
    138      1.1  christos   /* the actual fixups */
    139      1.1  christos   struct kvx_fixup fixup[2];
    140      1.1  christos };
    141      1.1  christos 
    142      1.1  christos typedef void (*print_insn_t) (struct kvxopc * op);
    143      1.1  christos static print_insn_t print_insn = NULL;
    144      1.1  christos 
    145      1.1  christos /* Set to TRUE when we assemble instructions.  */
    146      1.1  christos static bool assembling_insn = false;
    147      1.1  christos 
    148      1.1  christos #define NOIMMX -1
    149      1.1  christos 
    150      1.1  christos /* Was KVXMAXBUNDLEISSUE, changed because of NOPs */
    151      1.1  christos static struct kvxinsn insbuf[KVXMAXBUNDLEWORDS];
    152      1.1  christos static int insncnt = 0;
    153      1.1  christos static struct kvxinsn immxbuf[KVXMAXBUNDLEWORDS];
    154      1.1  christos static int immxcnt = 0;
    155      1.1  christos 
    156      1.1  christos static void
    157      1.1  christos incr_immxcnt (void)
    158      1.1  christos {
    159      1.1  christos   immxcnt++;
    160      1.1  christos   if (immxcnt >= KVXMAXBUNDLEWORDS)
    161      1.1  christos     as_bad ("Max immx number exceeded: %d", immxcnt);
    162      1.1  christos }
    163      1.1  christos 
    164      1.1  christos static void set_byte_counter (asection * sec, int value);
    165      1.1  christos static void
    166      1.1  christos set_byte_counter (asection * sec, int value)
    167      1.1  christos {
    168      1.1  christos   sec->target_index = value;
    169      1.1  christos }
    170      1.1  christos 
    171      1.1  christos static int get_byte_counter (asection * sec);
    172      1.1  christos int
    173      1.1  christos get_byte_counter (asection * sec)
    174      1.1  christos {
    175      1.1  christos   return sec->target_index;
    176      1.1  christos }
    177      1.1  christos 
    178      1.1  christos const char *
    179      1.1  christos kvx_target_format (void)
    180      1.1  christos {
    181      1.1  christos   return env.params.arch_size == 64 ? "elf64-kvx" : "elf32-kvx";
    182      1.1  christos }
    183      1.1  christos 
    184      1.1  christos /****************************************************/
    185      1.1  christos /*  ASSEMBLER Pseudo-ops.  Some of this just        */
    186      1.1  christos /*  extends the default definitions                 */
    187      1.1  christos /*  others are KVX specific                          */
    188      1.1  christos /****************************************************/
    189      1.1  christos 
    190      1.1  christos static void kvx_check_resources (int);
    191      1.1  christos static void kvx_proc (int start);
    192      1.1  christos static void kvx_endp (int start);
    193      1.1  christos static void kvx_type (int start);
    194      1.1  christos 
    195      1.1  christos const pseudo_typeS md_pseudo_table[] = {
    196      1.1  christos   /* override default 2-bytes */
    197      1.1  christos   { "word",             cons,                  4 },
    198      1.1  christos 
    199      1.1  christos   /* KVX specific */
    200      1.1  christos   { "dword",            cons,                  8 },
    201      1.1  christos 
    202      1.1  christos   /* Override align directives to have a boundary as argument (and not the
    203      1.1  christos      power of two as in p2align) */
    204      1.1  christos   { "align",            s_align_bytes,         0 },
    205      1.1  christos 
    206      1.1  christos   { "checkresources",   kvx_check_resources,   1 },
    207      1.1  christos   { "nocheckresources", kvx_check_resources,   0 },
    208      1.1  christos 
    209      1.1  christos   { "proc",             kvx_proc,              1 },
    210      1.1  christos   { "endp",             kvx_endp,              0 },
    211      1.1  christos 
    212      1.1  christos   { "type",             kvx_type,              0 },
    213      1.1  christos 
    214      1.1  christos #ifdef OBJ_ELF
    215      1.1  christos   { "file",             dwarf2_directive_file, 0 },
    216      1.1  christos   { "loc",              dwarf2_directive_loc,  0 },
    217      1.1  christos #endif
    218      1.1  christos   { NULL,               0,                     0 }
    219      1.1  christos };
    220      1.1  christos 
    221      1.1  christos 
    222      1.1  christos static int inside_bundle = 0;
    223      1.1  christos 
    224      1.1  christos /* Stores the labels inside bundles (typically debug labels) that need
    225      1.1  christos    to be postponed to the next bundle. */
    226      1.1  christos struct label_fix
    227      1.1  christos {
    228      1.1  christos   struct label_fix *next;
    229      1.1  christos   symbolS *sym;
    230      1.1  christos } *label_fixes = 0;
    231      1.1  christos 
    232      1.1  christos /*****************************************************/
    233      1.1  christos /*   OPTIONS PROCESSING                              */
    234      1.1  christos /*****************************************************/
    235      1.1  christos 
    236  1.1.1.2  christos const char md_shortopts[] = "hV";	/* catted to std short options */
    237      1.1  christos 
    238      1.1  christos /* added to std long options */
    239      1.1  christos 
    240      1.1  christos #define OPTION_HEXFILE               (OPTION_MD_BASE + 0)
    241      1.1  christos #define OPTION_MARCH                 (OPTION_MD_BASE + 4)
    242      1.1  christos #define OPTION_CHECK_RESOURCES       (OPTION_MD_BASE + 5)
    243      1.1  christos #define OPTION_NO_CHECK_RESOURCES    (OPTION_MD_BASE + 6)
    244      1.1  christos #define OPTION_GENERATE_ILLEGAL_CODE (OPTION_MD_BASE + 7)
    245      1.1  christos #define OPTION_DUMP_TABLE            (OPTION_MD_BASE + 8)
    246      1.1  christos #define OPTION_PIC                   (OPTION_MD_BASE + 9)
    247      1.1  christos #define OPTION_BIGPIC                (OPTION_MD_BASE + 10)
    248      1.1  christos #define OPTION_NOPIC                 (OPTION_MD_BASE + 12)
    249      1.1  christos #define OPTION_32                    (OPTION_MD_BASE + 13)
    250      1.1  christos #define OPTION_DUMPINSN              (OPTION_MD_BASE + 15)
    251      1.1  christos #define OPTION_ALL_SFR               (OPTION_MD_BASE + 16)
    252      1.1  christos #define OPTION_DIAGNOSTICS           (OPTION_MD_BASE + 17)
    253      1.1  christos #define OPTION_NO_DIAGNOSTICS        (OPTION_MD_BASE + 18)
    254      1.1  christos #define OPTION_MORE                  (OPTION_MD_BASE + 19)
    255      1.1  christos #define OPTION_NO_MORE               (OPTION_MD_BASE + 20)
    256      1.1  christos 
    257  1.1.1.2  christos const struct option md_longopts[] = {
    258      1.1  christos   { "march",                 required_argument, NULL, OPTION_MARCH                 },
    259      1.1  christos   { "check-resources",       no_argument,       NULL, OPTION_CHECK_RESOURCES       },
    260      1.1  christos   { "no-check-resources",    no_argument,       NULL, OPTION_NO_CHECK_RESOURCES    },
    261      1.1  christos   { "generate-illegal-code", no_argument,       NULL, OPTION_GENERATE_ILLEGAL_CODE },
    262      1.1  christos   { "dump-table",            no_argument,       NULL, OPTION_DUMP_TABLE            },
    263      1.1  christos   { "mpic",                  no_argument,       NULL, OPTION_PIC                   },
    264      1.1  christos   { "mPIC",                  no_argument,       NULL, OPTION_BIGPIC                },
    265      1.1  christos   { "mnopic",                no_argument,       NULL, OPTION_NOPIC                 },
    266      1.1  christos   { "m32",                   no_argument,       NULL, OPTION_32                    },
    267      1.1  christos   { "dump-insn",             no_argument,       NULL, OPTION_DUMPINSN              },
    268      1.1  christos   { "all-sfr",               no_argument,       NULL, OPTION_ALL_SFR               },
    269      1.1  christos   { "diagnostics",           no_argument,       NULL, OPTION_DIAGNOSTICS           },
    270      1.1  christos   { "no-diagnostics",        no_argument,       NULL, OPTION_NO_DIAGNOSTICS        },
    271      1.1  christos   { "more",                  no_argument,       NULL, OPTION_MORE                  },
    272      1.1  christos   { "no-more",               no_argument,       NULL, OPTION_NO_MORE               },
    273      1.1  christos   { NULL,                    no_argument,       NULL, 0                            }
    274      1.1  christos };
    275      1.1  christos 
    276  1.1.1.2  christos const size_t md_longopts_size = sizeof (md_longopts);
    277      1.1  christos 
    278      1.1  christos int
    279      1.1  christos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
    280      1.1  christos {
    281      1.1  christos   int find_core = 0;
    282      1.1  christos 
    283      1.1  christos   switch (c)
    284      1.1  christos     {
    285      1.1  christos     case 'h':
    286      1.1  christos       md_show_usage (stdout);
    287      1.1  christos       exit (EXIT_SUCCESS);
    288      1.1  christos       break;
    289      1.1  christos 
    290      1.1  christos       /* -V: SVR4 argument to print version ID.  */
    291      1.1  christos     case 'V':
    292      1.1  christos       print_version_id ();
    293      1.1  christos       exit (EXIT_SUCCESS);
    294      1.1  christos       break;
    295      1.1  christos     case OPTION_MARCH:
    296      1.1  christos       env.opts.march = strdup (arg);
    297      1.1  christos       for (int i = 0; i < KVXNUMCORES && !find_core; ++i)
    298      1.1  christos 	    if (!strcasecmp (env.opts.march, kvx_core_info_table[i]->name))
    299      1.1  christos 	      {
    300      1.1  christos 		kvx_core_info = kvx_core_info_table[i];
    301      1.1  christos 		kvx_registers = kvx_registers_table[i];
    302      1.1  christos 		kvx_modifiers = kvx_modifiers_table[i];
    303      1.1  christos 		kvx_regfiles = kvx_regfiles_table[i];
    304      1.1  christos 
    305      1.1  christos 		find_core = 1;
    306      1.1  christos 		break;
    307      1.1  christos 	      }
    308      1.1  christos       if (!find_core)
    309      1.1  christos 	{
    310      1.1  christos 	  char buf[100];
    311      1.1  christos 	  supported_cores (buf, sizeof (buf));
    312      1.1  christos 	  as_fatal ("Specified arch not supported [%s]", buf);
    313      1.1  christos 	}
    314      1.1  christos       break;
    315      1.1  christos     case OPTION_CHECK_RESOURCES:
    316      1.1  christos       env.opts.check_resource_usage = 1;
    317      1.1  christos       break;
    318      1.1  christos     case OPTION_NO_CHECK_RESOURCES:
    319      1.1  christos       env.opts.check_resource_usage = 0;
    320      1.1  christos       break;
    321      1.1  christos     case OPTION_GENERATE_ILLEGAL_CODE:
    322      1.1  christos       env.opts.generate_illegal_code = 1;
    323      1.1  christos       break;
    324      1.1  christos     case OPTION_DUMP_TABLE:
    325      1.1  christos       env.opts.dump_table = 1;
    326      1.1  christos       break;
    327      1.1  christos     case OPTION_DUMPINSN:
    328      1.1  christos       env.opts.dump_insn = 1;
    329      1.1  christos       break;
    330      1.1  christos     case OPTION_ALL_SFR:
    331      1.1  christos       env.opts.allow_all_sfr = 1;
    332      1.1  christos       break;
    333      1.1  christos     case OPTION_DIAGNOSTICS:
    334      1.1  christos       env.opts.diagnostics = 1;
    335      1.1  christos       break;
    336      1.1  christos     case OPTION_NO_DIAGNOSTICS:
    337      1.1  christos       env.opts.diagnostics = 0;
    338      1.1  christos       break;
    339      1.1  christos     case OPTION_MORE:
    340      1.1  christos       env.opts.more = 1;
    341      1.1  christos       break;
    342      1.1  christos     case OPTION_NO_MORE:
    343      1.1  christos       env.opts.more = 0;
    344      1.1  christos       break;
    345      1.1  christos     case OPTION_PIC:
    346      1.1  christos       /* fallthrough, for now the same on KVX */
    347      1.1  christos     case OPTION_BIGPIC:
    348      1.1  christos       env.params.pic_flags |= ELF_KVX_ABI_PIC_BIT;
    349      1.1  christos       break;
    350      1.1  christos     case OPTION_NOPIC:
    351      1.1  christos       env.params.pic_flags &= ~(ELF_KVX_ABI_PIC_BIT);
    352      1.1  christos       break;
    353      1.1  christos     case OPTION_32:
    354      1.1  christos       env.params.arch_size = 32;
    355      1.1  christos       break;
    356      1.1  christos 
    357      1.1  christos     default:
    358      1.1  christos       return 0;
    359      1.1  christos     }
    360      1.1  christos   return 1;
    361      1.1  christos }
    362      1.1  christos 
    363      1.1  christos void
    364      1.1  christos md_show_usage (FILE * stream)
    365      1.1  christos {
    366      1.1  christos   char buf[100];
    367      1.1  christos   supported_cores (buf, sizeof (buf));
    368      1.1  christos 
    369      1.1  christos   fprintf (stream, "\n"
    370      1.1  christos "KVX specific options:\n\n"
    371      1.1  christos "  --check-resources\t Perform minimal resource checking\n"
    372      1.1  christos "  --march [%s]\t Select architecture\n"
    373      1.1  christos "  -V \t\t\t Print assembler version number\n\n"
    374      1.1  christos "  The options -M, --mri and -f are not supported in this assembler.\n", buf);
    375      1.1  christos }
    376      1.1  christos 
    377      1.1  christos /**************************************************/
    378      1.1  christos /*              UTILITIES                         */
    379      1.1  christos /**************************************************/
    380      1.1  christos 
    381      1.1  christos /*
    382      1.1  christos  * Read a value from to the object file
    383      1.1  christos  */
    384      1.1  christos 
    385      1.1  christos static valueT md_chars_to_number (char *buf, int n);
    386      1.1  christos valueT
    387      1.1  christos md_chars_to_number (char *buf, int n)
    388      1.1  christos {
    389      1.1  christos   valueT val = 0;
    390      1.1  christos 
    391      1.1  christos   if (n > (int) sizeof (val) || n <= 0)
    392      1.1  christos     abort ();
    393      1.1  christos 
    394      1.1  christos   while (n--)
    395      1.1  christos     {
    396      1.1  christos       val <<= 8;
    397      1.1  christos       val |= (buf[n] & 0xff);
    398      1.1  christos     }
    399      1.1  christos 
    400      1.1  christos   return val;
    401      1.1  christos }
    402      1.1  christos 
    403      1.1  christos /* Returns the corresponding pseudo function matching SYM and to be
    404      1.1  christos    used for data section */
    405      1.1  christos static struct pseudo_func *
    406      1.1  christos kvx_get_pseudo_func_data_scn (symbolS * sym)
    407      1.1  christos {
    408      1.1  christos   for (int i = 0; i < kvx_core_info->nb_pseudo_funcs; i++)
    409      1.1  christos     if (sym == kvx_core_info->pseudo_funcs[i].sym
    410      1.1  christos 	&& kvx_core_info->pseudo_funcs[i].pseudo_relocs.single != BFD_RELOC_UNUSED)
    411      1.1  christos 	return &kvx_core_info->pseudo_funcs[i];
    412      1.1  christos   return NULL;
    413      1.1  christos }
    414      1.1  christos 
    415      1.1  christos /* Returns the corresponding pseudo function matching SYM and operand
    416      1.1  christos    format OPND */
    417      1.1  christos static struct pseudo_func *
    418      1.1  christos kvx_get_pseudo_func2 (symbolS *sym, struct kvx_operand * opnd)
    419      1.1  christos {
    420      1.1  christos   for (int i = 0; i < kvx_core_info->nb_pseudo_funcs; i++)
    421      1.1  christos     if (sym == kvx_core_info->pseudo_funcs[i].sym)
    422      1.1  christos       for (int relidx = 0; relidx < opnd->reloc_nb; relidx++)
    423      1.1  christos 	if (opnd->relocs[relidx] == kvx_core_info->pseudo_funcs[i].pseudo_relocs.kreloc
    424      1.1  christos 	    && (env.params.arch_size == (int) kvx_core_info->pseudo_funcs[i].pseudo_relocs.avail_modes
    425      1.1  christos 	      || kvx_core_info->pseudo_funcs[i].pseudo_relocs.avail_modes == PSEUDO_ALL))
    426      1.1  christos 	  return &kvx_core_info->pseudo_funcs[i];
    427      1.1  christos 
    428      1.1  christos   return NULL;
    429      1.1  christos }
    430      1.1  christos 
    431      1.1  christos static void
    432      1.1  christos supported_cores (char buf[], size_t buflen)
    433      1.1  christos {
    434      1.1  christos   buf[0] = '\0';
    435      1.1  christos   for (int i = 0; i < KVXNUMCORES; i++)
    436      1.1  christos     {
    437      1.1  christos       if (buf[0] == '\0')
    438      1.1  christos 	strcpy (buf, kvx_core_info_table[i]->name);
    439      1.1  christos       else
    440      1.1  christos 	if ((strlen (buf) + 1 + strlen (kvx_core_info_table[i]->name) + 1) < buflen)
    441      1.1  christos 	  {
    442      1.1  christos 	    strcat (buf, "|");
    443      1.1  christos 	    strcat (buf, kvx_core_info_table[i]->name);
    444      1.1  christos 	  }
    445      1.1  christos     }
    446      1.1  christos }
    447      1.1  christos 
    448      1.1  christos /***************************************************/
    449      1.1  christos /*   ASSEMBLE AN INSTRUCTION                       */
    450      1.1  christos /***************************************************/
    451      1.1  christos 
    452      1.1  christos /*
    453      1.1  christos  * Insert ARG into the operand described by OPDEF in instruction INSN
    454      1.1  christos  * Returns 1 if the immediate extension (IMMX) has been
    455      1.1  christos  * handled along with relocation, 0 if not.
    456      1.1  christos  */
    457      1.1  christos static int
    458      1.1  christos insert_operand (struct kvxinsn *insn, struct kvx_operand *opdef,
    459      1.1  christos 		struct token_list *tok)
    460      1.1  christos {
    461      1.1  christos   uint64_t op = 0;
    462      1.1  christos   struct kvx_bitfield *bfields = opdef->bfield;
    463      1.1  christos   int bf_nb = opdef->bitfields;
    464      1.1  christos   int immx_ready = 0;
    465      1.1  christos 
    466      1.1  christos   if (opdef->width == 0)
    467      1.1  christos     return 0;
    468      1.1  christos 
    469      1.1  christos #define add_fixup(insn_, reloc_, exp_) \
    470      1.1  christos   do { \
    471      1.1  christos     (insn_)->fixup[(insn_)->nfixups].reloc = (reloc_); \
    472      1.1  christos     (insn_)->fixup[(insn_)->nfixups].exp = (exp_);     \
    473      1.1  christos     (insn_)->fixup[(insn_)->nfixups].where = 0;        \
    474      1.1  christos     (insn_)->nfixups++;                                \
    475      1.1  christos   } while (0)
    476      1.1  christos 
    477      1.1  christos #define add_immx(insn_, words_, reloc_, exp_, nfixups_, len_) \
    478      1.1  christos   do { \
    479      1.1  christos     immxbuf[immxcnt].words[0] = (words_);                \
    480      1.1  christos     immxbuf[immxcnt].fixup[0].reloc = (reloc_);          \
    481      1.1  christos     immxbuf[immxcnt].fixup[0].exp = (exp_);              \
    482      1.1  christos     immxbuf[immxcnt].fixup[0].where = 0;                 \
    483      1.1  christos     immxbuf[immxcnt].nfixups = (nfixups_);               \
    484      1.1  christos     immxbuf[immxcnt].len = (len_);                       \
    485      1.1  christos     /* decrement insn->len: immx part handled separately \
    486      1.1  christos        from insn and must not be emited twice.  */       \
    487      1.1  christos     (insn_)->len -= 1;                                   \
    488      1.1  christos     incr_immxcnt ();                                     \
    489      1.1  christos   } while (0)
    490      1.1  christos 
    491      1.1  christos #define chk_imm(core_, imm_) \
    492      1.1  christos   (env.params.core == ELF_KVX_CORE_## core_ && opdef->type == (imm_))
    493      1.1  christos 
    494      1.1  christos   /* try to resolve the value */
    495      1.1  christos 
    496      1.1  christos   switch (tok->category)
    497      1.1  christos     {
    498      1.1  christos     case CAT_REGISTER:
    499      1.1  christos       op = S_GET_VALUE (str_hash_find (env.reg_hash, tok->tok));
    500      1.1  christos       op -= opdef->bias;
    501      1.1  christos       op >>= opdef->shift;
    502      1.1  christos       break;
    503      1.1  christos     case CAT_MODIFIER:
    504      1.1  christos       op = tok->val;
    505      1.1  christos       op -= opdef->bias;
    506      1.1  christos       op >>= opdef->shift;
    507      1.1  christos       break;
    508      1.1  christos     case CAT_IMMEDIATE:
    509      1.1  christos       {
    510      1.1  christos 	char *ilp_save = input_line_pointer;
    511      1.1  christos 	input_line_pointer = tok->tok;
    512  1.1.1.2  christos 	expressionS exp;
    513      1.1  christos 	expression (&exp);
    514      1.1  christos 	input_line_pointer = ilp_save;
    515      1.1  christos 
    516      1.1  christos 	/* We are dealing with a pseudo-function.  */
    517      1.1  christos 	if (tok->tok[0] == '@')
    518      1.1  christos 	  {
    519      1.1  christos 	    if (insn->nfixups == 0)
    520      1.1  christos 	      {
    521      1.1  christos 		expressionS reloc_arg;
    522      1.1  christos 		reloc_arg = exp;
    523      1.1  christos 		reloc_arg.X_op = O_symbol;
    524      1.1  christos 		struct pseudo_func *pf =
    525      1.1  christos 		  kvx_get_pseudo_func2 (exp.X_op_symbol, opdef);
    526      1.1  christos 		/* S64 uses LO10/UP27/EX27 format (3 words), with one reloc in each words (3) */
    527      1.1  christos 		/* S43 uses LO10/EX6/UP27 format (2 words), with 2 relocs in main syllabes and 1 in extra word */
    528      1.1  christos 		/* S37 uses LO10/UP27 format (2 words), with one reloc in each word (2) */
    529      1.1  christos 
    530      1.1  christos 		/* Beware that immxbuf must be filled in the same order as relocs should be emitted. */
    531      1.1  christos 
    532      1.1  christos 		if (pf->pseudo_relocs.reloc_type == S64_LO10_UP27_EX27
    533      1.1  christos 		    || pf->pseudo_relocs.reloc_type == S43_LO10_UP27_EX6
    534      1.1  christos 		    || pf->pseudo_relocs.reloc_type == S37_LO10_UP27)
    535      1.1  christos 		  {
    536      1.1  christos 		    add_fixup (insn, pf->pseudo_relocs.reloc_lo10, reloc_arg);
    537      1.1  christos 
    538      1.1  christos 		    insn->immx0 = immxcnt;
    539      1.1  christos 		    add_immx (insn, 0, pf->pseudo_relocs.reloc_up27,
    540      1.1  christos 			      reloc_arg, 1, 1);
    541      1.1  christos 		    immx_ready = 1;
    542      1.1  christos 		  }
    543      1.1  christos 		else if (pf->pseudo_relocs.reloc_type == S32_LO5_UP27)
    544      1.1  christos 		  {
    545      1.1  christos 		    add_fixup (insn, pf->pseudo_relocs.reloc_lo5, reloc_arg);
    546      1.1  christos 
    547      1.1  christos 		    insn->immx0 = immxcnt;
    548      1.1  christos 		    add_immx (insn, 0, pf->pseudo_relocs.reloc_up27,
    549      1.1  christos 			      reloc_arg, 1, 1);
    550      1.1  christos 		    immx_ready = 1;
    551      1.1  christos 		  }
    552      1.1  christos 		else if (pf->pseudo_relocs.reloc_type == S16)
    553      1.1  christos 		  add_fixup (insn, pf->pseudo_relocs.single, reloc_arg);
    554      1.1  christos 		else
    555      1.1  christos 		  as_fatal ("Unexpected fixup");
    556      1.1  christos 
    557      1.1  christos 		if (pf->pseudo_relocs.reloc_type == S64_LO10_UP27_EX27)
    558      1.1  christos 		  {
    559      1.1  christos 		    insn->immx1 = immxcnt;
    560      1.1  christos 		    add_immx (insn, 0, pf->pseudo_relocs.reloc_ex, reloc_arg,
    561      1.1  christos 			      1, 1);
    562      1.1  christos 		  }
    563      1.1  christos 		else if (pf->pseudo_relocs.reloc_type == S43_LO10_UP27_EX6)
    564      1.1  christos 		  add_fixup (insn, pf->pseudo_relocs.reloc_ex, reloc_arg);
    565      1.1  christos 	      }
    566      1.1  christos 	  }
    567      1.1  christos 	else
    568      1.1  christos 	  {
    569      1.1  christos 	    if (exp.X_op == O_constant)
    570      1.1  christos 	      {
    571      1.1  christos 		/* This is a immediate: either a regular immediate, or an
    572      1.1  christos 		   immediate that was saved in a variable through `.equ'.  */
    573      1.1  christos 		uint64_t sval = (int64_t) tok->val;
    574      1.1  christos 		op = opdef->flags & kvxSIGNED ? sval : tok->val;
    575      1.1  christos 		op >>= opdef->shift;
    576      1.1  christos 	      }
    577      1.1  christos 	    else if (exp.X_op == O_subtract)
    578      1.1  christos 	      as_fatal ("O_subtract not supported.");
    579      1.1  christos 	    else
    580      1.1  christos 	      {
    581      1.1  christos 
    582      1.1  christos 		/* This is a symbol which needs a relocation.  */
    583      1.1  christos 		if (insn->nfixups == 0)
    584      1.1  christos 		  {
    585      1.1  christos 		    if (chk_imm (KV3_1, Immediate_kv3_v1_pcrel17)
    586      1.1  christos 			|| chk_imm (KV3_2, Immediate_kv3_v2_pcrel17)
    587      1.1  christos 			|| chk_imm (KV4_1, Immediate_kv4_v1_pcrel17))
    588      1.1  christos 		      add_fixup (insn, BFD_RELOC_KVX_PCREL17, exp);
    589      1.1  christos 		    else if (chk_imm (KV3_1, Immediate_kv3_v1_pcrel27)
    590      1.1  christos 			     || chk_imm (KV3_2, Immediate_kv3_v2_pcrel27)
    591      1.1  christos 			     || chk_imm (KV4_1, Immediate_kv4_v1_pcrel27))
    592      1.1  christos 		      add_fixup (insn, BFD_RELOC_KVX_PCREL27, exp);
    593      1.1  christos 		    else if (chk_imm (KV3_1, Immediate_kv3_v1_wrapped32)
    594      1.1  christos 			     || chk_imm (KV3_2, Immediate_kv3_v2_wrapped32)
    595      1.1  christos 			     || chk_imm (KV4_1, Immediate_kv4_v1_wrapped32))
    596      1.1  christos 		      {
    597      1.1  christos 			add_fixup (insn, BFD_RELOC_KVX_S32_LO5, exp);
    598      1.1  christos 
    599      1.1  christos 			insn->immx0 = immxcnt;
    600      1.1  christos 			add_immx (insn, 0, BFD_RELOC_KVX_S32_UP27, exp, 1, 1);
    601      1.1  christos 
    602      1.1  christos 			immx_ready = 1;
    603      1.1  christos 		      }
    604      1.1  christos 		    else if (chk_imm (KV3_1, Immediate_kv3_v1_signed10)
    605      1.1  christos 			     || chk_imm (KV3_2, Immediate_kv3_v2_signed10)
    606      1.1  christos 			     || chk_imm (KV4_1, Immediate_kv4_v1_signed10))
    607      1.1  christos 		      add_fixup (insn, BFD_RELOC_KVX_S37_LO10, exp);
    608      1.1  christos 		    else if (chk_imm (KV3_1, Immediate_kv3_v1_signed37)
    609      1.1  christos 			     || chk_imm (KV3_2, Immediate_kv3_v2_signed37)
    610      1.1  christos 			     || chk_imm (KV4_1, Immediate_kv4_v1_signed37))
    611      1.1  christos 		      {
    612      1.1  christos 			add_fixup (insn, BFD_RELOC_KVX_S37_LO10, exp);
    613      1.1  christos 
    614      1.1  christos 			insn->immx0 = immxcnt;
    615      1.1  christos 			add_immx (insn, 0, BFD_RELOC_KVX_S37_UP27, exp, 1, 1);
    616      1.1  christos 
    617      1.1  christos 			immx_ready = 1;
    618      1.1  christos 		      }
    619      1.1  christos 		    else if (chk_imm (KV3_1, Immediate_kv3_v1_signed43)
    620      1.1  christos 			     || chk_imm (KV3_2, Immediate_kv3_v2_signed43)
    621      1.1  christos 			     || chk_imm (KV4_1, Immediate_kv4_v1_signed43))
    622      1.1  christos 		      {
    623      1.1  christos 			add_fixup (insn, BFD_RELOC_KVX_S43_LO10, exp);
    624      1.1  christos 			add_fixup (insn, BFD_RELOC_KVX_S43_EX6, exp);
    625      1.1  christos 
    626      1.1  christos 			insn->immx0 = immxcnt;
    627      1.1  christos 			add_immx (insn, insn->words[1],
    628      1.1  christos 				  BFD_RELOC_KVX_S43_UP27, exp, 1, 1);
    629      1.1  christos 
    630      1.1  christos 			immx_ready = 1;
    631      1.1  christos 		      }
    632      1.1  christos 		    else if (chk_imm (KV3_1, Immediate_kv3_v1_wrapped64)
    633      1.1  christos 			     || chk_imm (KV3_2, Immediate_kv3_v2_wrapped64)
    634      1.1  christos 			     || chk_imm (KV4_1, Immediate_kv4_v1_wrapped64))
    635      1.1  christos 		      {
    636      1.1  christos 			add_fixup (insn, BFD_RELOC_KVX_S64_LO10, exp);
    637      1.1  christos 
    638      1.1  christos 			insn->immx0 = immxcnt;
    639      1.1  christos 			add_immx (insn, insn->words[1],
    640      1.1  christos 				  BFD_RELOC_KVX_S64_UP27, exp, 1, 1);
    641      1.1  christos 
    642      1.1  christos 			insn->immx1 = immxcnt;
    643      1.1  christos 			add_immx (insn, insn->words[2],
    644      1.1  christos 				  BFD_RELOC_KVX_S64_EX27, exp, 1, 1);
    645      1.1  christos 
    646      1.1  christos 			immx_ready = 1;
    647      1.1  christos 		      }
    648      1.1  christos 		    else
    649      1.1  christos 		      as_fatal ("don't know how to generate a fixup record");
    650      1.1  christos 		    return immx_ready;
    651      1.1  christos 		  }
    652      1.1  christos 		else
    653      1.1  christos 		  as_fatal ("No room for fixup ");
    654      1.1  christos 	      }
    655      1.1  christos 	  }
    656      1.1  christos       }
    657      1.1  christos       break;
    658      1.1  christos     default:
    659      1.1  christos       break;
    660      1.1  christos     }
    661      1.1  christos 
    662      1.1  christos   for (int bf_idx = 0; bf_idx < bf_nb; bf_idx++)
    663      1.1  christos     {
    664      1.1  christos       uint64_t value =
    665      1.1  christos 	((uint64_t) op >> bfields[bf_idx].from_offset);
    666      1.1  christos       int j = 0;
    667      1.1  christos       int to_offset = bfields[bf_idx].to_offset;
    668      1.1  christos       value &= (1LL << bfields[bf_idx].size) - 1;
    669      1.1  christos       j = to_offset / 32;
    670      1.1  christos       to_offset = to_offset % 32;
    671      1.1  christos       insn->words[j] |= (value << to_offset) & 0xffffffff;
    672      1.1  christos     }
    673      1.1  christos 
    674      1.1  christos   return immx_ready;
    675      1.1  christos 
    676      1.1  christos #undef chk_imm
    677      1.1  christos #undef add_immx
    678      1.1  christos #undef add_fixup
    679      1.1  christos }
    680      1.1  christos 
    681      1.1  christos /*
    682      1.1  christos  * Given a set of operands and a matching instruction,
    683      1.1  christos  * assemble it
    684      1.1  christos  *
    685      1.1  christos  */
    686      1.1  christos static void
    687      1.1  christos assemble_insn (const struct kvxopc * opcode, struct token_list *tok, struct kvxinsn *insn)
    688      1.1  christos {
    689      1.1  christos   unsigned immx_ready = 0;
    690      1.1  christos 
    691      1.1  christos   memset (insn, 0, sizeof (*insn));
    692      1.1  christos   insn->opdef = opcode;
    693      1.1  christos   for (int i = 0; i < opcode->wordcount; i++)
    694      1.1  christos     {
    695      1.1  christos       insn->words[i] = opcode->codewords[i].opcode;
    696      1.1  christos       insn->len += 1;
    697      1.1  christos     }
    698      1.1  christos 
    699      1.1  christos   insn->immx0 = NOIMMX;
    700      1.1  christos   insn->immx1 = NOIMMX;
    701      1.1  christos 
    702      1.1  christos   struct token_list *tok_ = tok;
    703  1.1.1.2  christos   struct kvx_operand *const *format = opcode->format;
    704      1.1  christos 
    705      1.1  christos   while (tok_)
    706      1.1  christos     {
    707      1.1  christos       int ret = insert_operand (insn, *format, tok_);
    708      1.1  christos       immx_ready |= ret;
    709      1.1  christos       while ((tok_ = tok_->next) && tok_->category == CAT_SEPARATOR);
    710      1.1  christos       format++;
    711      1.1  christos     }
    712      1.1  christos 
    713      1.1  christos   // Handle immx if insert_operand did not already take care of that
    714      1.1  christos   if (!immx_ready)
    715      1.1  christos     {
    716      1.1  christos       for (int i = 0; i < opcode->wordcount; i++)
    717      1.1  christos 	{
    718      1.1  christos 	  if (opcode->codewords[i].flags & kvxOPCODE_FLAG_IMMX0)
    719      1.1  christos 	    {
    720      1.1  christos 	      insn->immx0 = immxcnt;
    721      1.1  christos 	      immxbuf[immxcnt].words[0] = insn->words[i];
    722      1.1  christos 	      immxbuf[immxcnt].nfixups = 0;
    723      1.1  christos 	      immxbuf[immxcnt].len = 1;
    724      1.1  christos 	      insn->len -= 1;
    725      1.1  christos 	      incr_immxcnt ();
    726      1.1  christos 	    }
    727      1.1  christos 	  if (opcode->codewords[i].flags & kvxOPCODE_FLAG_IMMX1)
    728      1.1  christos 	    {
    729      1.1  christos 	      insn->immx1 = immxcnt;
    730      1.1  christos 	      immxbuf[immxcnt].words[0] = insn->words[i];
    731      1.1  christos 	      immxbuf[immxcnt].nfixups = 0;
    732      1.1  christos 	      immxbuf[immxcnt].len = 1;
    733      1.1  christos 	      insn->len -= 1;
    734      1.1  christos 	      incr_immxcnt ();
    735      1.1  christos 	    }
    736      1.1  christos 	}
    737      1.1  christos     }
    738      1.1  christos }
    739      1.1  christos 
    740      1.1  christos /* Emit an instruction from the instruction array into the object
    741      1.1  christos  * file. INSN points to an element of the instruction array. STOPFLAG
    742      1.1  christos  * is true if this is the last instruction in the bundle.
    743      1.1  christos  *
    744      1.1  christos  * Only handles main syllables of bundle. Immediate extensions are
    745      1.1  christos  * handled by insert_operand.
    746      1.1  christos  */
    747      1.1  christos static void
    748      1.1  christos emit_insn (struct kvxinsn * insn, int insn_pos, int stopflag)
    749      1.1  christos {
    750      1.1  christos   char *f;
    751      1.1  christos   unsigned int image;
    752      1.1  christos 
    753      1.1  christos   /* if we are listing, attach frag to previous line.  */
    754      1.1  christos   if (listing)
    755      1.1  christos     listing_prev_line ();
    756      1.1  christos 
    757      1.1  christos   /* Update text size for lane parity checking.  */
    758      1.1  christos   set_byte_counter (now_seg, (get_byte_counter (now_seg) + (insn->len * 4)));
    759      1.1  christos 
    760      1.1  christos   /* allocate space in the fragment.  */
    761      1.1  christos   f = frag_more (insn->len * 4);
    762      1.1  christos 
    763      1.1  christos   /* spit out bits.  */
    764      1.1  christos   for (int i = 0; i < insn->len; i++)
    765      1.1  christos     {
    766      1.1  christos       image = insn->words[i];
    767      1.1  christos 
    768      1.1  christos       /* Handle bundle parallel bit. */ ;
    769      1.1  christos       if ((i == insn->len - 1) && stopflag)
    770      1.1  christos 	image &= ~PARALLEL_BIT;
    771      1.1  christos       else
    772      1.1  christos 	image |= PARALLEL_BIT;
    773      1.1  christos 
    774      1.1  christos       /* Emit the instruction image. */
    775      1.1  christos       md_number_to_chars (f + (i * 4), image, 4);
    776      1.1  christos     }
    777      1.1  christos 
    778      1.1  christos   /* generate fixup records */
    779      1.1  christos 
    780      1.1  christos   for (int i = 0; i < insn->nfixups; i++)
    781      1.1  christos     {
    782      1.1  christos       int size, pcrel;
    783      1.1  christos       reloc_howto_type *reloc_howto =
    784      1.1  christos 	bfd_reloc_type_lookup (stdoutput, insn->fixup[i].reloc);
    785      1.1  christos       assert (reloc_howto);
    786      1.1  christos       size = bfd_get_reloc_size (reloc_howto);
    787      1.1  christos       pcrel = reloc_howto->pc_relative;
    788      1.1  christos 
    789      1.1  christos       /* In case the PCREL relocation is not for the first insn in the
    790      1.1  christos          bundle, we have to offset it.  The pc used by the hardware
    791      1.1  christos          references a bundle and not separate insn.
    792      1.1  christos        */
    793      1.1  christos       assert (!(insn_pos == -1 && pcrel));
    794      1.1  christos       if (pcrel && insn_pos > 0)
    795      1.1  christos 	insn->fixup[i].exp.X_add_number += insn_pos * 4;
    796      1.1  christos 
    797      1.1  christos       fixS *fixup = fix_new_exp (frag_now,
    798      1.1  christos 				 f - frag_now->fr_literal +
    799      1.1  christos 				 insn->fixup[i].where,
    800      1.1  christos 				 size,
    801      1.1  christos 				 &(insn->fixup[i].exp),
    802      1.1  christos 				 pcrel,
    803      1.1  christos 				 insn->fixup[i].reloc);
    804      1.1  christos       /*
    805      1.1  christos        * Set this bit so that large value can still be
    806      1.1  christos        * handled. Without it, assembler will fail in fixup_segment
    807      1.1  christos        * when it checks there is enough bits to store the value. As we
    808      1.1  christos        * usually split our reloc across different words, it may think
    809      1.1  christos        * that 4 bytes are not enough for large value. This simply
    810      1.1  christos        * skips the tests
    811      1.1  christos        */
    812      1.1  christos       fixup->fx_no_overflow = 1;
    813      1.1  christos     }
    814      1.1  christos }
    815      1.1  christos 
    816      1.1  christos 
    817      1.1  christos /* Called for any expression that can not be recognized.  When the
    818      1.1  christos  * function is called, `input_line_pointer' will point to the start of
    819      1.1  christos  * the expression.  */
    820      1.1  christos /* FIXME: Should be done by the parser */
    821      1.1  christos void
    822      1.1  christos md_operand (expressionS * e)
    823      1.1  christos {
    824      1.1  christos   /* enum pseudo_type pseudo_type; */
    825      1.1  christos   /* char *name = NULL; */
    826      1.1  christos   size_t len;
    827      1.1  christos   int ch, i;
    828      1.1  christos 
    829      1.1  christos   switch (*input_line_pointer)
    830      1.1  christos     {
    831      1.1  christos     case '@':
    832      1.1  christos       /* Find what relocation pseudo-function we're dealing with. */
    833      1.1  christos       /* pseudo_type = 0; */
    834      1.1  christos       ch = *++input_line_pointer;
    835      1.1  christos       for (i = 0; i < kvx_core_info->nb_pseudo_funcs; ++i)
    836      1.1  christos 	if (kvx_core_info->pseudo_funcs[i].name && kvx_core_info->pseudo_funcs[i].name[0] == ch)
    837      1.1  christos 	  {
    838      1.1  christos 	    len = strlen (kvx_core_info->pseudo_funcs[i].name);
    839      1.1  christos 	    if (strncmp (kvx_core_info->pseudo_funcs[i].name + 1,
    840      1.1  christos 			 input_line_pointer + 1, len - 1) == 0
    841      1.1  christos 		&& !is_part_of_name (input_line_pointer[len]))
    842      1.1  christos 	      {
    843      1.1  christos 		input_line_pointer += len;
    844      1.1  christos 		break;
    845      1.1  christos 	      }
    846      1.1  christos 	  }
    847      1.1  christos       SKIP_WHITESPACE ();
    848      1.1  christos       if (*input_line_pointer != '(')
    849      1.1  christos 	{
    850      1.1  christos 	  as_bad ("Expected '('");
    851      1.1  christos 	  goto err;
    852      1.1  christos 	}
    853      1.1  christos       /* Skip '('.  */
    854      1.1  christos       ++input_line_pointer;
    855      1.1  christos       if (!kvx_core_info->pseudo_funcs[i].pseudo_relocs.has_no_arg)
    856      1.1  christos 	expression (e);
    857      1.1  christos       if (*input_line_pointer++ != ')')
    858      1.1  christos 	{
    859      1.1  christos 	  as_bad ("Missing ')'");
    860      1.1  christos 	  goto err;
    861      1.1  christos 	}
    862      1.1  christos       if (!kvx_core_info->pseudo_funcs[i].pseudo_relocs.has_no_arg)
    863      1.1  christos 	{
    864      1.1  christos 	  if (e->X_op != O_symbol)
    865      1.1  christos 	    as_fatal ("Illegal combination of relocation functions");
    866      1.1  christos 	}
    867      1.1  christos       /* Make sure gas doesn't get rid of local symbols that are used
    868      1.1  christos          in relocs.  */
    869      1.1  christos       e->X_op = O_pseudo_fixup;
    870      1.1  christos       e->X_op_symbol = kvx_core_info->pseudo_funcs[i].sym;
    871      1.1  christos       break;
    872      1.1  christos 
    873      1.1  christos     default:
    874      1.1  christos       break;
    875      1.1  christos     }
    876      1.1  christos   return;
    877      1.1  christos 
    878      1.1  christos err:
    879      1.1  christos   ignore_rest_of_line ();
    880      1.1  christos }
    881      1.1  christos 
    882      1.1  christos /*
    883      1.1  christos  * Return the Bundling type for an insn.
    884      1.1  christos  */
    885      1.1  christos static int
    886      1.1  christos find_bundling (const struct kvxinsn * insn)
    887      1.1  christos {
    888      1.1  christos   return insn->opdef->bundling;
    889      1.1  christos }
    890      1.1  christos 
    891      1.1  christos static int
    892      1.1  christos find_reservation (const struct kvxinsn * insn)
    893      1.1  christos {
    894      1.1  christos   return insn->opdef->reservation;
    895      1.1  christos }
    896      1.1  christos 
    897      1.1  christos static struct kvxopc *
    898      1.1  christos assemble_tokens (struct token_list *tok_list)
    899      1.1  christos {
    900      1.1  christos   assert (tok_list != NULL);
    901      1.1  christos   struct token_list *toks = tok_list;
    902      1.1  christos 
    903      1.1  christos   /* make sure there is room in instruction buffer */
    904      1.1  christos   /* Was KVXMAXBUNDLEISSUE, changed because of NOPs */
    905      1.1  christos   if (insncnt >= KVXMAXBUNDLEWORDS)
    906      1.1  christos     as_fatal ("[assemble_tokens]: too many instructions in bundle.");
    907      1.1  christos 
    908      1.1  christos   /* TODO: Merge */
    909      1.1  christos   struct kvxinsn *insn;
    910      1.1  christos   insn = insbuf + insncnt;
    911      1.1  christos 
    912      1.1  christos   /* The formats table registers the modifier into the opcode, therefore we need
    913      1.1  christos      to fuse both before looking up the opcodes hashtable.  */
    914      1.1  christos   char *opcode = NULL;
    915      1.1  christos 
    916      1.1  christos   opcode = toks->tok;
    917      1.1  christos   toks = toks->next;
    918      1.1  christos 
    919      1.1  christos   while (toks && toks->category == CAT_SEPARATOR)
    920      1.1  christos     toks = toks->next;
    921      1.1  christos 
    922      1.1  christos   /* Find the format requested by the instruction.  */
    923      1.1  christos   struct kvxopc *format_tbl = str_hash_find (env.opcode_hash, opcode);
    924      1.1  christos   struct kvxopc *format = NULL;
    925      1.1  christos 
    926      1.1  christos   struct token_list *toks_ = toks;
    927      1.1  christos 
    928      1.1  christos   while (!format && format_tbl && STREQ (opcode, format_tbl->as_op))
    929      1.1  christos   {
    930      1.1  christos     for (int i = 0 ; toks_ && format_tbl->format[i]
    931      1.1  christos 	&& toks_->class_id == format_tbl->format[i]->type ;)
    932      1.1  christos       {
    933      1.1  christos 	toks_ = toks_->next;
    934      1.1  christos 	while (toks_ && toks_->category == CAT_SEPARATOR)
    935      1.1  christos 	  toks_ = toks_->next;
    936      1.1  christos 	i += 1;
    937      1.1  christos       }
    938      1.1  christos 
    939      1.1  christos     if (!toks_)
    940      1.1  christos       format = format_tbl;
    941      1.1  christos     else
    942      1.1  christos       {
    943      1.1  christos 	toks_ = toks;
    944      1.1  christos 	format_tbl++;
    945      1.1  christos       }
    946      1.1  christos   }
    947      1.1  christos 
    948      1.1  christos   assert (format != NULL);
    949      1.1  christos 
    950      1.1  christos   assemble_insn (format, toks, insn);
    951      1.1  christos   insncnt++;
    952      1.1  christos 
    953      1.1  christos   return NULL;
    954      1.1  christos }
    955      1.1  christos 
    956      1.1  christos /*
    957      1.1  christos  * Write in buf at most buf_size.
    958      1.1  christos  * Returns the number of writen characters.
    959      1.1  christos  */
    960      1.1  christos static int ATTRIBUTE_UNUSED
    961      1.1  christos insn_syntax (struct kvxopc * op, char *buf, int buf_size)
    962      1.1  christos {
    963      1.1  christos   int chars = snprintf (buf, buf_size, "%s ", op->as_op);
    964      1.1  christos   const char *fmtp = op->fmtstring;
    965      1.1  christos   char ch = 0;
    966      1.1  christos 
    967      1.1  christos   for (int i = 0; op->format[i]; i++)
    968      1.1  christos     {
    969      1.1  christos       int type = op->format[i]->type;
    970      1.1  christos       const char *type_name = TOKEN_NAME (type);
    971      1.1  christos       int offset = 0;
    972      1.1  christos 
    973      1.1  christos       for (int j = 0 ; type_name[j] ; ++j)
    974      1.1  christos 	if (type_name[j] == '_')
    975      1.1  christos 	  offset = j + 1;
    976      1.1  christos 
    977      1.1  christos       /* Print characters in the format string up to the following * % or nul. */
    978      1.1  christos       while ((chars < buf_size) && (ch = *fmtp) && ch != '%')
    979      1.1  christos 	{
    980      1.1  christos 	  buf[chars++] = ch;
    981      1.1  christos 	  fmtp++;
    982      1.1  christos 	}
    983      1.1  christos 
    984      1.1  christos       /* Skip past %s */
    985      1.1  christos       if (ch == '%')
    986      1.1  christos 	{
    987      1.1  christos 	  ch = *fmtp++;
    988      1.1  christos 	  fmtp++;
    989      1.1  christos 	}
    990      1.1  christos 
    991      1.1  christos       chars += snprintf (&buf[chars], buf_size - chars, "%s", type_name + offset);
    992      1.1  christos     }
    993      1.1  christos 
    994      1.1  christos   /* Print trailing characters in the format string, if any */
    995      1.1  christos   while ((chars < buf_size) && (ch = *fmtp))
    996      1.1  christos     {
    997      1.1  christos       buf[chars++] = ch;
    998      1.1  christos       fmtp++;
    999      1.1  christos     }
   1000      1.1  christos 
   1001      1.1  christos   if (chars < buf_size)
   1002      1.1  christos     buf[chars++] = '\0';
   1003      1.1  christos   else
   1004      1.1  christos     buf[buf_size - 1] = '\0';
   1005      1.1  christos 
   1006      1.1  christos   return chars;
   1007      1.1  christos }
   1008      1.1  christos 
   1009      1.1  christos #define ASM_CHARS_MAX (71)
   1010      1.1  christos 
   1011      1.1  christos static void
   1012      1.1  christos kvx_print_insn (struct kvxopc * op ATTRIBUTE_UNUSED)
   1013      1.1  christos {
   1014      1.1  christos   char asm_str[ASM_CHARS_MAX];
   1015      1.1  christos   int chars = insn_syntax (op, asm_str, ASM_CHARS_MAX);
   1016      1.1  christos   const char *insn_type = "UNKNOWN";
   1017      1.1  christos   const char *insn_mode = "";
   1018      1.1  christos 
   1019      1.1  christos   for (int i = chars - 1; i < ASM_CHARS_MAX - 1; i++)
   1020      1.1  christos     asm_str[i] = '-';
   1021      1.1  christos 
   1022      1.1  christos   /* This is a hack which works because the Bundling is the same for all cores
   1023      1.1  christos      for now.  */
   1024  1.1.1.2  christos   switch (op->bundling)
   1025      1.1  christos     {
   1026      1.1  christos     case Bundling_kv3_v1_ALL:
   1027      1.1  christos       insn_type = "ALL  ";
   1028      1.1  christos       break;
   1029      1.1  christos     case Bundling_kv3_v1_BCU:
   1030      1.1  christos       insn_type = "BCU  ";
   1031      1.1  christos       break;
   1032      1.1  christos     case Bundling_kv3_v1_TCA:
   1033      1.1  christos       insn_type = "TCA  ";
   1034      1.1  christos       break;
   1035      1.1  christos     case Bundling_kv3_v1_FULL:
   1036      1.1  christos     case Bundling_kv3_v1_FULL_X:
   1037      1.1  christos     case Bundling_kv3_v1_FULL_Y:
   1038      1.1  christos       insn_type = "FULL ";
   1039      1.1  christos       break;
   1040      1.1  christos     case Bundling_kv3_v1_LITE:
   1041      1.1  christos     case Bundling_kv3_v1_LITE_X:
   1042      1.1  christos     case Bundling_kv3_v1_LITE_Y:
   1043      1.1  christos       insn_type = "LITE ";
   1044      1.1  christos       break;
   1045      1.1  christos     case Bundling_kv3_v1_TINY:
   1046      1.1  christos     case Bundling_kv3_v1_TINY_X:
   1047      1.1  christos     case Bundling_kv3_v1_TINY_Y:
   1048      1.1  christos       insn_type = "TINY ";
   1049      1.1  christos       break;
   1050      1.1  christos     case Bundling_kv3_v1_MAU:
   1051      1.1  christos     case Bundling_kv3_v1_MAU_X:
   1052      1.1  christos     case Bundling_kv3_v1_MAU_Y:
   1053      1.1  christos       insn_type = "MAU  ";
   1054      1.1  christos       break;
   1055      1.1  christos     case Bundling_kv3_v1_LSU:
   1056      1.1  christos     case Bundling_kv3_v1_LSU_X:
   1057      1.1  christos     case Bundling_kv3_v1_LSU_Y:
   1058      1.1  christos       insn_type = "LSU  ";
   1059      1.1  christos       break;
   1060      1.1  christos     case Bundling_kv3_v1_NOP:
   1061      1.1  christos       insn_type = "NOP  ";
   1062      1.1  christos       break;
   1063      1.1  christos     default:
   1064      1.1  christos       as_fatal ("Unhandled Bundling class %d", op->bundling);
   1065      1.1  christos     }
   1066      1.1  christos 
   1067      1.1  christos   if (op->codewords[0].flags & kvxOPCODE_FLAG_MODE64
   1068      1.1  christos       && op->codewords[0].flags & kvxOPCODE_FLAG_MODE32)
   1069      1.1  christos     insn_mode = "32 and 64";
   1070      1.1  christos   else if (op->codewords[0].flags & kvxOPCODE_FLAG_MODE64)
   1071      1.1  christos     insn_mode = "64";
   1072      1.1  christos   else if (op->codewords[0].flags & kvxOPCODE_FLAG_MODE32)
   1073      1.1  christos     insn_mode = "32";
   1074      1.1  christos   else
   1075      1.1  christos     as_fatal ("Unknown instruction mode.");
   1076      1.1  christos 
   1077      1.1  christos   printf ("%s | syllables: %d | type: %s | mode: %s bits\n", asm_str,
   1078      1.1  christos 	  op->wordcount, insn_type, insn_mode);
   1079      1.1  christos }
   1080      1.1  christos 
   1081      1.1  christos /* Comparison function compatible with qsort.  This is used to sort the issues
   1082      1.1  christos    into the right order.  */
   1083      1.1  christos static int
   1084      1.1  christos kvxinsn_compare (const void *a, const void *b)
   1085      1.1  christos {
   1086      1.1  christos   struct kvxinsn *kvxinsn_a = *(struct kvxinsn **) a;
   1087      1.1  christos   struct kvxinsn *kvxinsn_b = *(struct kvxinsn **) b;
   1088      1.1  christos   int bundling_a = find_bundling (kvxinsn_a);
   1089      1.1  christos   int bundling_b = find_bundling (kvxinsn_b);
   1090      1.1  christos   int order_a = kvxinsn_a->order;
   1091      1.1  christos   int order_b = kvxinsn_b->order;
   1092      1.1  christos   if (bundling_a != bundling_b)
   1093      1.1  christos     return (bundling_b < bundling_a) - (bundling_a < bundling_b);
   1094      1.1  christos   return (order_b < order_a) - (order_a < order_b);
   1095      1.1  christos }
   1096      1.1  christos 
   1097      1.1  christos static void
   1098      1.1  christos kvx_reorder_bundle (struct kvxinsn *bundle_insn[], int bundle_insncnt)
   1099      1.1  christos {
   1100      1.1  christos   enum
   1101      1.1  christos   { EXU_BCU, EXU_TCA, EXU_ALU0, EXU_ALU1, EXU_MAU, EXU_LSU, EXU__ };
   1102      1.1  christos   struct kvxinsn *issued[EXU__];
   1103      1.1  christos   int tag, exu;
   1104      1.1  christos 
   1105      1.1  christos   memset (issued, 0, sizeof (issued));
   1106      1.1  christos   for (int i = 0; i < bundle_insncnt; i++)
   1107      1.1  christos     {
   1108      1.1  christos       struct kvxinsn *kvxinsn = bundle_insn[i];
   1109      1.1  christos       tag = -1, exu = -1;
   1110      1.1  christos       /* This is a hack. It works because all the Bundling are the same for all
   1111      1.1  christos          cores for now.  */
   1112  1.1.1.2  christos       switch (find_bundling (kvxinsn))
   1113      1.1  christos 	{
   1114      1.1  christos 	case Bundling_kv3_v1_ALL:
   1115      1.1  christos 	  if (bundle_insncnt > 1)
   1116      1.1  christos 	    as_fatal ("Too many ops in a single op bundle");
   1117      1.1  christos 	  issued[0] = kvxinsn;
   1118      1.1  christos 	  break;
   1119      1.1  christos 	case Bundling_kv3_v1_BCU:
   1120      1.1  christos 	  if (!issued[EXU_BCU])
   1121      1.1  christos 	    issued[EXU_BCU] = kvxinsn;
   1122      1.1  christos 	  else
   1123      1.1  christos 	    as_fatal ("More than one BCU instruction in bundle");
   1124      1.1  christos 	  break;
   1125      1.1  christos 	case Bundling_kv3_v1_TCA:
   1126      1.1  christos 	  if (!issued[EXU_TCA])
   1127      1.1  christos 	    issued[EXU_TCA] = kvxinsn;
   1128      1.1  christos 	  else
   1129      1.1  christos 	    as_fatal ("More than one TCA instruction in bundle");
   1130      1.1  christos 	  break;
   1131      1.1  christos 	case Bundling_kv3_v1_FULL:
   1132      1.1  christos 	case Bundling_kv3_v1_FULL_X:
   1133      1.1  christos 	case Bundling_kv3_v1_FULL_Y:
   1134      1.1  christos 	  if (!issued[EXU_ALU0])
   1135      1.1  christos 	    {
   1136      1.1  christos 	      issued[EXU_ALU0] = kvxinsn;
   1137      1.1  christos 	      tag = Modifier_kv3_v1_exunum_ALU0;
   1138      1.1  christos 	      exu = EXU_ALU0;
   1139      1.1  christos 	    }
   1140      1.1  christos 	  else
   1141      1.1  christos 	    as_fatal ("More than one ALU FULL instruction in bundle");
   1142      1.1  christos 	  break;
   1143      1.1  christos 	case Bundling_kv3_v1_LITE:
   1144      1.1  christos 	case Bundling_kv3_v1_LITE_X:
   1145      1.1  christos 	case Bundling_kv3_v1_LITE_Y:
   1146      1.1  christos 	  if (!issued[EXU_ALU0])
   1147      1.1  christos 	    {
   1148      1.1  christos 	      issued[EXU_ALU0] = kvxinsn;
   1149      1.1  christos 	      tag = Modifier_kv3_v1_exunum_ALU0;
   1150      1.1  christos 	      exu = EXU_ALU0;
   1151      1.1  christos 	    }
   1152      1.1  christos 	  else if (!issued[EXU_ALU1])
   1153      1.1  christos 	    {
   1154      1.1  christos 	      issued[EXU_ALU1] = kvxinsn;
   1155      1.1  christos 	      tag = Modifier_kv3_v1_exunum_ALU1;
   1156      1.1  christos 	      exu = EXU_ALU1;
   1157      1.1  christos 	    }
   1158      1.1  christos 	  else
   1159      1.1  christos 	    as_fatal ("Too many ALU FULL or LITE instructions in bundle");
   1160      1.1  christos 	  break;
   1161      1.1  christos 	case Bundling_kv3_v1_MAU:
   1162      1.1  christos 	case Bundling_kv3_v1_MAU_X:
   1163      1.1  christos 	case Bundling_kv3_v1_MAU_Y:
   1164      1.1  christos 	  if (!issued[EXU_MAU])
   1165      1.1  christos 	    {
   1166      1.1  christos 	      issued[EXU_MAU] = kvxinsn;
   1167      1.1  christos 	      tag = Modifier_kv3_v1_exunum_MAU;
   1168      1.1  christos 	      exu = EXU_MAU;
   1169      1.1  christos 	    }
   1170      1.1  christos 	  else
   1171      1.1  christos 	    as_fatal ("More than one MAU instruction in bundle");
   1172      1.1  christos 	  break;
   1173      1.1  christos 	case Bundling_kv3_v1_LSU:
   1174      1.1  christos 	case Bundling_kv3_v1_LSU_X:
   1175      1.1  christos 	case Bundling_kv3_v1_LSU_Y:
   1176      1.1  christos 	  if (!issued[EXU_LSU])
   1177      1.1  christos 	    {
   1178      1.1  christos 	      issued[EXU_LSU] = kvxinsn;
   1179      1.1  christos 	      tag = Modifier_kv3_v1_exunum_LSU;
   1180      1.1  christos 	      exu = EXU_LSU;
   1181      1.1  christos 	    }
   1182      1.1  christos 	  else
   1183      1.1  christos 	    as_fatal ("More than one LSU instruction in bundle");
   1184      1.1  christos 	  break;
   1185      1.1  christos 	case Bundling_kv3_v1_TINY:
   1186      1.1  christos 	case Bundling_kv3_v1_TINY_X:
   1187      1.1  christos 	case Bundling_kv3_v1_TINY_Y:
   1188      1.1  christos 	case Bundling_kv3_v1_NOP:
   1189      1.1  christos 	  if (!issued[EXU_ALU0])
   1190      1.1  christos 	    {
   1191      1.1  christos 	      issued[EXU_ALU0] = kvxinsn;
   1192      1.1  christos 	      tag = Modifier_kv3_v1_exunum_ALU0;
   1193      1.1  christos 	      exu = EXU_ALU0;
   1194      1.1  christos 	    }
   1195      1.1  christos 	  else if (!issued[EXU_ALU1])
   1196      1.1  christos 	    {
   1197      1.1  christos 	      issued[EXU_ALU1] = kvxinsn;
   1198      1.1  christos 	      tag = Modifier_kv3_v1_exunum_ALU1;
   1199      1.1  christos 	      exu = EXU_ALU1;
   1200      1.1  christos 	    }
   1201      1.1  christos 	  else if (!issued[EXU_MAU])
   1202      1.1  christos 	    {
   1203      1.1  christos 	      issued[EXU_MAU] = kvxinsn;
   1204      1.1  christos 	      tag = Modifier_kv3_v1_exunum_MAU;
   1205      1.1  christos 	      exu = EXU_MAU;
   1206      1.1  christos 	    }
   1207      1.1  christos 	  else if (!issued[EXU_LSU])
   1208      1.1  christos 	    {
   1209      1.1  christos 	      issued[EXU_LSU] = kvxinsn;
   1210      1.1  christos 	      tag = Modifier_kv3_v1_exunum_LSU;
   1211      1.1  christos 	      exu = EXU_LSU;
   1212      1.1  christos 	    }
   1213      1.1  christos 	  else
   1214      1.1  christos 	    as_fatal ("Too many ALU instructions in bundle");
   1215      1.1  christos 	  break;
   1216      1.1  christos 	default:
   1217      1.1  christos 	  as_fatal ("Unhandled Bundling class %d", find_bundling (kvxinsn));
   1218      1.1  christos 	}
   1219      1.1  christos       if (tag >= 0)
   1220      1.1  christos 	{
   1221      1.1  christos 	  if (issued[exu]->immx0 != NOIMMX)
   1222      1.1  christos 	    immxbuf[issued[exu]->immx0].words[0] |= (tag << 27);
   1223      1.1  christos 	  if (issued[exu]->immx1 != NOIMMX)
   1224      1.1  christos 	    immxbuf[issued[exu]->immx1].words[0] |= (tag << 27);
   1225      1.1  christos 	}
   1226      1.1  christos     }
   1227      1.1  christos 
   1228      1.1  christos   int i;
   1229      1.1  christos   for (i = 0, exu = 0; exu < EXU__; exu++)
   1230      1.1  christos     {
   1231      1.1  christos       if (issued[exu])
   1232      1.1  christos 	bundle_insn[i++] = issued[exu];
   1233      1.1  christos     }
   1234      1.1  christos   if (i != bundle_insncnt)
   1235      1.1  christos     as_fatal ("Mismatch between bundle and issued instructions");
   1236      1.1  christos }
   1237      1.1  christos 
   1238      1.1  christos static void
   1239      1.1  christos kvx_check_resource_usage (struct kvxinsn **bundle_insn, int bundle_insncnt)
   1240      1.1  christos {
   1241      1.1  christos   const int reservation_table_len =
   1242      1.1  christos     (kvx_core_info->reservation_table_lines * kvx_core_info->resource_max);
   1243      1.1  christos   const int *resources = kvx_core_info->resources;
   1244      1.1  christos   int *resources_used =
   1245      1.1  christos     malloc (reservation_table_len * sizeof (int));
   1246      1.1  christos   memset (resources_used, 0, reservation_table_len * sizeof (int));
   1247      1.1  christos 
   1248      1.1  christos   for (int i = 0; i < bundle_insncnt; i++)
   1249      1.1  christos   {
   1250      1.1  christos     int insn_reservation = find_reservation (bundle_insn[i]);
   1251      1.1  christos     int reservation = insn_reservation & 0xff;
   1252      1.1  christos     const int *reservation_table = kvx_core_info->reservation_table_table[reservation];
   1253      1.1  christos     for (int j = 0; j < reservation_table_len; j++)
   1254      1.1  christos       resources_used[j] += reservation_table[j];
   1255      1.1  christos   }
   1256      1.1  christos 
   1257      1.1  christos   for (int i = 0; i < kvx_core_info->reservation_table_lines; i++)
   1258      1.1  christos     {
   1259      1.1  christos       for (int j = 0; j < kvx_core_info->resource_max; j++)
   1260      1.1  christos 	if (resources_used[(i * kvx_core_info->resource_max) + j] > resources[j])
   1261      1.1  christos 	  {
   1262      1.1  christos 	    int v = resources_used[(i * kvx_core_info->resource_max) + j];
   1263      1.1  christos 	    free (resources_used);
   1264      1.1  christos 	    as_fatal ("Resource %s over-used in bundle: %d used, %d available",
   1265      1.1  christos 		kvx_core_info->resource_names[j], v, resources[j]);
   1266      1.1  christos 	  }
   1267      1.1  christos   }
   1268      1.1  christos   free (resources_used);
   1269      1.1  christos }
   1270      1.1  christos 
   1271      1.1  christos /*
   1272      1.1  christos  * Called by core to assemble a single line
   1273      1.1  christos  */
   1274      1.1  christos void
   1275      1.1  christos md_assemble (char *line)
   1276      1.1  christos {
   1277      1.1  christos   char *line_cursor = line;
   1278      1.1  christos 
   1279      1.1  christos   if (get_byte_counter (now_seg) & 3)
   1280      1.1  christos     as_fatal ("code segment not word aligned in md_assemble");
   1281      1.1  christos 
   1282  1.1.1.2  christos   while (is_whitespace (line_cursor[0]))
   1283      1.1  christos     line_cursor++;
   1284      1.1  christos 
   1285      1.1  christos   /* ;; was converted to "be" by line hook          */
   1286      1.1  christos   /* here we look for the bundle end                */
   1287      1.1  christos   /* and actually output any instructions in bundle */
   1288      1.1  christos   /* also we need to implement the stop bit         */
   1289      1.1  christos   /* check for bundle end */
   1290      1.1  christos   if (strncmp (line_cursor, "be", 2) == 0)
   1291      1.1  christos   {
   1292      1.1  christos     inside_bundle = 0;
   1293      1.1  christos     //int sec_align = bfd_get_section_alignment(stdoutput, now_seg);
   1294      1.1  christos     /* Was KVXMAXBUNDLEISSUE, changed because of NOPs */
   1295      1.1  christos     struct kvxinsn *bundle_insn[KVXMAXBUNDLEWORDS];
   1296      1.1  christos     int bundle_insncnt = 0;
   1297      1.1  christos     int syllables = 0;
   1298      1.1  christos     int entry;
   1299      1.1  christos 
   1300      1.1  christos #ifdef OBJ_ELF
   1301      1.1  christos     /* Emit Dwarf debug line information */
   1302      1.1  christos     dwarf2_emit_insn (0);
   1303      1.1  christos #endif
   1304      1.1  christos     for (int j = 0; j < insncnt; j++)
   1305      1.1  christos     {
   1306      1.1  christos       insbuf[j].order = j;
   1307      1.1  christos       bundle_insn[bundle_insncnt++] = &insbuf[j];
   1308      1.1  christos       syllables += insbuf[j].len;
   1309      1.1  christos     }
   1310      1.1  christos 
   1311      1.1  christos     if (syllables + immxcnt > KVXMAXBUNDLEWORDS)
   1312      1.1  christos       as_fatal ("Bundle has too many syllables : %d instead of %d",
   1313      1.1  christos 	  syllables + immxcnt, KVXMAXBUNDLEWORDS);
   1314      1.1  christos 
   1315      1.1  christos     if (env.opts.check_resource_usage)
   1316      1.1  christos       kvx_check_resource_usage (bundle_insn, bundle_insncnt);
   1317      1.1  christos 
   1318      1.1  christos     /* Reorder and check the bundle.  */
   1319      1.1  christos     if (!env.opts.generate_illegal_code)
   1320      1.1  christos     {
   1321      1.1  christos       /* Sort the bundle_insn in order of bundling. */
   1322      1.1  christos       qsort (bundle_insn, bundle_insncnt, sizeof (struct kvxinsn *), kvxinsn_compare);
   1323      1.1  christos 
   1324      1.1  christos       kvx_reorder_bundle (bundle_insn, bundle_insncnt);
   1325      1.1  christos     }
   1326      1.1  christos 
   1327      1.1  christos     /* The ordering of the insns has been set correctly in bundle_insn. */
   1328      1.1  christos     for (int i = 0; i < bundle_insncnt; i++)
   1329      1.1  christos     {
   1330      1.1  christos       emit_insn (bundle_insn[i], i, (i == bundle_insncnt + immxcnt - 1));
   1331      1.1  christos       bundle_insn[i]->written = 1;
   1332      1.1  christos     }
   1333      1.1  christos 
   1334      1.1  christos     // Emit immx, ordering them by EXU tags, 0 to 3
   1335      1.1  christos     entry = 0;
   1336      1.1  christos     for (int tag = 0; tag < 4; tag++)
   1337      1.1  christos     {
   1338      1.1  christos       for (int j = 0; j < immxcnt; j++)
   1339      1.1  christos       {
   1340      1.1  christos #define kv3_exunum2_fld(x) (int)(((unsigned int)(x) >> 27) & 0x3)
   1341      1.1  christos 	if (kv3_exunum2_fld (immxbuf[j].words[0]) == tag)
   1342      1.1  christos 	{
   1343      1.1  christos 	  assert (immxbuf[j].written == 0);
   1344      1.1  christos 	  int insn_pos = bundle_insncnt + entry;
   1345      1.1  christos 	  emit_insn (&(immxbuf[j]), insn_pos, entry == immxcnt - 1);
   1346      1.1  christos 	  immxbuf[j].written = 1;
   1347      1.1  christos 	  entry++;
   1348      1.1  christos 	}
   1349      1.1  christos #undef kv3_exunum2_fld
   1350      1.1  christos       }
   1351      1.1  christos     }
   1352      1.1  christos     if (entry != immxcnt)
   1353      1.1  christos       as_fatal ("%d IMMX produced, only %d emitted.", immxcnt, entry);
   1354      1.1  christos 
   1355      1.1  christos     /* The debug label that appear in the middle of bundles
   1356      1.1  christos        had better appear to be attached to the next
   1357      1.1  christos        bundle. This is because usually these labels point to
   1358      1.1  christos        the first instruction where some condition is met. If
   1359      1.1  christos        the label isn't handled this way it will be attached to
   1360      1.1  christos        the current bundle which is wrong as the corresponding
   1361      1.1  christos        instruction wasn't executed yet. */
   1362      1.1  christos     while (label_fixes)
   1363      1.1  christos     {
   1364      1.1  christos       struct label_fix *fix = label_fixes;
   1365      1.1  christos 
   1366      1.1  christos       label_fixes = fix->next;
   1367      1.1  christos       symbol_set_value_now (fix->sym);
   1368      1.1  christos       free (fix);
   1369      1.1  christos     }
   1370      1.1  christos 
   1371      1.1  christos     insncnt = 0;
   1372      1.1  christos     immxcnt = 0;
   1373      1.1  christos     memset (immxbuf, 0, sizeof (immxbuf));
   1374      1.1  christos 
   1375      1.1  christos     return;
   1376      1.1  christos   }
   1377      1.1  christos 
   1378      1.1  christos     char *buf = NULL;
   1379      1.1  christos     sscanf (line_cursor, "%m[^\n]", &buf);
   1380      1.1  christos     struct token_s my_tok = { .insn = buf, .begin = 0, .end = 0, .class_id = -1 , .val = 0 };
   1381      1.1  christos     struct token_list *tok_lst = parse (my_tok);
   1382      1.1  christos     free (buf);
   1383      1.1  christos 
   1384      1.1  christos     if (!tok_lst)
   1385      1.1  christos       return;
   1386      1.1  christos 
   1387      1.1  christos     /* Skip opcode */
   1388      1.1  christos     line_cursor += strlen (tok_lst->tok);
   1389      1.1  christos 
   1390      1.1  christos   assembling_insn = true;
   1391      1.1  christos 
   1392      1.1  christos   inside_bundle = 1;
   1393      1.1  christos   assemble_tokens (tok_lst);
   1394      1.1  christos   free_token_list (tok_lst);
   1395      1.1  christos   assembling_insn = false;
   1396      1.1  christos }
   1397      1.1  christos 
   1398      1.1  christos static void
   1399      1.1  christos kvx_set_cpu (void)
   1400      1.1  christos {
   1401      1.1  christos   if (!kvx_core_info)
   1402      1.1  christos     kvx_core_info = &kvx_kv3_v1_core_info;
   1403      1.1  christos 
   1404      1.1  christos   if (!kvx_registers)
   1405      1.1  christos     kvx_registers = kvx_kv3_v1_registers;
   1406      1.1  christos 
   1407      1.1  christos   if (!kvx_regfiles)
   1408      1.1  christos     kvx_regfiles = kvx_kv3_v1_regfiles;
   1409      1.1  christos 
   1410      1.1  christos   if (!kvx_modifiers)
   1411      1.1  christos     kvx_modifiers = kvx_kv3_v1_modifiers;
   1412      1.1  christos 
   1413      1.1  christos   if (env.params.core == -1)
   1414      1.1  christos       env.params.core = kvx_core_info->elf_core;
   1415      1.1  christos 
   1416      1.1  christos   int kvx_bfd_mach;
   1417      1.1  christos   print_insn = kvx_print_insn;
   1418      1.1  christos 
   1419      1.1  christos   switch (kvx_core_info->elf_core)
   1420      1.1  christos     {
   1421      1.1  christos     case ELF_KVX_CORE_KV3_1:
   1422      1.1  christos       kvx_bfd_mach = env.params.arch_size == 32 ? bfd_mach_kv3_1 : bfd_mach_kv3_1_64;
   1423      1.1  christos       setup (ELF_KVX_CORE_KV3_1);
   1424      1.1  christos       break;
   1425      1.1  christos     case ELF_KVX_CORE_KV3_2:
   1426      1.1  christos       kvx_bfd_mach = env.params.arch_size == 32 ? bfd_mach_kv3_2 : bfd_mach_kv3_2_64;
   1427      1.1  christos       setup (ELF_KVX_CORE_KV3_2);
   1428      1.1  christos       break;
   1429      1.1  christos     case ELF_KVX_CORE_KV4_1:
   1430      1.1  christos       kvx_bfd_mach = env.params.arch_size == 32 ? bfd_mach_kv4_1 : bfd_mach_kv4_1_64;
   1431      1.1  christos       setup (ELF_KVX_CORE_KV4_1);
   1432      1.1  christos       break;
   1433      1.1  christos     default:
   1434      1.1  christos       as_fatal ("Unknown elf core: 0x%x", kvx_core_info->elf_core);
   1435      1.1  christos     }
   1436      1.1  christos 
   1437      1.1  christos   if (!bfd_set_arch_mach (stdoutput, TARGET_ARCH, kvx_bfd_mach))
   1438      1.1  christos     as_warn (_("could not set architecture and machine"));
   1439      1.1  christos }
   1440      1.1  christos 
   1441      1.1  christos static int
   1442      1.1  christos kvxop_compar (const void *a, const void *b)
   1443      1.1  christos {
   1444  1.1.1.2  christos   const struct kvxopc *opa = a;
   1445  1.1.1.2  christos   const struct kvxopc *opb = b;
   1446      1.1  christos   int res = strcmp (opa->as_op, opb->as_op);
   1447      1.1  christos 
   1448      1.1  christos   if (res)
   1449      1.1  christos     return res;
   1450      1.1  christos   else
   1451      1.1  christos     {
   1452      1.1  christos       for (int i = 0; opa->format[i] && opb->format[i]; ++i)
   1453      1.1  christos 	if (opa->format[i]->width != opb->format[i]->width)
   1454      1.1  christos 	  return opa->format[i]->width - opb->format[i]->width;
   1455      1.1  christos       return 0;
   1456      1.1  christos     }
   1457      1.1  christos }
   1458      1.1  christos 
   1459      1.1  christos /***************************************************/
   1460      1.1  christos /*    INITIALIZE ASSEMBLER                         */
   1461      1.1  christos /***************************************************/
   1462      1.1  christos 
   1463      1.1  christos static int
   1464      1.1  christos print_hash (void **slot, void *arg ATTRIBUTE_UNUSED)
   1465      1.1  christos {
   1466      1.1  christos   string_tuple_t *tuple = *((string_tuple_t **) slot);
   1467      1.1  christos   printf ("%s\n", tuple->key);
   1468      1.1  christos   return 1;
   1469      1.1  christos }
   1470      1.1  christos 
   1471      1.1  christos static void
   1472      1.1  christos declare_register (const char *name, int number)
   1473      1.1  christos {
   1474      1.1  christos   symbolS *regS = symbol_create (name, reg_section,
   1475      1.1  christos 				 &zero_address_frag, number);
   1476      1.1  christos 
   1477      1.1  christos   if (str_hash_insert (env.reg_hash, S_GET_NAME (regS), regS, 0) != NULL)
   1478      1.1  christos     as_fatal (_("duplicate %s"), name);
   1479      1.1  christos }
   1480      1.1  christos 
   1481      1.1  christos void
   1482      1.1  christos md_begin ()
   1483      1.1  christos {
   1484      1.1  christos   kvx_set_cpu ();
   1485      1.1  christos 
   1486      1.1  christos   /*
   1487      1.1  christos    * Declare register names with symbols
   1488      1.1  christos    */
   1489      1.1  christos 
   1490      1.1  christos   env.reg_hash = str_htab_create ();
   1491      1.1  christos 
   1492      1.1  christos   for (int i = 0; i < kvx_regfiles[KVX_REGFILE_REGISTERS]; i++)
   1493      1.1  christos     declare_register (kvx_registers[i].name, kvx_registers[i].id);
   1494      1.1  christos 
   1495      1.1  christos   /* Sort optab, so that identical mnemonics appear consecutively */
   1496      1.1  christos   {
   1497      1.1  christos     int nel;
   1498      1.1  christos     for (nel = 0; !STREQ ("", kvx_core_info->optab[nel].as_op); nel++)
   1499      1.1  christos       ;
   1500      1.1  christos     qsort (kvx_core_info->optab, nel, sizeof (kvx_core_info->optab[0]),
   1501      1.1  christos 	   kvxop_compar);
   1502      1.1  christos   }
   1503      1.1  christos 
   1504      1.1  christos   /* The '?' is an operand separator */
   1505      1.1  christos   lex_type['?'] = 0;
   1506      1.1  christos 
   1507      1.1  christos   /* Create the opcode hash table      */
   1508      1.1  christos   /* Each name should appear only once */
   1509      1.1  christos 
   1510      1.1  christos   env.opcode_hash = str_htab_create ();
   1511      1.1  christos   env.reloc_hash = str_htab_create ();
   1512      1.1  christos 
   1513      1.1  christos   {
   1514      1.1  christos     struct kvxopc *op;
   1515      1.1  christos     const char *name = 0;
   1516      1.1  christos     for (op = kvx_core_info->optab; !(STREQ ("", op->as_op)); op++)
   1517      1.1  christos       {
   1518      1.1  christos 	/* enter in hash table if this is a new name */
   1519      1.1  christos 	if (!(STREQ (name, op->as_op)))
   1520      1.1  christos 	  {
   1521      1.1  christos 	    name = op->as_op;
   1522      1.1  christos 	    if (str_hash_insert (env.opcode_hash, name, op, 0))
   1523      1.1  christos 	      as_fatal ("internal error: can't hash opcode `%s'", name);
   1524      1.1  christos 	  }
   1525      1.1  christos 
   1526      1.1  christos 
   1527      1.1  christos 	for (int i = 0 ; op->format[i] ; ++i)
   1528      1.1  christos 	  {
   1529      1.1  christos 	    const char *reloc_name = TOKEN_NAME (op->format[i]->type);
   1530      1.1  christos 	    void *relocs = op->format[i]->relocs;
   1531      1.1  christos 	    if (op->format[i]->relocs[0] != 0
   1532      1.1  christos 		&& !str_hash_find (env.reloc_hash, reloc_name))
   1533      1.1  christos 	      if (str_hash_insert (env.reloc_hash, reloc_name, relocs, 0))
   1534      1.1  christos 		  as_fatal ("internal error: can't hash type `%s'", reloc_name);
   1535      1.1  christos 	  }
   1536      1.1  christos       }
   1537      1.1  christos   }
   1538      1.1  christos 
   1539      1.1  christos   if (env.opts.dump_table)
   1540      1.1  christos     {
   1541      1.1  christos       htab_traverse (env.opcode_hash, print_hash, NULL);
   1542      1.1  christos       exit (0);
   1543      1.1  christos     }
   1544      1.1  christos 
   1545      1.1  christos   if (env.opts.dump_insn)
   1546      1.1  christos     {
   1547      1.1  christos       for (struct kvxopc *op = kvx_core_info->optab; !(STREQ ("", op->as_op)); op++)
   1548      1.1  christos 	print_insn (op);
   1549      1.1  christos       exit (0);
   1550      1.1  christos     }
   1551      1.1  christos 
   1552      1.1  christos   /* Here we enforce the minimum section alignment.  Remember, in
   1553      1.1  christos    * the linker we can make the boudaries between the linked sections
   1554      1.1  christos    * on larger boundaries.  The text segment is aligned to long words
   1555      1.1  christos    * because of the odd/even constraint on immediate extensions
   1556      1.1  christos    */
   1557      1.1  christos 
   1558      1.1  christos   bfd_set_section_alignment (text_section, 3);	/* -- 8 bytes */
   1559      1.1  christos   bfd_set_section_alignment (data_section, 2);	/* -- 4 bytes */
   1560      1.1  christos   bfd_set_section_alignment (bss_section, 2);	/* -- 4 bytes */
   1561      1.1  christos   subseg_set (text_section, 0);
   1562      1.1  christos 
   1563      1.1  christos   symbolS *gotoff_sym   = symbol_create (".<gotoff>",   undefined_section, &zero_address_frag, 0);
   1564      1.1  christos   symbolS *got_sym      = symbol_create (".<got>",      undefined_section, &zero_address_frag, 0);
   1565      1.1  christos   symbolS *plt_sym      = symbol_create (".<plt>",      undefined_section, &zero_address_frag, 0);
   1566      1.1  christos   symbolS *tlsgd_sym    = symbol_create (".<tlsgd>",    undefined_section, &zero_address_frag, 0);
   1567      1.1  christos   symbolS *tlsie_sym    = symbol_create (".<tlsie>",    undefined_section, &zero_address_frag, 0);
   1568      1.1  christos   symbolS *tlsle_sym    = symbol_create (".<tlsle>",    undefined_section, &zero_address_frag, 0);
   1569      1.1  christos   symbolS *tlsld_sym    = symbol_create (".<tlsld>",    undefined_section, &zero_address_frag, 0);
   1570      1.1  christos   symbolS *dtpoff_sym   = symbol_create (".<dtpoff>",   undefined_section, &zero_address_frag, 0);
   1571      1.1  christos   symbolS *plt64_sym    = symbol_create (".<plt64>",    undefined_section, &zero_address_frag, 0);
   1572      1.1  christos   symbolS *gotaddr_sym  = symbol_create (".<gotaddr>",  undefined_section, &zero_address_frag, 0);
   1573      1.1  christos   symbolS *pcrel16_sym  = symbol_create (".<pcrel16>",  undefined_section, &zero_address_frag, 0);
   1574      1.1  christos   symbolS *pcrel_sym    = symbol_create (".<pcrel>",    undefined_section, &zero_address_frag, 0);
   1575      1.1  christos   symbolS *signed32_sym = symbol_create (".<signed32>", undefined_section, &zero_address_frag, 0);
   1576      1.1  christos 
   1577      1.1  christos   for (int i = 0; i < kvx_core_info->nb_pseudo_funcs; ++i)
   1578      1.1  christos     {
   1579      1.1  christos       symbolS *sym;
   1580      1.1  christos       if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "gotoff"))
   1581      1.1  christos 	sym = gotoff_sym;
   1582      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "got"))
   1583      1.1  christos 	sym = got_sym;
   1584      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "plt"))
   1585      1.1  christos 	sym = plt_sym;
   1586      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "tlsgd"))
   1587      1.1  christos 	sym = tlsgd_sym;
   1588      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "tlsle"))
   1589      1.1  christos 	sym = tlsle_sym;
   1590      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "tlsld"))
   1591      1.1  christos 	sym = tlsld_sym;
   1592      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "dtpoff"))
   1593      1.1  christos 	sym = dtpoff_sym;
   1594      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "tlsie"))
   1595      1.1  christos 	sym = tlsie_sym;
   1596      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "plt64"))
   1597      1.1  christos 	sym = plt64_sym;
   1598      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "pcrel16"))
   1599      1.1  christos 	sym = pcrel16_sym;
   1600      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "pcrel"))
   1601      1.1  christos 	sym = pcrel_sym;
   1602      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "gotaddr"))
   1603      1.1  christos 	sym = gotaddr_sym;
   1604      1.1  christos       else if (!strcmp (kvx_core_info->pseudo_funcs[i].name, "signed32"))
   1605      1.1  christos 	sym = signed32_sym;
   1606      1.1  christos       else
   1607      1.1  christos 	as_fatal ("internal error: Unknown pseudo func `%s'",
   1608      1.1  christos 	    kvx_core_info->pseudo_funcs[i].name);
   1609      1.1  christos 
   1610      1.1  christos       kvx_core_info->pseudo_funcs[i].sym = sym;
   1611      1.1  christos     }
   1612      1.1  christos }
   1613      1.1  christos 
   1614      1.1  christos /***************************************************/
   1615      1.1  christos /*          ASSEMBLER CLEANUP STUFF                */
   1616      1.1  christos /***************************************************/
   1617      1.1  christos 
   1618      1.1  christos /* Return non-zero if the indicated VALUE has overflowed the maximum
   1619      1.1  christos    range expressible by a signed number with the indicated number of
   1620      1.1  christos    BITS.
   1621      1.1  christos 
   1622      1.1  christos    This is from tc-aarch64.c
   1623      1.1  christos */
   1624      1.1  christos 
   1625      1.1  christos static bfd_boolean
   1626      1.1  christos signed_overflow (offsetT value, unsigned bits)
   1627      1.1  christos {
   1628      1.1  christos   offsetT lim;
   1629      1.1  christos   if (bits >= sizeof (offsetT) * 8)
   1630      1.1  christos     return FALSE;
   1631      1.1  christos   lim = (offsetT) 1 << (bits - 1);
   1632      1.1  christos   return (value < -lim || value >= lim);
   1633      1.1  christos }
   1634      1.1  christos 
   1635      1.1  christos /***************************************************/
   1636      1.1  christos /*          ASSEMBLER FIXUP STUFF                  */
   1637      1.1  christos /***************************************************/
   1638      1.1  christos 
   1639      1.1  christos void
   1640      1.1  christos md_apply_fix (fixS * fixP, valueT * valueP, segT segmentP ATTRIBUTE_UNUSED)
   1641      1.1  christos {
   1642      1.1  christos   char *const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
   1643      1.1  christos   valueT value = *valueP;
   1644      1.1  christos   valueT image;
   1645      1.1  christos   arelent *rel;
   1646      1.1  christos 
   1647  1.1.1.2  christos   rel = xmalloc (sizeof (arelent));
   1648      1.1  christos 
   1649      1.1  christos   rel->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
   1650      1.1  christos   if (rel->howto == NULL)
   1651      1.1  christos     {
   1652      1.1  christos       as_fatal
   1653      1.1  christos 	("[md_apply_fix] unsupported relocation type (can't find howto)");
   1654      1.1  christos     }
   1655      1.1  christos 
   1656      1.1  christos   /* Note whether this will delete the relocation.  */
   1657      1.1  christos   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
   1658      1.1  christos     fixP->fx_done = 1;
   1659      1.1  christos 
   1660      1.1  christos   if (fixP->fx_size > 0)
   1661      1.1  christos     image = md_chars_to_number (fixpos, fixP->fx_size);
   1662      1.1  christos   else
   1663      1.1  christos     image = 0;
   1664      1.1  christos   if (fixP->fx_addsy != NULL)
   1665      1.1  christos     {
   1666      1.1  christos       switch (fixP->fx_r_type)
   1667      1.1  christos 	{
   1668      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_LE_UP27:
   1669      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_LE_LO10:
   1670      1.1  christos 
   1671      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LE_EX6:
   1672      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LE_UP27:
   1673      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LE_LO10:
   1674      1.1  christos 
   1675      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_GD_LO10:
   1676      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_GD_UP27:
   1677      1.1  christos 
   1678      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_GD_LO10:
   1679      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_GD_UP27:
   1680      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_GD_EX6:
   1681      1.1  christos 
   1682      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_IE_LO10:
   1683      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_IE_UP27:
   1684      1.1  christos 
   1685      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_IE_LO10:
   1686      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_IE_UP27:
   1687      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_IE_EX6:
   1688      1.1  christos 
   1689      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_LD_LO10:
   1690      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_LD_UP27:
   1691      1.1  christos 
   1692      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LD_LO10:
   1693      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LD_UP27:
   1694      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LD_EX6:
   1695      1.1  christos 
   1696      1.1  christos 	  S_SET_THREAD_LOCAL (fixP->fx_addsy);
   1697      1.1  christos 	  break;
   1698      1.1  christos 	default:
   1699      1.1  christos 	  break;
   1700      1.1  christos 	}
   1701      1.1  christos     }
   1702      1.1  christos 
   1703      1.1  christos   /* If relocation has been marked for deletion, apply remaining changes */
   1704      1.1  christos   if (fixP->fx_done)
   1705      1.1  christos     {
   1706      1.1  christos       switch (fixP->fx_r_type)
   1707      1.1  christos 	{
   1708      1.1  christos 	case BFD_RELOC_8:
   1709      1.1  christos 	case BFD_RELOC_16:
   1710      1.1  christos 	case BFD_RELOC_32:
   1711      1.1  christos 	case BFD_RELOC_64:
   1712      1.1  christos 
   1713      1.1  christos 	case BFD_RELOC_KVX_GLOB_DAT:
   1714      1.1  christos 	case BFD_RELOC_KVX_32_GOT:
   1715      1.1  christos 	case BFD_RELOC_KVX_64_GOT:
   1716      1.1  christos 	case BFD_RELOC_KVX_64_GOTOFF:
   1717      1.1  christos 	case BFD_RELOC_KVX_32_GOTOFF:
   1718      1.1  christos 	  image = value;
   1719      1.1  christos 	  md_number_to_chars (fixpos, image, fixP->fx_size);
   1720      1.1  christos 	  break;
   1721      1.1  christos 
   1722      1.1  christos 	case BFD_RELOC_KVX_PCREL17:
   1723      1.1  christos 	  if (signed_overflow (value, 17 + 2))
   1724      1.1  christos 	    as_bad_where (fixP->fx_file, fixP->fx_line,
   1725      1.1  christos 			  _("branch out of range"));
   1726      1.1  christos 	  goto pcrel_common;
   1727      1.1  christos 
   1728      1.1  christos 	case BFD_RELOC_KVX_PCREL27:
   1729      1.1  christos 	  if (signed_overflow (value, 27 + 2))
   1730      1.1  christos 	    as_bad_where (fixP->fx_file, fixP->fx_line,
   1731      1.1  christos 			  _("branch out of range"));
   1732      1.1  christos 	  goto pcrel_common;
   1733      1.1  christos 
   1734      1.1  christos 	case BFD_RELOC_KVX_S16_PCREL:
   1735      1.1  christos 	  if (signed_overflow (value, 16))
   1736      1.1  christos 	    as_bad_where (fixP->fx_file, fixP->fx_line,
   1737      1.1  christos 			  _("signed16 PCREL value out of range"));
   1738      1.1  christos 	  goto pcrel_common;
   1739      1.1  christos 
   1740      1.1  christos 	case BFD_RELOC_KVX_S43_PCREL_LO10:
   1741      1.1  christos 	case BFD_RELOC_KVX_S43_PCREL_UP27:
   1742      1.1  christos 	case BFD_RELOC_KVX_S43_PCREL_EX6:
   1743      1.1  christos 	  if (signed_overflow (value, 10 + 27 + 6))
   1744      1.1  christos 	    as_bad_where (fixP->fx_file, fixP->fx_line,
   1745      1.1  christos 			  _("signed43 PCREL value out of range"));
   1746      1.1  christos 	  goto pcrel_common;
   1747      1.1  christos 
   1748      1.1  christos 	case BFD_RELOC_KVX_S37_PCREL_LO10:
   1749      1.1  christos 	case BFD_RELOC_KVX_S37_PCREL_UP27:
   1750      1.1  christos 	  if (signed_overflow (value, 10 + 27))
   1751      1.1  christos 	    as_bad_where (fixP->fx_file, fixP->fx_line,
   1752      1.1  christos 			  _("signed37 PCREL value out of range"));
   1753      1.1  christos 	  goto pcrel_common;
   1754      1.1  christos 
   1755      1.1  christos 	case BFD_RELOC_KVX_S64_PCREL_LO10:
   1756      1.1  christos 	case BFD_RELOC_KVX_S64_PCREL_UP27:
   1757      1.1  christos 	case BFD_RELOC_KVX_S64_PCREL_EX27:
   1758      1.1  christos 
   1759      1.1  christos 	pcrel_common:
   1760      1.1  christos 	  if (fixP->fx_pcrel || fixP->fx_addsy)
   1761      1.1  christos 	    return;
   1762      1.1  christos 	  value =
   1763      1.1  christos 	    (((value >> rel->howto->rightshift) << rel->howto->bitpos) & rel->
   1764      1.1  christos 	     howto->dst_mask);
   1765      1.1  christos 	  image = (image & ~(rel->howto->dst_mask)) | value;
   1766      1.1  christos 	  md_number_to_chars (fixpos, image, fixP->fx_size);
   1767      1.1  christos 	  break;
   1768      1.1  christos 
   1769      1.1  christos 	case BFD_RELOC_KVX_S64_GOTADDR_LO10:
   1770      1.1  christos 	case BFD_RELOC_KVX_S64_GOTADDR_UP27:
   1771      1.1  christos 	case BFD_RELOC_KVX_S64_GOTADDR_EX27:
   1772      1.1  christos 
   1773      1.1  christos 	case BFD_RELOC_KVX_S43_GOTADDR_LO10:
   1774      1.1  christos 	case BFD_RELOC_KVX_S43_GOTADDR_UP27:
   1775      1.1  christos 	case BFD_RELOC_KVX_S43_GOTADDR_EX6:
   1776      1.1  christos 
   1777      1.1  christos 	case BFD_RELOC_KVX_S37_GOTADDR_LO10:
   1778      1.1  christos 	case BFD_RELOC_KVX_S37_GOTADDR_UP27:
   1779      1.1  christos 	  value = 0;
   1780      1.1  christos 	  /* Fallthrough */
   1781      1.1  christos 
   1782      1.1  christos 	case BFD_RELOC_KVX_S32_UP27:
   1783      1.1  christos 
   1784      1.1  christos 	case BFD_RELOC_KVX_S37_UP27:
   1785      1.1  christos 
   1786      1.1  christos 	case BFD_RELOC_KVX_S43_UP27:
   1787      1.1  christos 
   1788      1.1  christos 	case BFD_RELOC_KVX_S64_UP27:
   1789      1.1  christos 	case BFD_RELOC_KVX_S64_EX27:
   1790      1.1  christos 	case BFD_RELOC_KVX_S64_LO10:
   1791      1.1  christos 
   1792      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LE_UP27:
   1793      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LE_EX6:
   1794      1.1  christos 
   1795      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_LE_UP27:
   1796      1.1  christos 
   1797      1.1  christos 	case BFD_RELOC_KVX_S37_GOTOFF_UP27:
   1798      1.1  christos 
   1799      1.1  christos 	case BFD_RELOC_KVX_S43_GOTOFF_UP27:
   1800      1.1  christos 	case BFD_RELOC_KVX_S43_GOTOFF_EX6:
   1801      1.1  christos 
   1802      1.1  christos 	case BFD_RELOC_KVX_S43_GOT_UP27:
   1803      1.1  christos 	case BFD_RELOC_KVX_S43_GOT_EX6:
   1804      1.1  christos 
   1805      1.1  christos 	case BFD_RELOC_KVX_S37_GOT_UP27:
   1806      1.1  christos 
   1807      1.1  christos 	case BFD_RELOC_KVX_S32_LO5:
   1808      1.1  christos 	case BFD_RELOC_KVX_S37_LO10:
   1809      1.1  christos 
   1810      1.1  christos 	case BFD_RELOC_KVX_S43_LO10:
   1811      1.1  christos 	case BFD_RELOC_KVX_S43_EX6:
   1812      1.1  christos 
   1813      1.1  christos 	case BFD_RELOC_KVX_S43_TLS_LE_LO10:
   1814      1.1  christos 	case BFD_RELOC_KVX_S37_TLS_LE_LO10:
   1815      1.1  christos 
   1816      1.1  christos 	case BFD_RELOC_KVX_S37_GOTOFF_LO10:
   1817      1.1  christos 	case BFD_RELOC_KVX_S43_GOTOFF_LO10:
   1818      1.1  christos 
   1819      1.1  christos 	case BFD_RELOC_KVX_S43_GOT_LO10:
   1820      1.1  christos 	case BFD_RELOC_KVX_S37_GOT_LO10:
   1821      1.1  christos 
   1822      1.1  christos 	default:
   1823      1.1  christos 	  as_fatal ("[md_apply_fix]:"
   1824      1.1  christos 		    "unsupported relocation type (type not handled : %d)",
   1825      1.1  christos 		    fixP->fx_r_type);
   1826      1.1  christos 	}
   1827      1.1  christos     }
   1828  1.1.1.2  christos   xfree (rel);
   1829      1.1  christos }
   1830      1.1  christos 
   1831      1.1  christos /*
   1832      1.1  christos  * Warning: Can be called only in fixup_segment() after fx_addsy field
   1833      1.1  christos  * has been updated by calling symbol_get_value_expression(...->X_add_symbol)
   1834      1.1  christos  */
   1835      1.1  christos int
   1836      1.1  christos kvx_validate_sub_fix (fixS * fixP)
   1837      1.1  christos {
   1838      1.1  christos   segT add_symbol_segment, sub_symbol_segment;
   1839      1.1  christos 
   1840      1.1  christos   switch (fixP->fx_r_type)
   1841      1.1  christos     {
   1842      1.1  christos     case BFD_RELOC_8:
   1843      1.1  christos     case BFD_RELOC_16:
   1844      1.1  christos     case BFD_RELOC_32:
   1845      1.1  christos       if (fixP->fx_addsy != NULL)
   1846      1.1  christos 	add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy);
   1847      1.1  christos       else
   1848      1.1  christos 	return 0;
   1849      1.1  christos       if (fixP->fx_subsy != NULL)
   1850      1.1  christos 	sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy);
   1851      1.1  christos       else
   1852      1.1  christos 	return 0;
   1853      1.1  christos 
   1854      1.1  christos       if ((strcmp (S_GET_NAME (fixP->fx_addsy),
   1855      1.1  christos 		   S_GET_NAME (fixP->fx_subsy)) == 0) &&
   1856      1.1  christos 	  (add_symbol_segment == sub_symbol_segment))
   1857      1.1  christos 	return 1;
   1858      1.1  christos       break;
   1859      1.1  christos     default:
   1860      1.1  christos       break;
   1861      1.1  christos     }
   1862      1.1  christos 
   1863      1.1  christos   return 0;
   1864      1.1  christos }
   1865      1.1  christos 
   1866      1.1  christos /* This is called whenever some data item (not an instruction) needs a
   1867      1.1  christos  * fixup.  */
   1868      1.1  christos void
   1869      1.1  christos kvx_cons_fix_new (fragS * f, int where, int nbytes, expressionS * exp,
   1870      1.1  christos 		  bfd_reloc_code_real_type code)
   1871      1.1  christos {
   1872      1.1  christos   if (exp->X_op == O_pseudo_fixup)
   1873      1.1  christos     {
   1874      1.1  christos       exp->X_op = O_symbol;
   1875      1.1  christos       struct pseudo_func *pf =
   1876      1.1  christos 	kvx_get_pseudo_func_data_scn (exp->X_op_symbol);
   1877      1.1  christos       assert (pf != NULL);
   1878      1.1  christos       code = pf->pseudo_relocs.single;
   1879      1.1  christos 
   1880      1.1  christos       if (code == BFD_RELOC_UNUSED)
   1881      1.1  christos 	as_fatal ("Unsupported relocation");
   1882      1.1  christos     }
   1883      1.1  christos   else
   1884      1.1  christos     {
   1885      1.1  christos       switch (nbytes)
   1886      1.1  christos 	{
   1887      1.1  christos 	case 1:
   1888      1.1  christos 	  code = BFD_RELOC_8;
   1889      1.1  christos 	  break;
   1890      1.1  christos 	case 2:
   1891      1.1  christos 	  code = BFD_RELOC_16;
   1892      1.1  christos 	  break;
   1893      1.1  christos 	case 4:
   1894      1.1  christos 	  code = BFD_RELOC_32;
   1895      1.1  christos 	  break;
   1896      1.1  christos 	case 8:
   1897      1.1  christos 	  code = BFD_RELOC_64;
   1898      1.1  christos 	  break;
   1899      1.1  christos 	default:
   1900      1.1  christos 	  as_fatal ("unsupported BFD relocation size %u", nbytes);
   1901      1.1  christos 	  break;
   1902      1.1  christos 	}
   1903      1.1  christos     }
   1904      1.1  christos   fix_new_exp (f, where, nbytes, exp, 0, code);
   1905      1.1  christos }
   1906      1.1  christos 
   1907      1.1  christos /*
   1908      1.1  christos  * generate a relocation record
   1909      1.1  christos  */
   1910      1.1  christos 
   1911      1.1  christos arelent *
   1912      1.1  christos tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp)
   1913      1.1  christos {
   1914      1.1  christos   arelent *reloc;
   1915      1.1  christos   bfd_reloc_code_real_type code;
   1916      1.1  christos 
   1917  1.1.1.2  christos   reloc = notes_alloc (sizeof (arelent));
   1918  1.1.1.2  christos   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   1919      1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1920      1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   1921      1.1  christos 
   1922      1.1  christos   code = fixp->fx_r_type;
   1923      1.1  christos   if (code == BFD_RELOC_32 && fixp->fx_pcrel)
   1924      1.1  christos     code = BFD_RELOC_32_PCREL;
   1925      1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   1926      1.1  christos 
   1927      1.1  christos   if (reloc->howto == NULL)
   1928      1.1  christos     {
   1929      1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   1930      1.1  christos 		    "cannot represent `%s' relocation in object file",
   1931      1.1  christos 		    bfd_get_reloc_code_name (code));
   1932      1.1  christos       return NULL;
   1933      1.1  christos     }
   1934      1.1  christos 
   1935      1.1  christos //  if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
   1936      1.1  christos //    {
   1937      1.1  christos //      as_fatal ("internal error? cannot generate `%s' relocation",
   1938      1.1  christos //		bfd_get_reloc_code_name (code));
   1939      1.1  christos //    }
   1940      1.1  christos //  assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
   1941      1.1  christos 
   1942      1.1  christos   reloc->addend = fixp->fx_offset;
   1943      1.1  christos 
   1944      1.1  christos   /*
   1945      1.1  christos    * Ohhh, this is ugly.  The problem is that if this is a local global
   1946      1.1  christos    * symbol, the relocation will entirely be performed at link time, not
   1947      1.1  christos    * at assembly time.  bfd_perform_reloc doesn't know about this sort
   1948      1.1  christos    * of thing, and as a result we need to fake it out here.
   1949      1.1  christos    */
   1950      1.1  christos 
   1951      1.1  christos   /* GD I'm not sure what this is used for in the kvx case but it sure  */
   1952      1.1  christos   /* messes up the relocs when emit_all_relocs is used as they are not */
   1953      1.1  christos   /* resolved with respect to a global sysmbol (e.g. .text), and hence */
   1954      1.1  christos   /* they are ALWAYS resolved at link time                             */
   1955      1.1  christos   /* FIXME FIXME                                                       */
   1956      1.1  christos 
   1957      1.1  christos   /* clarkes: 030827:  This code (and the other half of the fix in write.c)
   1958      1.1  christos    * have caused problems with the PIC relocations.
   1959      1.1  christos    * The root problem is that bfd_install_relocation adds in to the reloc
   1960      1.1  christos    * addend the section offset of a symbol defined in the current object.
   1961      1.1  christos    * This causes problems on numerous other targets too, and there are
   1962      1.1  christos    * several different methods used to get around it:
   1963      1.1  christos    *   1.  In tc_gen_reloc, subtract off the value that bfd_install_relocation
   1964      1.1  christos    *       added.  That is what we do here, and it is also done the
   1965      1.1  christos    *       same way for alpha.
   1966      1.1  christos    *   2.  In md_apply_fix, subtract off the value that bfd_install_relocation
   1967      1.1  christos    *       will add.  This is done on SH (non-ELF) and sparc targets.
   1968      1.1  christos    *   3.  In the howto structure for the relocations, specify a
   1969      1.1  christos    *       special function that does not return bfd_reloc_continue.
   1970      1.1  christos    *       This causes bfd_install_relocaion to terminate before it
   1971      1.1  christos    *       adds in the symbol offset.  This is done on SH ELF targets.
   1972      1.1  christos    *       Note that on ST200 we specify bfd_elf_generic_reloc as
   1973      1.1  christos    *       the special function.  This will return bfd_reloc_continue
   1974      1.1  christos    *       only in some circumstances, but in particular if the reloc
   1975      1.1  christos    *       is marked as partial_inplace in the bfd howto structure, then
   1976      1.1  christos    *       bfd_elf_generic_reloc will return bfd_reloc_continue.
   1977      1.1  christos    *       Some ST200 relocations are marked as partial_inplace
   1978      1.1  christos    *       (this is an error in my opinion because ST200 always uses
   1979      1.1  christos    *       a separate addend), but some are not.  The PIC relocations
   1980      1.1  christos    *       are not marked as partial_inplace, so for them,
   1981      1.1  christos    *       bfd_elf_generic_reloc returns bfd_reloc_ok, and the addend
   1982      1.1  christos    *       is not modified by bfd_install_relocation.   The relocations
   1983      1.1  christos    *       R_KVX_16 and R_KVX_32 are marked partial_inplace, and so for
   1984      1.1  christos    *       these we need to correct the addend.
   1985      1.1  christos    * In the code below, the condition in the emit_all_relocs branch
   1986      1.1  christos    * (now moved to write.c) is the inverse of the condition that
   1987      1.1  christos    * bfd_elf_generic_reloc uses to short-circuit the code in
   1988      1.1  christos    * bfd_install_relocation that modifies the addend.  The condition
   1989      1.1  christos    * in the else branch match the condition used in the alpha version
   1990      1.1  christos    * of tc_gen_reloc (see tc-alpha.c).
   1991      1.1  christos    * I do not know why we need to use different conditions in these
   1992      1.1  christos    * two branches, it seems to me that the condition should be the same
   1993      1.1  christos    * whether or not emit_all_relocs is true.
   1994      1.1  christos    * I also do not understand why it was necessary to move the emit_all_relocs
   1995      1.1  christos    * condition to write.c.
   1996      1.1  christos    */
   1997      1.1  christos 
   1998      1.1  christos   if (S_IS_EXTERNAL (fixp->fx_addsy) &&
   1999      1.1  christos       !S_IS_COMMON (fixp->fx_addsy) && reloc->howto->partial_inplace)
   2000      1.1  christos     reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
   2001      1.1  christos 
   2002      1.1  christos   return reloc;
   2003      1.1  christos }
   2004      1.1  christos 
   2005      1.1  christos /* Round up segment to appropriate boundary */
   2006      1.1  christos 
   2007      1.1  christos valueT
   2008      1.1  christos md_section_align (asection * seg ATTRIBUTE_UNUSED, valueT size)
   2009      1.1  christos {
   2010      1.1  christos #ifndef OBJ_ELF
   2011      1.1  christos   /* This is not right for ELF; a.out wants it, and COFF will force
   2012      1.1  christos    * the alignment anyways.  */
   2013      1.1  christos   int align = bfd_get_section_alignment (stdoutput, seg);
   2014      1.1  christos   valueT mask = ((valueT) 1 << align) - 1;
   2015      1.1  christos   return (size + mask) & ~mask;
   2016      1.1  christos #else
   2017      1.1  christos   return size;
   2018      1.1  christos #endif
   2019      1.1  christos }
   2020      1.1  christos 
   2021      1.1  christos int
   2022      1.1  christos md_estimate_size_before_relax (register fragS * fragP ATTRIBUTE_UNUSED,
   2023      1.1  christos 			       segT segtype ATTRIBUTE_UNUSED)
   2024      1.1  christos {
   2025      1.1  christos   as_fatal ("estimate_size_before_relax called");
   2026      1.1  christos }
   2027      1.1  christos 
   2028      1.1  christos void
   2029      1.1  christos md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
   2030      1.1  christos 		 asection * sec ATTRIBUTE_UNUSED,
   2031      1.1  christos 		 fragS * fragp ATTRIBUTE_UNUSED)
   2032      1.1  christos {
   2033      1.1  christos   as_fatal ("kvx convert_frag");
   2034      1.1  christos }
   2035      1.1  christos 
   2036      1.1  christos symbolS *
   2037      1.1  christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   2038      1.1  christos {
   2039      1.1  christos   return 0;
   2040      1.1  christos }
   2041      1.1  christos 
   2042      1.1  christos const char *
   2043      1.1  christos md_atof (int type ATTRIBUTE_UNUSED,
   2044      1.1  christos 	 char *litp ATTRIBUTE_UNUSED, int *sizep ATTRIBUTE_UNUSED)
   2045      1.1  christos {
   2046      1.1  christos   return ieee_md_atof (type, litp, sizep, TARGET_BYTES_BIG_ENDIAN);
   2047      1.1  christos }
   2048      1.1  christos 
   2049      1.1  christos /*
   2050      1.1  christos  * calculate the base for a pcrel fixup
   2051      1.1  christos  * -- for relocation, we might need to add addend ?
   2052      1.1  christos  */
   2053      1.1  christos 
   2054      1.1  christos long
   2055      1.1  christos md_pcrel_from (fixS * fixP)
   2056      1.1  christos {
   2057      1.1  christos   return (fixP->fx_where + fixP->fx_frag->fr_address);
   2058      1.1  christos }
   2059      1.1  christos 
   2060      1.1  christos /************************************************************/
   2061      1.1  christos /*   Hooks into standard processing -- we hook into label   */
   2062      1.1  christos /*   handling code to detect double ':' and we hook before  */
   2063      1.1  christos /*   a line of code is processed to do some simple sed style */
   2064      1.1  christos /*   edits.                                                 */
   2065      1.1  christos /************************************************************/
   2066      1.1  christos 
   2067      1.1  christos static symbolS *last_proc_sym = NULL;
   2068      1.1  christos static int update_last_proc_sym = 0;
   2069      1.1  christos 
   2070      1.1  christos void
   2071      1.1  christos kvx_frob_label (symbolS *sym)
   2072      1.1  christos {
   2073      1.1  christos   if (update_last_proc_sym)
   2074      1.1  christos     {
   2075      1.1  christos       last_proc_sym = sym;
   2076      1.1  christos       update_last_proc_sym = 0;
   2077      1.1  christos     }
   2078      1.1  christos 
   2079      1.1  christos   if (inside_bundle)
   2080      1.1  christos     {
   2081      1.1  christos       struct label_fix *fix;
   2082      1.1  christos       fix = malloc (sizeof (*fix));
   2083      1.1  christos       fix->next = label_fixes;
   2084      1.1  christos       fix->sym = sym;
   2085      1.1  christos       label_fixes = fix;
   2086      1.1  christos     }
   2087      1.1  christos 
   2088      1.1  christos   dwarf2_emit_label (sym);
   2089      1.1  christos }
   2090      1.1  christos 
   2091      1.1  christos void
   2092      1.1  christos kvx_check_label (symbolS *sym)
   2093      1.1  christos {
   2094      1.1  christos   /* Labels followed by a second semi-colon are considered external symbols.  */
   2095      1.1  christos   if (*input_line_pointer == ':')
   2096      1.1  christos     {
   2097      1.1  christos       S_SET_EXTERNAL (sym);
   2098      1.1  christos       input_line_pointer++;
   2099      1.1  christos     }
   2100      1.1  christos }
   2101      1.1  christos 
   2102      1.1  christos /* Emit single bundle nop. This is needed by .nop asm directive
   2103      1.1  christos  * Have to manage end of bundle done usually by start_line_hook
   2104      1.1  christos  * using BE pseudo op
   2105      1.1  christos  */
   2106      1.1  christos void
   2107      1.1  christos kvx_emit_single_noop (void)
   2108      1.1  christos {
   2109  1.1.1.2  christos   char nop[] = "nop";
   2110  1.1.1.2  christos   char end_of_bundle[] = "be";
   2111      1.1  christos 
   2112      1.1  christos   char *saved_ilp = input_line_pointer;
   2113      1.1  christos   md_assemble (nop);
   2114      1.1  christos   md_assemble (end_of_bundle);
   2115      1.1  christos   input_line_pointer = saved_ilp;
   2116      1.1  christos }
   2117      1.1  christos 
   2118      1.1  christos /*  edit out some syntactic sugar that confuses GAS       */
   2119      1.1  christos /*  input_line_pointer is guaranteed to point to the      */
   2120      1.1  christos /*  the current line but may include text from following  */
   2121      1.1  christos /*  lines.  Thus, '\n' must be scanned for as well as '\0' */
   2122      1.1  christos 
   2123      1.1  christos void
   2124      1.1  christos kvx_md_start_line_hook (void)
   2125      1.1  christos {
   2126      1.1  christos   char *t;
   2127      1.1  christos 
   2128  1.1.1.2  christos   for (t = input_line_pointer; is_whitespace (t[0]); t++);
   2129      1.1  christos 
   2130      1.1  christos   /* Detect illegal syntax patterns:
   2131      1.1  christos    * - two bundle ends on the same line: ;; ;;
   2132      1.1  christos    * - illegal token: ;;;
   2133      1.1  christos    */
   2134      1.1  christos   if (t && (t[0] == ';') && (t[1] == ';'))
   2135      1.1  christos     {
   2136      1.1  christos       char *tmp_t;
   2137      1.1  christos       bool newline_seen = false;
   2138      1.1  christos 
   2139      1.1  christos       if (t[2] == ';')
   2140      1.1  christos 	as_fatal ("Syntax error: Illegal ;;; token");
   2141      1.1  christos 
   2142      1.1  christos       tmp_t = t + 2;
   2143      1.1  christos 
   2144      1.1  christos       while (tmp_t && tmp_t[0])
   2145      1.1  christos 	{
   2146      1.1  christos 	  while (tmp_t && tmp_t[0] &&
   2147  1.1.1.2  christos 		 (is_whitespace (tmp_t[0]) || is_end_of_stmt (tmp_t[0])))
   2148      1.1  christos 	    {
   2149  1.1.1.2  christos 	      if (is_end_of_stmt (tmp_t[0]))
   2150      1.1  christos 		newline_seen = true;
   2151      1.1  christos 	      tmp_t++;
   2152      1.1  christos 	    }
   2153      1.1  christos 	  if (tmp_t[0] == ';' && tmp_t[1] == ';')
   2154      1.1  christos 	    {
   2155      1.1  christos 	      /* if there's no newline between the two bundle stops
   2156      1.1  christos 	       * then raise a syntax error now, otherwise a strange error
   2157      1.1  christos 	       * message from read.c will be raised: "junk at end of line..."
   2158      1.1  christos 	       */
   2159      1.1  christos 	      if (tmp_t[2] == ';')
   2160      1.1  christos 		as_fatal ("Syntax error: Illegal ;;; token");
   2161      1.1  christos 
   2162      1.1  christos 	      if (!newline_seen)
   2163      1.1  christos 		  as_fatal ("Syntax error: More than one bundle stop on a line");
   2164      1.1  christos 	      newline_seen = false;	/* reset */
   2165      1.1  christos 
   2166      1.1  christos 	      /* this is an empty bundle, transform it into an
   2167      1.1  christos 	       * empty statement */
   2168      1.1  christos 	      tmp_t[0] = ';';
   2169      1.1  christos 	      tmp_t[1] = ' ';
   2170      1.1  christos 
   2171      1.1  christos 	      tmp_t += 2;
   2172      1.1  christos 	    }
   2173      1.1  christos 	  else
   2174      1.1  christos 	    break;
   2175      1.1  christos 	}
   2176      1.1  christos     }
   2177      1.1  christos 
   2178      1.1  christos   /* check for bundle end                             */
   2179      1.1  christos   /* we transform these into a special opcode BE      */
   2180      1.1  christos   /* because gas has ';' hardwired as a statement end */
   2181      1.1  christos   if (t && (t[0] == ';') && (t[1] == ';'))
   2182      1.1  christos     {
   2183      1.1  christos       t[0] = 'B';
   2184      1.1  christos       t[1] = 'E';
   2185      1.1  christos       return;
   2186      1.1  christos     }
   2187      1.1  christos }
   2188      1.1  christos 
   2189      1.1  christos static void
   2190      1.1  christos kvx_check_resources (int f)
   2191      1.1  christos {
   2192      1.1  christos   env.opts.check_resource_usage = f;
   2193      1.1  christos }
   2194      1.1  christos 
   2195      1.1  christos /** called before write_object_file */
   2196      1.1  christos void
   2197      1.1  christos kvx_end (void)
   2198      1.1  christos {
   2199      1.1  christos   int newflags;
   2200      1.1  christos 
   2201      1.1  christos   if (!env.params.core_set)
   2202      1.1  christos     env.params.core = kvx_core_info->elf_core;
   2203      1.1  christos 
   2204      1.1  christos   /* (pp) the flags must be set at once */
   2205      1.1  christos   newflags = env.params.core | env.params.abi | env.params.pic_flags;
   2206      1.1  christos 
   2207      1.1  christos   if (env.params.arch_size == 64)
   2208      1.1  christos     newflags |= ELF_KVX_ABI_64B_ADDR_BIT;
   2209      1.1  christos 
   2210      1.1  christos   bfd_set_private_flags (stdoutput, newflags);
   2211      1.1  christos 
   2212      1.1  christos   cleanup ();
   2213      1.1  christos 
   2214      1.1  christos   if (inside_bundle && insncnt != 0)
   2215      1.1  christos     as_bad ("unexpected end-of-file while processing a bundle."
   2216      1.1  christos 	    "  Please check that ;; is on its own line.");
   2217      1.1  christos }
   2218      1.1  christos 
   2219      1.1  christos static void
   2220      1.1  christos kvx_type (int start ATTRIBUTE_UNUSED)
   2221      1.1  christos {
   2222      1.1  christos   char *name;
   2223      1.1  christos   char c;
   2224      1.1  christos   int type;
   2225      1.1  christos   char *typename = NULL;
   2226      1.1  christos   symbolS *sym;
   2227      1.1  christos   elf_symbol_type *elfsym;
   2228      1.1  christos 
   2229      1.1  christos   c = get_symbol_name (&name);
   2230      1.1  christos   sym = symbol_find_or_make (name);
   2231      1.1  christos   elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
   2232      1.1  christos   *input_line_pointer = c;
   2233      1.1  christos 
   2234      1.1  christos   if (!*S_GET_NAME (sym))
   2235      1.1  christos     as_bad (_("Missing symbol name in directive"));
   2236      1.1  christos 
   2237      1.1  christos   SKIP_WHITESPACE ();
   2238      1.1  christos   if (*input_line_pointer == ',')
   2239      1.1  christos     ++input_line_pointer;
   2240      1.1  christos 
   2241      1.1  christos 
   2242      1.1  christos   SKIP_WHITESPACE ();
   2243      1.1  christos   if (*input_line_pointer == '#'
   2244      1.1  christos       || *input_line_pointer == '@'
   2245      1.1  christos       || *input_line_pointer == '"' || *input_line_pointer == '%')
   2246      1.1  christos     ++input_line_pointer;
   2247      1.1  christos 
   2248      1.1  christos   /* typename = input_line_pointer; */
   2249      1.1  christos   /* c = get_symbol_end(); */
   2250      1.1  christos   c = get_symbol_name (&typename);
   2251      1.1  christos 
   2252      1.1  christos   type = 0;
   2253      1.1  christos   if (strcmp (typename, "function") == 0
   2254      1.1  christos       || strcmp (typename, "STT_FUNC") == 0)
   2255      1.1  christos     type = BSF_FUNCTION;
   2256      1.1  christos   else if (strcmp (typename, "object") == 0
   2257      1.1  christos 	   || strcmp (typename, "STT_OBJECT") == 0)
   2258      1.1  christos     type = BSF_OBJECT;
   2259      1.1  christos   else if (strcmp (typename, "tls_object") == 0
   2260      1.1  christos 	   || strcmp (typename, "STT_TLS") == 0)
   2261      1.1  christos     type = BSF_OBJECT | BSF_THREAD_LOCAL;
   2262      1.1  christos   else if (strcmp (typename, "common") == 0
   2263      1.1  christos 	   || strcmp (typename, "STT_COMMON") == 0)
   2264      1.1  christos     type = BSF_ELF_COMMON;
   2265      1.1  christos   else if (strcmp (typename, "gnu_unique_object") == 0
   2266      1.1  christos 	   || strcmp (typename, "STB_GNU_UNIQUE") == 0)
   2267      1.1  christos     {
   2268      1.1  christos       elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_unique;
   2269      1.1  christos       type = BSF_OBJECT | BSF_GNU_UNIQUE;
   2270      1.1  christos     }
   2271      1.1  christos   else if (strcmp (typename, "notype") == 0
   2272      1.1  christos 	   || strcmp (typename, "STT_NOTYPE") == 0)
   2273      1.1  christos     ;
   2274      1.1  christos #ifdef md_elf_symbol_type
   2275      1.1  christos   else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1)
   2276      1.1  christos     ;
   2277      1.1  christos #endif
   2278      1.1  christos   else
   2279      1.1  christos     as_bad (_("unrecognized symbol type \"%s\""), typename);
   2280      1.1  christos 
   2281      1.1  christos   *input_line_pointer = c;
   2282      1.1  christos 
   2283      1.1  christos   if (*input_line_pointer == '"')
   2284      1.1  christos     ++input_line_pointer;
   2285      1.1  christos 
   2286      1.1  christos   elfsym->symbol.flags |= type;
   2287      1.1  christos   symbol_get_bfdsym (sym)->flags |= type;
   2288      1.1  christos 
   2289      1.1  christos   demand_empty_rest_of_line ();
   2290      1.1  christos }
   2291      1.1  christos 
   2292      1.1  christos #define ENDPROCEXTENSION	"$endproc"
   2293      1.1  christos #define MINUSEXPR		".-"
   2294      1.1  christos 
   2295      1.1  christos static int proc_endp_status = 0;
   2296      1.1  christos 
   2297      1.1  christos static void
   2298      1.1  christos kvx_endp (int start ATTRIBUTE_UNUSED)
   2299      1.1  christos {
   2300      1.1  christos   char c;
   2301      1.1  christos   char *name;
   2302      1.1  christos 
   2303      1.1  christos   if (inside_bundle)
   2304      1.1  christos     as_warn (".endp directive inside a bundle.");
   2305      1.1  christos   /* function name is optionnal and is ignored */
   2306      1.1  christos   /* there may be several names separated by commas... */
   2307      1.1  christos   while (1)
   2308      1.1  christos     {
   2309      1.1  christos       SKIP_WHITESPACE ();
   2310      1.1  christos       c = get_symbol_name (&name);
   2311      1.1  christos       (void) restore_line_pointer (c);
   2312      1.1  christos       SKIP_WHITESPACE ();
   2313      1.1  christos       if (*input_line_pointer != ',')
   2314      1.1  christos 	break;
   2315      1.1  christos       ++input_line_pointer;
   2316      1.1  christos     }
   2317      1.1  christos   demand_empty_rest_of_line ();
   2318      1.1  christos 
   2319      1.1  christos   if (!proc_endp_status)
   2320      1.1  christos     {
   2321      1.1  christos       as_warn (".endp directive doesn't follow .proc -- ignoring ");
   2322      1.1  christos       return;
   2323      1.1  christos     }
   2324      1.1  christos 
   2325      1.1  christos   proc_endp_status = 0;
   2326      1.1  christos 
   2327      1.1  christos   /* TB begin : add BSF_FUNCTION attribute to last_proc_sym symbol */
   2328      1.1  christos   if (size_type_function)
   2329      1.1  christos     {
   2330      1.1  christos       if (!last_proc_sym)
   2331      1.1  christos 	{
   2332      1.1  christos 	  as_bad ("Cannot set function attributes (bad symbol)");
   2333      1.1  christos 	  return;
   2334      1.1  christos 	}
   2335      1.1  christos 
   2336      1.1  christos       /*    last_proc_sym->symbol.flags |= BSF_FUNCTION; */
   2337      1.1  christos       symbol_get_bfdsym (last_proc_sym)->flags |= BSF_FUNCTION;
   2338      1.1  christos       /* Add .size funcname,.-funcname in order to add size
   2339      1.1  christos        * attribute to the current function */
   2340      1.1  christos       {
   2341      1.1  christos 	const int newdirective_sz =
   2342      1.1  christos 	  strlen (S_GET_NAME (last_proc_sym)) + strlen (MINUSEXPR) + 1;
   2343      1.1  christos 	char *newdirective = malloc (newdirective_sz);
   2344      1.1  christos 	char *savep = input_line_pointer;
   2345      1.1  christos 	expressionS exp;
   2346      1.1  christos 
   2347      1.1  christos 	memset (newdirective, 0, newdirective_sz);
   2348      1.1  christos 
   2349      1.1  christos 	/* BUILD :".-funcname" expression */
   2350      1.1  christos 	strcat (newdirective, MINUSEXPR);
   2351      1.1  christos 	strcat (newdirective, S_GET_NAME (last_proc_sym));
   2352      1.1  christos 	input_line_pointer = newdirective;
   2353      1.1  christos 	expression (&exp);
   2354      1.1  christos 
   2355      1.1  christos 	if (exp.X_op == O_constant)
   2356      1.1  christos 	  {
   2357      1.1  christos 	    S_SET_SIZE (last_proc_sym, exp.X_add_number);
   2358  1.1.1.2  christos 	    symbol_get_obj (last_proc_sym)->size = NULL;
   2359      1.1  christos 	  }
   2360      1.1  christos 	else
   2361      1.1  christos 	  {
   2362  1.1.1.2  christos 	    symbol_get_obj (last_proc_sym)->size = notes_alloc (sizeof (exp));
   2363      1.1  christos 	    *symbol_get_obj (last_proc_sym)->size = exp;
   2364      1.1  christos 	  }
   2365      1.1  christos 
   2366      1.1  christos 	/* just restore the real input pointer */
   2367      1.1  christos 	input_line_pointer = savep;
   2368      1.1  christos 	free (newdirective);
   2369      1.1  christos       }
   2370      1.1  christos     }
   2371      1.1  christos   /* TB end */
   2372      1.1  christos 
   2373      1.1  christos   last_proc_sym = NULL;
   2374      1.1  christos }
   2375      1.1  christos 
   2376      1.1  christos static void
   2377      1.1  christos kvx_proc (int start ATTRIBUTE_UNUSED)
   2378      1.1  christos {
   2379      1.1  christos   char c;
   2380      1.1  christos   char *name;
   2381      1.1  christos   /* there may be several names separated by commas... */
   2382      1.1  christos   while (1)
   2383      1.1  christos     {
   2384      1.1  christos       SKIP_WHITESPACE ();
   2385      1.1  christos       c = get_symbol_name (&name);
   2386      1.1  christos       (void) restore_line_pointer (c);
   2387      1.1  christos 
   2388      1.1  christos       SKIP_WHITESPACE ();
   2389      1.1  christos       if (*input_line_pointer != ',')
   2390      1.1  christos 	break;
   2391      1.1  christos       ++input_line_pointer;
   2392      1.1  christos     }
   2393      1.1  christos   demand_empty_rest_of_line ();
   2394      1.1  christos 
   2395      1.1  christos   if (proc_endp_status)
   2396      1.1  christos     {
   2397      1.1  christos       as_warn (".proc follows .proc -- ignoring");
   2398      1.1  christos       return;
   2399      1.1  christos     }
   2400      1.1  christos 
   2401      1.1  christos   proc_endp_status = 1;
   2402      1.1  christos 
   2403      1.1  christos   /* this code emit a global symbol to mark the end of each function    */
   2404      1.1  christos   /* the symbol emitted has a name formed by the original function name */
   2405      1.1  christos   /* concatenated with $endproc so if _foo is a function name the symbol */
   2406      1.1  christos   /* marking the end of it is _foo$endproc                              */
   2407      1.1  christos   /* It is also required for generation of .size directive in kvx_endp() */
   2408      1.1  christos 
   2409      1.1  christos   if (size_type_function)
   2410      1.1  christos     update_last_proc_sym = 1;
   2411      1.1  christos }
   2412      1.1  christos 
   2413      1.1  christos int
   2414      1.1  christos kvx_force_reloc (fixS * fixP)
   2415      1.1  christos {
   2416      1.1  christos   symbolS *sym;
   2417      1.1  christos   asection *symsec;
   2418      1.1  christos 
   2419      1.1  christos   if (generic_force_reloc (fixP))
   2420      1.1  christos     return 1;
   2421      1.1  christos 
   2422      1.1  christos   switch (fixP->fx_r_type)
   2423      1.1  christos     {
   2424      1.1  christos     case BFD_RELOC_KVX_32_GOTOFF:
   2425      1.1  christos     case BFD_RELOC_KVX_S37_GOTOFF_UP27:
   2426      1.1  christos     case BFD_RELOC_KVX_S37_GOTOFF_LO10:
   2427      1.1  christos 
   2428      1.1  christos     case BFD_RELOC_KVX_64_GOTOFF:
   2429      1.1  christos     case BFD_RELOC_KVX_S43_GOTOFF_UP27:
   2430      1.1  christos     case BFD_RELOC_KVX_S43_GOTOFF_LO10:
   2431      1.1  christos     case BFD_RELOC_KVX_S43_GOTOFF_EX6:
   2432      1.1  christos 
   2433      1.1  christos     case BFD_RELOC_KVX_32_GOT:
   2434      1.1  christos     case BFD_RELOC_KVX_64_GOT:
   2435      1.1  christos     case BFD_RELOC_KVX_S37_GOT_UP27:
   2436      1.1  christos     case BFD_RELOC_KVX_S37_GOT_LO10:
   2437      1.1  christos 
   2438      1.1  christos     case BFD_RELOC_KVX_GLOB_DAT:
   2439      1.1  christos       return 1;
   2440      1.1  christos     default:
   2441      1.1  christos       return 0;
   2442      1.1  christos     }
   2443      1.1  christos 
   2444      1.1  christos   sym = fixP->fx_addsy;
   2445      1.1  christos   if (sym)
   2446      1.1  christos     {
   2447      1.1  christos       symsec = S_GET_SEGMENT (sym);
   2448      1.1  christos       /* if (bfd_is_abs_section (symsec)) return 0; */
   2449      1.1  christos       if (!SEG_NORMAL (symsec))
   2450      1.1  christos 	return 0;
   2451      1.1  christos     }
   2452      1.1  christos   return 1;
   2453      1.1  christos }
   2454      1.1  christos 
   2455      1.1  christos int
   2456      1.1  christos kvx_force_reloc_sub_same (fixS * fixP, segT sec)
   2457      1.1  christos {
   2458      1.1  christos   symbolS *sym;
   2459      1.1  christos   asection *symsec;
   2460      1.1  christos   const char *sec_name = NULL;
   2461      1.1  christos 
   2462      1.1  christos   if (generic_force_reloc (fixP))
   2463      1.1  christos     return 1;
   2464      1.1  christos 
   2465      1.1  christos   switch (fixP->fx_r_type)
   2466      1.1  christos     {
   2467      1.1  christos     case BFD_RELOC_KVX_32_GOTOFF:
   2468      1.1  christos     case BFD_RELOC_KVX_S37_GOTOFF_UP27:
   2469      1.1  christos     case BFD_RELOC_KVX_S37_GOTOFF_LO10:
   2470      1.1  christos 
   2471      1.1  christos     case BFD_RELOC_KVX_64_GOTOFF:
   2472      1.1  christos     case BFD_RELOC_KVX_S43_GOTOFF_UP27:
   2473      1.1  christos     case BFD_RELOC_KVX_S43_GOTOFF_LO10:
   2474      1.1  christos     case BFD_RELOC_KVX_S43_GOTOFF_EX6:
   2475      1.1  christos 
   2476      1.1  christos     case BFD_RELOC_KVX_32_GOT:
   2477      1.1  christos     case BFD_RELOC_KVX_64_GOT:
   2478      1.1  christos     case BFD_RELOC_KVX_S37_GOT_UP27:
   2479      1.1  christos     case BFD_RELOC_KVX_S37_GOT_LO10:
   2480      1.1  christos 
   2481      1.1  christos     case BFD_RELOC_KVX_S37_LO10:
   2482      1.1  christos     case BFD_RELOC_KVX_S37_UP27:
   2483      1.1  christos 
   2484      1.1  christos     case BFD_RELOC_KVX_GLOB_DAT:
   2485      1.1  christos       return 1;
   2486      1.1  christos 
   2487      1.1  christos     default:
   2488      1.1  christos       return 0;
   2489      1.1  christos     }
   2490      1.1  christos 
   2491      1.1  christos   sym = fixP->fx_addsy;
   2492      1.1  christos   if (sym)
   2493      1.1  christos     {
   2494      1.1  christos       symsec = S_GET_SEGMENT (sym);
   2495      1.1  christos       /* if (bfd_is_abs_section (symsec)) return 0; */
   2496      1.1  christos       if (!SEG_NORMAL (symsec))
   2497      1.1  christos 	return 0;
   2498      1.1  christos 
   2499      1.1  christos       /*
   2500      1.1  christos        * for .debug_arrange, .debug_frame, .eh_frame sections, containing
   2501      1.1  christos        * expressions of the form "sym2 - sym1 + addend", solve them even when
   2502      1.1  christos        * --emit-all-relocs is set. Otherwise, a relocation on two symbols
   2503      1.1  christos        * is necessary and fails at elf level. Binopt should not be impacted by
   2504      1.1  christos        * the resolution of this relocatable expression on symbols inside a
   2505      1.1  christos        * function.
   2506      1.1  christos        */
   2507      1.1  christos       sec_name = segment_name (sec);
   2508      1.1  christos       if ((strcmp (sec_name, ".eh_frame") == 0) ||
   2509      1.1  christos 	  (strcmp (sec_name, ".except_table") == 0) ||
   2510      1.1  christos 	  (strncmp (sec_name, ".debug_", sizeof (".debug_")) == 0))
   2511      1.1  christos 	return 0;
   2512      1.1  christos     }
   2513      1.1  christos   return 1;
   2514      1.1  christos }
   2515      1.1  christos 
   2516  1.1.1.2  christos /* Pads code section with bundle of nops when possible, 0 if not. */
   2517      1.1  christos 
   2518  1.1.1.2  christos void
   2519  1.1.1.2  christos kvx_handle_align (fragS *fragP)
   2520      1.1  christos {
   2521  1.1.1.2  christos   if (fragP->fr_type != rs_align_code)
   2522  1.1.1.2  christos     return;
   2523      1.1  christos 
   2524      1.1  christos   static unsigned int nop_single = 0;
   2525      1.1  christos   if (!nop_single)
   2526      1.1  christos     {
   2527  1.1.1.2  christos       const struct kvxopc *opcode = str_hash_find (env.opcode_hash, "nop");
   2528      1.1  christos 
   2529      1.1  christos       if (opcode == NULL)
   2530      1.1  christos 	as_fatal
   2531      1.1  christos 	  ("internal error: could not find opcode for 'nop' during padding");
   2532      1.1  christos 
   2533      1.1  christos       nop_single = opcode->codewords[0].opcode;
   2534      1.1  christos     }
   2535      1.1  christos 
   2536  1.1.1.2  christos   bfd_signed_vma bytes = (fragP->fr_next->fr_address
   2537  1.1.1.2  christos 			  - fragP->fr_address - fragP->fr_fix);
   2538  1.1.1.2  christos   if (bytes <= 0)
   2539  1.1.1.2  christos     return;
   2540      1.1  christos 
   2541  1.1.1.2  christos   char *p = fragP->fr_literal + fragP->fr_fix;
   2542      1.1  christos 
   2543  1.1.1.2  christos   /* KVX instructions are always 4-bytes aligned.  If we are at a
   2544  1.1.1.2  christos      position that is not 4 bytes aligned, it means this is not part
   2545  1.1.1.2  christos      of an instruction, so it is safe to use a zero byte for padding.  */
   2546  1.1.1.2  christos   int fix = bytes & 3;
   2547  1.1.1.2  christos   if (fix != 0)
   2548      1.1  christos     {
   2549  1.1.1.2  christos       memset (p, 0, fix);
   2550  1.1.1.2  christos       p += fix;
   2551  1.1.1.2  christos       bytes -= fix;
   2552  1.1.1.2  christos     }
   2553      1.1  christos 
   2554  1.1.1.2  christos   /* Output any nops that don't make a full bundle.  */
   2555  1.1.1.2  christos   while (bytes & 15)
   2556  1.1.1.2  christos     {
   2557  1.1.1.2  christos       unsigned int nop = nop_single;
   2558  1.1.1.2  christos       bytes -= 4;
   2559  1.1.1.2  christos       if (bytes & 15)
   2560  1.1.1.2  christos 	nop |= PARALLEL_BIT;
   2561  1.1.1.2  christos       memcpy (p, &nop, 4);
   2562  1.1.1.2  christos       p += 4;
   2563  1.1.1.2  christos       fix += 4;
   2564  1.1.1.2  christos     }
   2565  1.1.1.2  christos   fragP->fr_fix += fix;
   2566  1.1.1.2  christos 
   2567  1.1.1.2  christos   /* Any more are repeated copies of this full bundle of nops.  */
   2568  1.1.1.2  christos   if (bytes)
   2569  1.1.1.2  christos     {
   2570  1.1.1.2  christos       unsigned int nop = nop_single | PARALLEL_BIT;
   2571  1.1.1.2  christos       memcpy (p, &nop, 4);
   2572  1.1.1.2  christos       p += 4;
   2573  1.1.1.2  christos       memcpy (p, &nop, 4);
   2574  1.1.1.2  christos       p += 4;
   2575  1.1.1.2  christos       memcpy (p, &nop, 4);
   2576  1.1.1.2  christos       p += 4;
   2577  1.1.1.2  christos       memcpy (p, &nop_single, 4);
   2578  1.1.1.2  christos       fragP->fr_var = 16;
   2579      1.1  christos     }
   2580      1.1  christos }
   2581      1.1  christos /*
   2582      1.1  christos  * This is just used for debugging
   2583      1.1  christos  */
   2584      1.1  christos 
   2585      1.1  christos ATTRIBUTE_UNUSED
   2586      1.1  christos static void
   2587      1.1  christos print_operand (expressionS * e, FILE * out)
   2588      1.1  christos {
   2589      1.1  christos   if (e)
   2590      1.1  christos     {
   2591      1.1  christos       switch (e->X_op)
   2592      1.1  christos 	{
   2593      1.1  christos 	case O_register:
   2594      1.1  christos 	  fprintf (out, "%s", kvx_registers[e->X_add_number].name);
   2595      1.1  christos 	  break;
   2596      1.1  christos 
   2597      1.1  christos 	case O_constant:
   2598      1.1  christos 	  if (e->X_add_symbol)
   2599      1.1  christos 	    {
   2600      1.1  christos 	      if (e->X_add_number)
   2601      1.1  christos 		fprintf (out, "(%s + %d)", S_GET_NAME (e->X_add_symbol),
   2602      1.1  christos 			 (int) e->X_add_number);
   2603      1.1  christos 	      else
   2604      1.1  christos 		fprintf (out, "%s", S_GET_NAME (e->X_add_symbol));
   2605      1.1  christos 	    }
   2606      1.1  christos 	  else
   2607      1.1  christos 	    fprintf (out, "%d", (int) e->X_add_number);
   2608      1.1  christos 	  break;
   2609      1.1  christos 
   2610      1.1  christos 	case O_symbol:
   2611      1.1  christos 	  if (e->X_add_symbol)
   2612      1.1  christos 	    {
   2613      1.1  christos 	      if (e->X_add_number)
   2614      1.1  christos 		fprintf (out, "(%s + %d)", S_GET_NAME (e->X_add_symbol),
   2615      1.1  christos 			 (int) e->X_add_number);
   2616      1.1  christos 	      else
   2617      1.1  christos 		fprintf (out, "%s", S_GET_NAME (e->X_add_symbol));
   2618      1.1  christos 	    }
   2619      1.1  christos 	  else
   2620      1.1  christos 	    fprintf (out, "%d", (int) e->X_add_number);
   2621      1.1  christos 	  break;
   2622      1.1  christos 
   2623      1.1  christos 	default:
   2624      1.1  christos 	  fprintf (out, "o,ptype-%d", e->X_op);
   2625      1.1  christos 	}
   2626      1.1  christos     }
   2627      1.1  christos }
   2628      1.1  christos 
   2629      1.1  christos void
   2630      1.1  christos kvx_cfi_frame_initial_instructions (void)
   2631      1.1  christos {
   2632      1.1  christos   cfi_add_CFA_def_cfa (KVX_SP_REGNO, 0);
   2633      1.1  christos }
   2634      1.1  christos 
   2635      1.1  christos int
   2636      1.1  christos kvx_regname_to_dw2regnum (const char *regname)
   2637      1.1  christos {
   2638      1.1  christos   unsigned int regnum = -1;
   2639      1.1  christos   const char *p;
   2640      1.1  christos   char *q;
   2641      1.1  christos 
   2642      1.1  christos   if (regname[0] == 'r')
   2643      1.1  christos     {
   2644      1.1  christos       p = regname + 1;
   2645      1.1  christos       regnum = strtoul (p, &q, 10);
   2646      1.1  christos       if (p == q || *q || regnum >= 64)
   2647      1.1  christos 	return -1;
   2648      1.1  christos     }
   2649      1.1  christos   return regnum;
   2650      1.1  christos }
   2651