1 /* tc-kvx.c -- Assemble for the KVX ISA
3 Copyright (C) 2009-2023 Free Software Foundation, Inc.
4 Contributed by Kalray SA.
6 This file is part of GAS.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the license, or
11 (at your option) any later version.
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; see the file COPYING3. If not,
20 see <http://www.gnu.org/licenses/>. */
26 #include "libiberty.h"
36 #include "dwarf2dbg.h"
37 #include "dw2gencfi.h"
40 #define D(args...) do { if(debug) fprintf(args); } while(0)
42 static void supported_cores (char buf
[], size_t buflen
);
44 #define NELEMS(a) ((int) (sizeof (a)/sizeof ((a)[0])))
46 #define STREQ(x,y) !strcmp(((x) ? (x) : ""), ((y) ? (y) : ""))
47 #define STRNEQ(x,y,n) !strncmp(((x) ? (x) : ""), ((y) ? (y) : ""),(n))
49 /* The PARALLEL_BIT is set to 0 when an instruction is the last of a bundle. */
50 #define PARALLEL_BIT (1u << 31)
53 int size_type_function
= 1;
56 struct kvx_as_env env
= {
58 .abi
= ELF_KVX_ABI_UNDEF
,
59 .osabi
= ELFOSABI_NONE
,
69 .check_resource_usage
= 1,
70 .generate_illegal_code
= 0,
79 /* This string should contain position in string where error occured. */
81 /* Default kvx_registers array. */
82 const struct kvx_Register
*kvx_registers
= NULL
;
83 /* Default kvx_modifiers array. */
84 const char ***kvx_modifiers
= NULL
;
85 /* Default kvx_regfiles array. */
86 const int *kvx_regfiles
= NULL
;
87 /* Default values used if no assume directive is given */
88 const struct kvx_core_info
*kvx_core_info
= NULL
;
90 /***********************************************/
91 /* Generic Globals for GAS */
92 /***********************************************/
94 const char comment_chars
[] = "#";
95 const char line_comment_chars
[] = "#";
96 const char line_separator_chars
[] = ";";
97 const char EXP_CHARS
[] = "eE";
98 const char FLT_CHARS
[] = "dD";
99 const int md_short_jump_size
= 0;
100 const int md_long_jump_size
= 0;
102 /***********************************************/
104 /***********************************************/
106 /* a fix up record */
110 /* The expression used. */
112 /* The place in the frag where this goes. */
114 /* The relocation. */
115 bfd_reloc_code_real_type reloc
;
118 /* a single assembled instruction record */
119 /* may include immediate extension words */
124 /* Opcode table entry for this insn */
125 const struct kvxopc
*opdef
;
126 /* length of instruction in words (1 or 2) */
128 /* insn is extended */
130 /* insn has two immx */
132 /* order to stabilize sort */
134 /* instruction words */
135 uint32_t words
[KVXMAXBUNDLEWORDS
];
136 /* the number of fixups [0,2] */
138 /* the actual fixups */
139 struct kvx_fixup fixup
[2];
142 typedef void (*print_insn_t
) (struct kvxopc
* op
);
143 static print_insn_t print_insn
= NULL
;
145 /* Set to TRUE when we assemble instructions. */
146 static bool assembling_insn
= false;
150 /* Was KVXMAXBUNDLEISSUE, changed because of NOPs */
151 static struct kvxinsn insbuf
[KVXMAXBUNDLEWORDS
];
152 static int insncnt
= 0;
153 static struct kvxinsn immxbuf
[KVXMAXBUNDLEWORDS
];
154 static int immxcnt
= 0;
160 if (immxcnt
>= KVXMAXBUNDLEWORDS
)
161 as_bad ("Max immx number exceeded: %d", immxcnt
);
164 static void set_byte_counter (asection
* sec
, int value
);
166 set_byte_counter (asection
* sec
, int value
)
168 sec
->target_index
= value
;
171 static int get_byte_counter (asection
* sec
);
173 get_byte_counter (asection
* sec
)
175 return sec
->target_index
;
179 kvx_target_format (void)
181 return env
.params
.arch_size
== 64 ? "elf64-kvx" : "elf32-kvx";
184 /****************************************************/
185 /* ASSEMBLER Pseudo-ops. Some of this just */
186 /* extends the default definitions */
187 /* others are KVX specific */
188 /****************************************************/
190 static void kvx_check_resources (int);
191 static void kvx_proc (int start
);
192 static void kvx_endp (int start
);
193 static void kvx_type (int start
);
195 const pseudo_typeS md_pseudo_table
[] = {
196 /* override default 2-bytes */
200 { "dword", cons
, 8 },
202 /* Override align directives to have a boundary as argument (and not the
203 power of two as in p2align) */
204 { "align", s_align_bytes
, 0 },
206 { "checkresources", kvx_check_resources
, 1 },
207 { "nocheckresources", kvx_check_resources
, 0 },
209 { "proc", kvx_proc
, 1 },
210 { "endp", kvx_endp
, 0 },
212 { "type", kvx_type
, 0 },
215 { "file", dwarf2_directive_file
, 0 },
216 { "loc", dwarf2_directive_loc
, 0 },
222 static int inside_bundle
= 0;
224 /* Stores the labels inside bundles (typically debug labels) that need
225 to be postponed to the next bundle. */
228 struct label_fix
*next
;
232 /*****************************************************/
233 /* OPTIONS PROCESSING */
234 /*****************************************************/
236 const char *md_shortopts
= "hV"; /* catted to std short options */
238 /* added to std long options */
240 #define OPTION_HEXFILE (OPTION_MD_BASE + 0)
241 #define OPTION_MARCH (OPTION_MD_BASE + 4)
242 #define OPTION_CHECK_RESOURCES (OPTION_MD_BASE + 5)
243 #define OPTION_NO_CHECK_RESOURCES (OPTION_MD_BASE + 6)
244 #define OPTION_GENERATE_ILLEGAL_CODE (OPTION_MD_BASE + 7)
245 #define OPTION_DUMP_TABLE (OPTION_MD_BASE + 8)
246 #define OPTION_PIC (OPTION_MD_BASE + 9)
247 #define OPTION_BIGPIC (OPTION_MD_BASE + 10)
248 #define OPTION_NOPIC (OPTION_MD_BASE + 12)
249 #define OPTION_32 (OPTION_MD_BASE + 13)
250 #define OPTION_DUMPINSN (OPTION_MD_BASE + 15)
251 #define OPTION_ALL_SFR (OPTION_MD_BASE + 16)
252 #define OPTION_DIAGNOSTICS (OPTION_MD_BASE + 17)
253 #define OPTION_NO_DIAGNOSTICS (OPTION_MD_BASE + 18)
254 #define OPTION_MORE (OPTION_MD_BASE + 19)
255 #define OPTION_NO_MORE (OPTION_MD_BASE + 20)
257 struct option md_longopts
[] = {
258 { "march", required_argument
, NULL
, OPTION_MARCH
},
259 { "check-resources", no_argument
, NULL
, OPTION_CHECK_RESOURCES
},
260 { "no-check-resources", no_argument
, NULL
, OPTION_NO_CHECK_RESOURCES
},
261 { "generate-illegal-code", no_argument
, NULL
, OPTION_GENERATE_ILLEGAL_CODE
},
262 { "dump-table", no_argument
, NULL
, OPTION_DUMP_TABLE
},
263 { "mpic", no_argument
, NULL
, OPTION_PIC
},
264 { "mPIC", no_argument
, NULL
, OPTION_BIGPIC
},
265 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
266 { "m32", no_argument
, NULL
, OPTION_32
},
267 { "dump-insn", no_argument
, NULL
, OPTION_DUMPINSN
},
268 { "all-sfr", no_argument
, NULL
, OPTION_ALL_SFR
},
269 { "diagnostics", no_argument
, NULL
, OPTION_DIAGNOSTICS
},
270 { "no-diagnostics", no_argument
, NULL
, OPTION_NO_DIAGNOSTICS
},
271 { "more", no_argument
, NULL
, OPTION_MORE
},
272 { "no-more", no_argument
, NULL
, OPTION_NO_MORE
},
273 { NULL
, no_argument
, NULL
, 0 }
276 size_t md_longopts_size
= sizeof (md_longopts
);
279 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
286 md_show_usage (stdout
);
290 /* -V: SVR4 argument to print version ID. */
296 env
.opts
.march
= strdup (arg
);
297 for (int i
= 0; i
< KVXNUMCORES
&& !find_core
; ++i
)
298 if (!strcasecmp (env
.opts
.march
, kvx_core_info_table
[i
]->name
))
300 kvx_core_info
= kvx_core_info_table
[i
];
301 kvx_registers
= kvx_registers_table
[i
];
302 kvx_modifiers
= kvx_modifiers_table
[i
];
303 kvx_regfiles
= kvx_regfiles_table
[i
];
311 supported_cores (buf
, sizeof (buf
));
312 as_fatal ("Specified arch not supported [%s]", buf
);
315 case OPTION_CHECK_RESOURCES
:
316 env
.opts
.check_resource_usage
= 1;
318 case OPTION_NO_CHECK_RESOURCES
:
319 env
.opts
.check_resource_usage
= 0;
321 case OPTION_GENERATE_ILLEGAL_CODE
:
322 env
.opts
.generate_illegal_code
= 1;
324 case OPTION_DUMP_TABLE
:
325 env
.opts
.dump_table
= 1;
327 case OPTION_DUMPINSN
:
328 env
.opts
.dump_insn
= 1;
331 env
.opts
.allow_all_sfr
= 1;
333 case OPTION_DIAGNOSTICS
:
334 env
.opts
.diagnostics
= 1;
336 case OPTION_NO_DIAGNOSTICS
:
337 env
.opts
.diagnostics
= 0;
346 /* fallthrough, for now the same on KVX */
348 env
.params
.pic_flags
|= ELF_KVX_ABI_PIC_BIT
;
351 env
.params
.pic_flags
&= ~(ELF_KVX_ABI_PIC_BIT
);
354 env
.params
.arch_size
= 32;
364 md_show_usage (FILE * stream
)
367 supported_cores (buf
, sizeof (buf
));
369 fprintf (stream
, "\n"
370 "KVX specific options:\n\n"
371 " --check-resources\t Perform minimal resource checking\n"
372 " --march [%s]\t Select architecture\n"
373 " -V \t\t\t Print assembler version number\n\n"
374 " The options -M, --mri and -f are not supported in this assembler.\n", buf
);
377 /**************************************************/
379 /**************************************************/
382 * Read a value from to the object file
385 static valueT
md_chars_to_number (char *buf
, int n
);
387 md_chars_to_number (char *buf
, int n
)
391 if (n
> (int) sizeof (val
) || n
<= 0)
397 val
|= (buf
[n
] & 0xff);
403 /* Returns the corresponding pseudo function matching SYM and to be
404 used for data section */
405 static struct pseudo_func
*
406 kvx_get_pseudo_func_data_scn (symbolS
* sym
)
408 for (int i
= 0; i
< kvx_core_info
->nb_pseudo_funcs
; i
++)
409 if (sym
== kvx_core_info
->pseudo_funcs
[i
].sym
410 && kvx_core_info
->pseudo_funcs
[i
].pseudo_relocs
.single
!= BFD_RELOC_UNUSED
)
411 return &kvx_core_info
->pseudo_funcs
[i
];
415 /* Returns the corresponding pseudo function matching SYM and operand
417 static struct pseudo_func
*
418 kvx_get_pseudo_func2 (symbolS
*sym
, struct kvx_operand
* opnd
)
420 for (int i
= 0; i
< kvx_core_info
->nb_pseudo_funcs
; i
++)
421 if (sym
== kvx_core_info
->pseudo_funcs
[i
].sym
)
422 for (int relidx
= 0; relidx
< opnd
->reloc_nb
; relidx
++)
423 if (opnd
->relocs
[relidx
] == kvx_core_info
->pseudo_funcs
[i
].pseudo_relocs
.kreloc
424 && (env
.params
.arch_size
== (int) kvx_core_info
->pseudo_funcs
[i
].pseudo_relocs
.avail_modes
425 || kvx_core_info
->pseudo_funcs
[i
].pseudo_relocs
.avail_modes
== PSEUDO_ALL
))
426 return &kvx_core_info
->pseudo_funcs
[i
];
432 supported_cores (char buf
[], size_t buflen
)
435 for (int i
= 0; i
< KVXNUMCORES
; i
++)
438 strcpy (buf
, kvx_core_info_table
[i
]->name
);
440 if ((strlen (buf
) + 1 + strlen (kvx_core_info_table
[i
]->name
) + 1) < buflen
)
443 strcat (buf
, kvx_core_info_table
[i
]->name
);
448 /***************************************************/
449 /* ASSEMBLE AN INSTRUCTION */
450 /***************************************************/
453 * Insert ARG into the operand described by OPDEF in instruction INSN
454 * Returns 1 if the immediate extension (IMMX) has been
455 * handled along with relocation, 0 if not.
458 insert_operand (struct kvxinsn
*insn
, struct kvx_operand
*opdef
,
459 struct token_list
*tok
)
462 struct kvx_bitfield
*bfields
= opdef
->bfield
;
463 int bf_nb
= opdef
->bitfields
;
466 if (opdef
->width
== 0)
469 #define add_fixup(insn_, reloc_, exp_) \
471 (insn_)->fixup[(insn_)->nfixups].reloc = (reloc_); \
472 (insn_)->fixup[(insn_)->nfixups].exp = (exp_); \
473 (insn_)->fixup[(insn_)->nfixups].where = 0; \
474 (insn_)->nfixups++; \
477 #define add_immx(insn_, words_, reloc_, exp_, nfixups_, len_) \
479 immxbuf[immxcnt].words[0] = (words_); \
480 immxbuf[immxcnt].fixup[0].reloc = (reloc_); \
481 immxbuf[immxcnt].fixup[0].exp = (exp_); \
482 immxbuf[immxcnt].fixup[0].where = 0; \
483 immxbuf[immxcnt].nfixups = (nfixups_); \
484 immxbuf[immxcnt].len = (len_); \
485 /* decrement insn->len: immx part handled separately \
486 from insn and must not be emited twice. */ \
491 #define chk_imm(core_, imm_) \
492 (env.params.core == ELF_KVX_CORE_## core_ && opdef->type == (imm_))
494 /* try to resolve the value */
496 switch (tok
->category
)
499 op
= S_GET_VALUE (str_hash_find (env
.reg_hash
, tok
->tok
));
510 char *ilp_save
= input_line_pointer
;
511 input_line_pointer
= tok
->tok
;
512 expressionS exp
= { 0 };
514 input_line_pointer
= ilp_save
;
516 /* We are dealing with a pseudo-function. */
517 if (tok
->tok
[0] == '@')
519 if (insn
->nfixups
== 0)
521 expressionS reloc_arg
;
523 reloc_arg
.X_op
= O_symbol
;
524 struct pseudo_func
*pf
=
525 kvx_get_pseudo_func2 (exp
.X_op_symbol
, opdef
);
526 /* S64 uses LO10/UP27/EX27 format (3 words), with one reloc in each words (3) */
527 /* S43 uses LO10/EX6/UP27 format (2 words), with 2 relocs in main syllabes and 1 in extra word */
528 /* S37 uses LO10/UP27 format (2 words), with one reloc in each word (2) */
530 /* Beware that immxbuf must be filled in the same order as relocs should be emitted. */
532 if (pf
->pseudo_relocs
.reloc_type
== S64_LO10_UP27_EX27
533 || pf
->pseudo_relocs
.reloc_type
== S43_LO10_UP27_EX6
534 || pf
->pseudo_relocs
.reloc_type
== S37_LO10_UP27
)
536 add_fixup (insn
, pf
->pseudo_relocs
.reloc_lo10
, reloc_arg
);
538 insn
->immx0
= immxcnt
;
539 add_immx (insn
, 0, pf
->pseudo_relocs
.reloc_up27
,
543 else if (pf
->pseudo_relocs
.reloc_type
== S32_LO5_UP27
)
545 add_fixup (insn
, pf
->pseudo_relocs
.reloc_lo5
, reloc_arg
);
547 insn
->immx0
= immxcnt
;
548 add_immx (insn
, 0, pf
->pseudo_relocs
.reloc_up27
,
552 else if (pf
->pseudo_relocs
.reloc_type
== S16
)
553 add_fixup (insn
, pf
->pseudo_relocs
.single
, reloc_arg
);
555 as_fatal ("Unexpected fixup");
557 if (pf
->pseudo_relocs
.reloc_type
== S64_LO10_UP27_EX27
)
559 insn
->immx1
= immxcnt
;
560 add_immx (insn
, 0, pf
->pseudo_relocs
.reloc_ex
, reloc_arg
,
563 else if (pf
->pseudo_relocs
.reloc_type
== S43_LO10_UP27_EX6
)
564 add_fixup (insn
, pf
->pseudo_relocs
.reloc_ex
, reloc_arg
);
569 if (exp
.X_op
== O_constant
)
571 /* This is a immediate: either a regular immediate, or an
572 immediate that was saved in a variable through `.equ'. */
573 uint64_t sval
= (int64_t) tok
->val
;
574 op
= opdef
->flags
& kvxSIGNED
? sval
: tok
->val
;
577 else if (exp
.X_op
== O_subtract
)
578 as_fatal ("O_subtract not supported.");
582 /* This is a symbol which needs a relocation. */
583 if (insn
->nfixups
== 0)
585 if (chk_imm (KV3_1
, Immediate_kv3_v1_pcrel17
)
586 || chk_imm (KV3_2
, Immediate_kv3_v2_pcrel17
)
587 || chk_imm (KV4_1
, Immediate_kv4_v1_pcrel17
))
588 add_fixup (insn
, BFD_RELOC_KVX_PCREL17
, exp
);
589 else if (chk_imm (KV3_1
, Immediate_kv3_v1_pcrel27
)
590 || chk_imm (KV3_2
, Immediate_kv3_v2_pcrel27
)
591 || chk_imm (KV4_1
, Immediate_kv4_v1_pcrel27
))
592 add_fixup (insn
, BFD_RELOC_KVX_PCREL27
, exp
);
593 else if (chk_imm (KV3_1
, Immediate_kv3_v1_wrapped32
)
594 || chk_imm (KV3_2
, Immediate_kv3_v2_wrapped32
)
595 || chk_imm (KV4_1
, Immediate_kv4_v1_wrapped32
))
597 add_fixup (insn
, BFD_RELOC_KVX_S32_LO5
, exp
);
599 insn
->immx0
= immxcnt
;
600 add_immx (insn
, 0, BFD_RELOC_KVX_S32_UP27
, exp
, 1, 1);
604 else if (chk_imm (KV3_1
, Immediate_kv3_v1_signed10
)
605 || chk_imm (KV3_2
, Immediate_kv3_v2_signed10
)
606 || chk_imm (KV4_1
, Immediate_kv4_v1_signed10
))
607 add_fixup (insn
, BFD_RELOC_KVX_S37_LO10
, exp
);
608 else if (chk_imm (KV3_1
, Immediate_kv3_v1_signed37
)
609 || chk_imm (KV3_2
, Immediate_kv3_v2_signed37
)
610 || chk_imm (KV4_1
, Immediate_kv4_v1_signed37
))
612 add_fixup (insn
, BFD_RELOC_KVX_S37_LO10
, exp
);
614 insn
->immx0
= immxcnt
;
615 add_immx (insn
, 0, BFD_RELOC_KVX_S37_UP27
, exp
, 1, 1);
619 else if (chk_imm (KV3_1
, Immediate_kv3_v1_signed43
)
620 || chk_imm (KV3_2
, Immediate_kv3_v2_signed43
)
621 || chk_imm (KV4_1
, Immediate_kv4_v1_signed43
))
623 add_fixup (insn
, BFD_RELOC_KVX_S43_LO10
, exp
);
624 add_fixup (insn
, BFD_RELOC_KVX_S43_EX6
, exp
);
626 insn
->immx0
= immxcnt
;
627 add_immx (insn
, insn
->words
[1],
628 BFD_RELOC_KVX_S43_UP27
, exp
, 1, 1);
632 else if (chk_imm (KV3_1
, Immediate_kv3_v1_wrapped64
)
633 || chk_imm (KV3_2
, Immediate_kv3_v2_wrapped64
)
634 || chk_imm (KV4_1
, Immediate_kv4_v1_wrapped64
))
636 add_fixup (insn
, BFD_RELOC_KVX_S64_LO10
, exp
);
638 insn
->immx0
= immxcnt
;
639 add_immx (insn
, insn
->words
[1],
640 BFD_RELOC_KVX_S64_UP27
, exp
, 1, 1);
642 insn
->immx1
= immxcnt
;
643 add_immx (insn
, insn
->words
[2],
644 BFD_RELOC_KVX_S64_EX27
, exp
, 1, 1);
649 as_fatal ("don't know how to generate a fixup record");
653 as_fatal ("No room for fixup ");
662 for (int bf_idx
= 0; bf_idx
< bf_nb
; bf_idx
++)
665 ((uint64_t) op
>> bfields
[bf_idx
].from_offset
);
667 int to_offset
= bfields
[bf_idx
].to_offset
;
668 value
&= (1LL << bfields
[bf_idx
].size
) - 1;
670 to_offset
= to_offset
% 32;
671 insn
->words
[j
] |= (value
<< to_offset
) & 0xffffffff;
682 * Given a set of operands and a matching instruction,
687 assemble_insn (const struct kvxopc
* opcode
, struct token_list
*tok
, struct kvxinsn
*insn
)
689 unsigned immx_ready
= 0;
691 memset (insn
, 0, sizeof (*insn
));
692 insn
->opdef
= opcode
;
693 for (int i
= 0; i
< opcode
->wordcount
; i
++)
695 insn
->words
[i
] = opcode
->codewords
[i
].opcode
;
699 insn
->immx0
= NOIMMX
;
700 insn
->immx1
= NOIMMX
;
702 struct token_list
*tok_
= tok
;
703 struct kvx_operand
**format
= (struct kvx_operand
**) opcode
->format
;
707 int ret
= insert_operand (insn
, *format
, tok_
);
709 while ((tok_
= tok_
->next
) && tok_
->category
== CAT_SEPARATOR
);
713 // Handle immx if insert_operand did not already take care of that
716 for (int i
= 0; i
< opcode
->wordcount
; i
++)
718 if (opcode
->codewords
[i
].flags
& kvxOPCODE_FLAG_IMMX0
)
720 insn
->immx0
= immxcnt
;
721 immxbuf
[immxcnt
].words
[0] = insn
->words
[i
];
722 immxbuf
[immxcnt
].nfixups
= 0;
723 immxbuf
[immxcnt
].len
= 1;
727 if (opcode
->codewords
[i
].flags
& kvxOPCODE_FLAG_IMMX1
)
729 insn
->immx1
= immxcnt
;
730 immxbuf
[immxcnt
].words
[0] = insn
->words
[i
];
731 immxbuf
[immxcnt
].nfixups
= 0;
732 immxbuf
[immxcnt
].len
= 1;
740 /* Emit an instruction from the instruction array into the object
741 * file. INSN points to an element of the instruction array. STOPFLAG
742 * is true if this is the last instruction in the bundle.
744 * Only handles main syllables of bundle. Immediate extensions are
745 * handled by insert_operand.
748 emit_insn (struct kvxinsn
* insn
, int insn_pos
, int stopflag
)
753 /* if we are listing, attach frag to previous line. */
755 listing_prev_line ();
757 /* Update text size for lane parity checking. */
758 set_byte_counter (now_seg
, (get_byte_counter (now_seg
) + (insn
->len
* 4)));
760 /* allocate space in the fragment. */
761 f
= frag_more (insn
->len
* 4);
764 for (int i
= 0; i
< insn
->len
; i
++)
766 image
= insn
->words
[i
];
768 /* Handle bundle parallel bit. */ ;
769 if ((i
== insn
->len
- 1) && stopflag
)
770 image
&= ~PARALLEL_BIT
;
772 image
|= PARALLEL_BIT
;
774 /* Emit the instruction image. */
775 md_number_to_chars (f
+ (i
* 4), image
, 4);
778 /* generate fixup records */
780 for (int i
= 0; i
< insn
->nfixups
; i
++)
783 reloc_howto_type
*reloc_howto
=
784 bfd_reloc_type_lookup (stdoutput
, insn
->fixup
[i
].reloc
);
785 assert (reloc_howto
);
786 size
= bfd_get_reloc_size (reloc_howto
);
787 pcrel
= reloc_howto
->pc_relative
;
789 /* In case the PCREL relocation is not for the first insn in the
790 bundle, we have to offset it. The pc used by the hardware
791 references a bundle and not separate insn.
793 assert (!(insn_pos
== -1 && pcrel
));
794 if (pcrel
&& insn_pos
> 0)
795 insn
->fixup
[i
].exp
.X_add_number
+= insn_pos
* 4;
797 fixS
*fixup
= fix_new_exp (frag_now
,
798 f
- frag_now
->fr_literal
+
799 insn
->fixup
[i
].where
,
801 &(insn
->fixup
[i
].exp
),
803 insn
->fixup
[i
].reloc
);
805 * Set this bit so that large value can still be
806 * handled. Without it, assembler will fail in fixup_segment
807 * when it checks there is enough bits to store the value. As we
808 * usually split our reloc across different words, it may think
809 * that 4 bytes are not enough for large value. This simply
812 fixup
->fx_no_overflow
= 1;
817 /* Called for any expression that can not be recognized. When the
818 * function is called, `input_line_pointer' will point to the start of
820 /* FIXME: Should be done by the parser */
822 md_operand (expressionS
* e
)
824 /* enum pseudo_type pseudo_type; */
825 /* char *name = NULL; */
829 switch (*input_line_pointer
)
832 /* Find what relocation pseudo-function we're dealing with. */
833 /* pseudo_type = 0; */
834 ch
= *++input_line_pointer
;
835 for (i
= 0; i
< kvx_core_info
->nb_pseudo_funcs
; ++i
)
836 if (kvx_core_info
->pseudo_funcs
[i
].name
&& kvx_core_info
->pseudo_funcs
[i
].name
[0] == ch
)
838 len
= strlen (kvx_core_info
->pseudo_funcs
[i
].name
);
839 if (strncmp (kvx_core_info
->pseudo_funcs
[i
].name
+ 1,
840 input_line_pointer
+ 1, len
- 1) == 0
841 && !is_part_of_name (input_line_pointer
[len
]))
843 input_line_pointer
+= len
;
848 if (*input_line_pointer
!= '(')
850 as_bad ("Expected '('");
854 ++input_line_pointer
;
855 if (!kvx_core_info
->pseudo_funcs
[i
].pseudo_relocs
.has_no_arg
)
857 if (*input_line_pointer
++ != ')')
859 as_bad ("Missing ')'");
862 if (!kvx_core_info
->pseudo_funcs
[i
].pseudo_relocs
.has_no_arg
)
864 if (e
->X_op
!= O_symbol
)
865 as_fatal ("Illegal combination of relocation functions");
867 /* Make sure gas doesn't get rid of local symbols that are used
869 e
->X_op
= O_pseudo_fixup
;
870 e
->X_op_symbol
= kvx_core_info
->pseudo_funcs
[i
].sym
;
879 ignore_rest_of_line ();
883 * Return the Bundling type for an insn.
886 find_bundling (const struct kvxinsn
* insn
)
888 return insn
->opdef
->bundling
;
892 find_reservation (const struct kvxinsn
* insn
)
894 return insn
->opdef
->reservation
;
897 static struct kvxopc
*
898 assemble_tokens (struct token_list
*tok_list
)
900 assert (tok_list
!= NULL
);
901 struct token_list
*toks
= tok_list
;
903 /* make sure there is room in instruction buffer */
904 /* Was KVXMAXBUNDLEISSUE, changed because of NOPs */
905 if (insncnt
>= KVXMAXBUNDLEWORDS
)
906 as_fatal ("[assemble_tokens]: too many instructions in bundle.");
909 struct kvxinsn
*insn
;
910 insn
= insbuf
+ insncnt
;
912 /* The formats table registers the modifier into the opcode, therefore we need
913 to fuse both before looking up the opcodes hashtable. */
919 while (toks
&& toks
->category
== CAT_SEPARATOR
)
922 /* Find the format requested by the instruction. */
923 struct kvxopc
*format_tbl
= str_hash_find (env
.opcode_hash
, opcode
);
924 struct kvxopc
*format
= NULL
;
926 struct token_list
*toks_
= toks
;
928 while (!format
&& format_tbl
&& STREQ (opcode
, format_tbl
->as_op
))
930 for (int i
= 0 ; toks_
&& format_tbl
->format
[i
]
931 && toks_
->class_id
== format_tbl
->format
[i
]->type
;)
934 while (toks_
&& toks_
->category
== CAT_SEPARATOR
)
948 assert (format
!= NULL
);
950 assemble_insn (format
, toks
, insn
);
957 * Write in buf at most buf_size.
958 * Returns the number of writen characters.
960 static int ATTRIBUTE_UNUSED
961 insn_syntax (struct kvxopc
* op
, char *buf
, int buf_size
)
963 int chars
= snprintf (buf
, buf_size
, "%s ", op
->as_op
);
964 const char *fmtp
= op
->fmtstring
;
967 for (int i
= 0; op
->format
[i
]; i
++)
969 int type
= op
->format
[i
]->type
;
970 const char *type_name
= TOKEN_NAME (type
);
973 for (int j
= 0 ; type_name
[j
] ; ++j
)
974 if (type_name
[j
] == '_')
977 /* Print characters in the format string up to the following * % or nul. */
978 while ((chars
< buf_size
) && (ch
= *fmtp
) && ch
!= '%')
991 chars
+= snprintf (&buf
[chars
], buf_size
- chars
, "%s", type_name
+ offset
);
994 /* Print trailing characters in the format string, if any */
995 while ((chars
< buf_size
) && (ch
= *fmtp
))
1001 if (chars
< buf_size
)
1002 buf
[chars
++] = '\0';
1004 buf
[buf_size
- 1] = '\0';
1009 #define ASM_CHARS_MAX (71)
1012 kvx_print_insn (struct kvxopc
* op ATTRIBUTE_UNUSED
)
1014 char asm_str
[ASM_CHARS_MAX
];
1015 int chars
= insn_syntax (op
, asm_str
, ASM_CHARS_MAX
);
1016 const char *insn_type
= "UNKNOWN";
1017 const char *insn_mode
= "";
1019 for (int i
= chars
- 1; i
< ASM_CHARS_MAX
- 1; i
++)
1022 /* This is a hack which works because the Bundling is the same for all cores
1024 switch ((int) op
->bundling
)
1026 case Bundling_kv3_v1_ALL
:
1029 case Bundling_kv3_v1_BCU
:
1032 case Bundling_kv3_v1_TCA
:
1035 case Bundling_kv3_v1_FULL
:
1036 case Bundling_kv3_v1_FULL_X
:
1037 case Bundling_kv3_v1_FULL_Y
:
1038 insn_type
= "FULL ";
1040 case Bundling_kv3_v1_LITE
:
1041 case Bundling_kv3_v1_LITE_X
:
1042 case Bundling_kv3_v1_LITE_Y
:
1043 insn_type
= "LITE ";
1045 case Bundling_kv3_v1_TINY
:
1046 case Bundling_kv3_v1_TINY_X
:
1047 case Bundling_kv3_v1_TINY_Y
:
1048 insn_type
= "TINY ";
1050 case Bundling_kv3_v1_MAU
:
1051 case Bundling_kv3_v1_MAU_X
:
1052 case Bundling_kv3_v1_MAU_Y
:
1055 case Bundling_kv3_v1_LSU
:
1056 case Bundling_kv3_v1_LSU_X
:
1057 case Bundling_kv3_v1_LSU_Y
:
1060 case Bundling_kv3_v1_NOP
:
1064 as_fatal ("Unhandled Bundling class %d", op
->bundling
);
1067 if (op
->codewords
[0].flags
& kvxOPCODE_FLAG_MODE64
1068 && op
->codewords
[0].flags
& kvxOPCODE_FLAG_MODE32
)
1069 insn_mode
= "32 and 64";
1070 else if (op
->codewords
[0].flags
& kvxOPCODE_FLAG_MODE64
)
1072 else if (op
->codewords
[0].flags
& kvxOPCODE_FLAG_MODE32
)
1075 as_fatal ("Unknown instruction mode.");
1077 printf ("%s | syllables: %d | type: %s | mode: %s bits\n", asm_str
,
1078 op
->wordcount
, insn_type
, insn_mode
);
1081 /* Comparison function compatible with qsort. This is used to sort the issues
1082 into the right order. */
1084 kvxinsn_compare (const void *a
, const void *b
)
1086 struct kvxinsn
*kvxinsn_a
= *(struct kvxinsn
**) a
;
1087 struct kvxinsn
*kvxinsn_b
= *(struct kvxinsn
**) b
;
1088 int bundling_a
= find_bundling (kvxinsn_a
);
1089 int bundling_b
= find_bundling (kvxinsn_b
);
1090 int order_a
= kvxinsn_a
->order
;
1091 int order_b
= kvxinsn_b
->order
;
1092 if (bundling_a
!= bundling_b
)
1093 return (bundling_b
< bundling_a
) - (bundling_a
< bundling_b
);
1094 return (order_b
< order_a
) - (order_a
< order_b
);
1098 kvx_reorder_bundle (struct kvxinsn
*bundle_insn
[], int bundle_insncnt
)
1101 { EXU_BCU
, EXU_TCA
, EXU_ALU0
, EXU_ALU1
, EXU_MAU
, EXU_LSU
, EXU__
};
1102 struct kvxinsn
*issued
[EXU__
];
1105 memset (issued
, 0, sizeof (issued
));
1106 for (int i
= 0; i
< bundle_insncnt
; i
++)
1108 struct kvxinsn
*kvxinsn
= bundle_insn
[i
];
1110 /* This is a hack. It works because all the Bundling are the same for all
1112 switch ((int) find_bundling (kvxinsn
))
1114 case Bundling_kv3_v1_ALL
:
1115 if (bundle_insncnt
> 1)
1116 as_fatal ("Too many ops in a single op bundle");
1117 issued
[0] = kvxinsn
;
1119 case Bundling_kv3_v1_BCU
:
1120 if (!issued
[EXU_BCU
])
1121 issued
[EXU_BCU
] = kvxinsn
;
1123 as_fatal ("More than one BCU instruction in bundle");
1125 case Bundling_kv3_v1_TCA
:
1126 if (!issued
[EXU_TCA
])
1127 issued
[EXU_TCA
] = kvxinsn
;
1129 as_fatal ("More than one TCA instruction in bundle");
1131 case Bundling_kv3_v1_FULL
:
1132 case Bundling_kv3_v1_FULL_X
:
1133 case Bundling_kv3_v1_FULL_Y
:
1134 if (!issued
[EXU_ALU0
])
1136 issued
[EXU_ALU0
] = kvxinsn
;
1137 tag
= Modifier_kv3_v1_exunum_ALU0
;
1141 as_fatal ("More than one ALU FULL instruction in bundle");
1143 case Bundling_kv3_v1_LITE
:
1144 case Bundling_kv3_v1_LITE_X
:
1145 case Bundling_kv3_v1_LITE_Y
:
1146 if (!issued
[EXU_ALU0
])
1148 issued
[EXU_ALU0
] = kvxinsn
;
1149 tag
= Modifier_kv3_v1_exunum_ALU0
;
1152 else if (!issued
[EXU_ALU1
])
1154 issued
[EXU_ALU1
] = kvxinsn
;
1155 tag
= Modifier_kv3_v1_exunum_ALU1
;
1159 as_fatal ("Too many ALU FULL or LITE instructions in bundle");
1161 case Bundling_kv3_v1_MAU
:
1162 case Bundling_kv3_v1_MAU_X
:
1163 case Bundling_kv3_v1_MAU_Y
:
1164 if (!issued
[EXU_MAU
])
1166 issued
[EXU_MAU
] = kvxinsn
;
1167 tag
= Modifier_kv3_v1_exunum_MAU
;
1171 as_fatal ("More than one MAU instruction in bundle");
1173 case Bundling_kv3_v1_LSU
:
1174 case Bundling_kv3_v1_LSU_X
:
1175 case Bundling_kv3_v1_LSU_Y
:
1176 if (!issued
[EXU_LSU
])
1178 issued
[EXU_LSU
] = kvxinsn
;
1179 tag
= Modifier_kv3_v1_exunum_LSU
;
1183 as_fatal ("More than one LSU instruction in bundle");
1185 case Bundling_kv3_v1_TINY
:
1186 case Bundling_kv3_v1_TINY_X
:
1187 case Bundling_kv3_v1_TINY_Y
:
1188 case Bundling_kv3_v1_NOP
:
1189 if (!issued
[EXU_ALU0
])
1191 issued
[EXU_ALU0
] = kvxinsn
;
1192 tag
= Modifier_kv3_v1_exunum_ALU0
;
1195 else if (!issued
[EXU_ALU1
])
1197 issued
[EXU_ALU1
] = kvxinsn
;
1198 tag
= Modifier_kv3_v1_exunum_ALU1
;
1201 else if (!issued
[EXU_MAU
])
1203 issued
[EXU_MAU
] = kvxinsn
;
1204 tag
= Modifier_kv3_v1_exunum_MAU
;
1207 else if (!issued
[EXU_LSU
])
1209 issued
[EXU_LSU
] = kvxinsn
;
1210 tag
= Modifier_kv3_v1_exunum_LSU
;
1214 as_fatal ("Too many ALU instructions in bundle");
1217 as_fatal ("Unhandled Bundling class %d", find_bundling (kvxinsn
));
1221 if (issued
[exu
]->immx0
!= NOIMMX
)
1222 immxbuf
[issued
[exu
]->immx0
].words
[0] |= (tag
<< 27);
1223 if (issued
[exu
]->immx1
!= NOIMMX
)
1224 immxbuf
[issued
[exu
]->immx1
].words
[0] |= (tag
<< 27);
1229 for (i
= 0, exu
= 0; exu
< EXU__
; exu
++)
1232 bundle_insn
[i
++] = issued
[exu
];
1234 if (i
!= bundle_insncnt
)
1235 as_fatal ("Mismatch between bundle and issued instructions");
1239 kvx_check_resource_usage (struct kvxinsn
**bundle_insn
, int bundle_insncnt
)
1241 const int reservation_table_len
=
1242 (kvx_core_info
->reservation_table_lines
* kvx_core_info
->resource_max
);
1243 const int *resources
= kvx_core_info
->resources
;
1244 int *resources_used
=
1245 malloc (reservation_table_len
* sizeof (int));
1246 memset (resources_used
, 0, reservation_table_len
* sizeof (int));
1248 for (int i
= 0; i
< bundle_insncnt
; i
++)
1250 int insn_reservation
= find_reservation (bundle_insn
[i
]);
1251 int reservation
= insn_reservation
& 0xff;
1252 const int *reservation_table
= kvx_core_info
->reservation_table_table
[reservation
];
1253 for (int j
= 0; j
< reservation_table_len
; j
++)
1254 resources_used
[j
] += reservation_table
[j
];
1257 for (int i
= 0; i
< kvx_core_info
->reservation_table_lines
; i
++)
1259 for (int j
= 0; j
< kvx_core_info
->resource_max
; j
++)
1260 if (resources_used
[(i
* kvx_core_info
->resource_max
) + j
] > resources
[j
])
1262 int v
= resources_used
[(i
* kvx_core_info
->resource_max
) + j
];
1263 free (resources_used
);
1264 as_fatal ("Resource %s over-used in bundle: %d used, %d available",
1265 kvx_core_info
->resource_names
[j
], v
, resources
[j
]);
1268 free (resources_used
);
1272 * Called by core to assemble a single line
1275 md_assemble (char *line
)
1277 char *line_cursor
= line
;
1279 if (get_byte_counter (now_seg
) & 3)
1280 as_fatal ("code segment not word aligned in md_assemble");
1282 while (line_cursor
&& line_cursor
[0] && (line_cursor
[0] == ' '))
1285 /* ;; was converted to "be" by line hook */
1286 /* here we look for the bundle end */
1287 /* and actually output any instructions in bundle */
1288 /* also we need to implement the stop bit */
1289 /* check for bundle end */
1290 if (strncmp (line_cursor
, "be", 2) == 0)
1293 //int sec_align = bfd_get_section_alignment(stdoutput, now_seg);
1294 /* Was KVXMAXBUNDLEISSUE, changed because of NOPs */
1295 struct kvxinsn
*bundle_insn
[KVXMAXBUNDLEWORDS
];
1296 int bundle_insncnt
= 0;
1301 /* Emit Dwarf debug line information */
1302 dwarf2_emit_insn (0);
1304 for (int j
= 0; j
< insncnt
; j
++)
1306 insbuf
[j
].order
= j
;
1307 bundle_insn
[bundle_insncnt
++] = &insbuf
[j
];
1308 syllables
+= insbuf
[j
].len
;
1311 if (syllables
+ immxcnt
> KVXMAXBUNDLEWORDS
)
1312 as_fatal ("Bundle has too many syllables : %d instead of %d",
1313 syllables
+ immxcnt
, KVXMAXBUNDLEWORDS
);
1315 if (env
.opts
.check_resource_usage
)
1316 kvx_check_resource_usage (bundle_insn
, bundle_insncnt
);
1318 /* Reorder and check the bundle. */
1319 if (!env
.opts
.generate_illegal_code
)
1321 /* Sort the bundle_insn in order of bundling. */
1322 qsort (bundle_insn
, bundle_insncnt
, sizeof (struct kvxinsn
*), kvxinsn_compare
);
1324 kvx_reorder_bundle (bundle_insn
, bundle_insncnt
);
1327 /* The ordering of the insns has been set correctly in bundle_insn. */
1328 for (int i
= 0; i
< bundle_insncnt
; i
++)
1330 emit_insn (bundle_insn
[i
], i
, (i
== bundle_insncnt
+ immxcnt
- 1));
1331 bundle_insn
[i
]->written
= 1;
1334 // Emit immx, ordering them by EXU tags, 0 to 3
1336 for (int tag
= 0; tag
< 4; tag
++)
1338 for (int j
= 0; j
< immxcnt
; j
++)
1340 #define kv3_exunum2_fld(x) (int)(((unsigned int)(x) >> 27) & 0x3)
1341 if (kv3_exunum2_fld (immxbuf
[j
].words
[0]) == tag
)
1343 assert (immxbuf
[j
].written
== 0);
1344 int insn_pos
= bundle_insncnt
+ entry
;
1345 emit_insn (&(immxbuf
[j
]), insn_pos
, entry
== immxcnt
- 1);
1346 immxbuf
[j
].written
= 1;
1349 #undef kv3_exunum2_fld
1352 if (entry
!= immxcnt
)
1353 as_fatal ("%d IMMX produced, only %d emitted.", immxcnt
, entry
);
1355 /* The debug label that appear in the middle of bundles
1356 had better appear to be attached to the next
1357 bundle. This is because usually these labels point to
1358 the first instruction where some condition is met. If
1359 the label isn't handled this way it will be attached to
1360 the current bundle which is wrong as the corresponding
1361 instruction wasn't executed yet. */
1364 struct label_fix
*fix
= label_fixes
;
1366 label_fixes
= fix
->next
;
1367 symbol_set_value_now (fix
->sym
);
1373 memset (immxbuf
, 0, sizeof (immxbuf
));
1379 sscanf (line_cursor
, "%m[^\n]", &buf
);
1380 struct token_s my_tok
= { .insn
= buf
, .begin
= 0, .end
= 0, .class_id
= -1 , .val
= 0 };
1381 struct token_list
*tok_lst
= parse (my_tok
);
1388 line_cursor
+= strlen (tok_lst
->tok
);
1390 assembling_insn
= true;
1393 assemble_tokens (tok_lst
);
1394 free_token_list (tok_lst
);
1395 assembling_insn
= false;
1402 kvx_core_info
= &kvx_kv3_v1_core_info
;
1405 kvx_registers
= kvx_kv3_v1_registers
;
1408 kvx_regfiles
= kvx_kv3_v1_regfiles
;
1411 kvx_modifiers
= kvx_kv3_v1_modifiers
;
1413 if (env
.params
.core
== -1)
1414 env
.params
.core
= kvx_core_info
->elf_core
;
1417 print_insn
= kvx_print_insn
;
1419 switch (kvx_core_info
->elf_core
)
1421 case ELF_KVX_CORE_KV3_1
:
1422 kvx_bfd_mach
= env
.params
.arch_size
== 32 ? bfd_mach_kv3_1
: bfd_mach_kv3_1_64
;
1423 setup (ELF_KVX_CORE_KV3_1
);
1425 case ELF_KVX_CORE_KV3_2
:
1426 kvx_bfd_mach
= env
.params
.arch_size
== 32 ? bfd_mach_kv3_2
: bfd_mach_kv3_2_64
;
1427 setup (ELF_KVX_CORE_KV3_2
);
1429 case ELF_KVX_CORE_KV4_1
:
1430 kvx_bfd_mach
= env
.params
.arch_size
== 32 ? bfd_mach_kv4_1
: bfd_mach_kv4_1_64
;
1431 setup (ELF_KVX_CORE_KV4_1
);
1434 as_fatal ("Unknown elf core: 0x%x", kvx_core_info
->elf_core
);
1437 if (!bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, kvx_bfd_mach
))
1438 as_warn (_("could not set architecture and machine"));
1442 kvxop_compar (const void *a
, const void *b
)
1444 const struct kvxopc
*opa
= (const struct kvxopc
*) a
;
1445 const struct kvxopc
*opb
= (const struct kvxopc
*) b
;
1446 int res
= strcmp (opa
->as_op
, opb
->as_op
);
1452 for (int i
= 0; opa
->format
[i
] && opb
->format
[i
]; ++i
)
1453 if (opa
->format
[i
]->width
!= opb
->format
[i
]->width
)
1454 return opa
->format
[i
]->width
- opb
->format
[i
]->width
;
1459 /***************************************************/
1460 /* INITIALIZE ASSEMBLER */
1461 /***************************************************/
1464 print_hash (void **slot
, void *arg ATTRIBUTE_UNUSED
)
1466 string_tuple_t
*tuple
= *((string_tuple_t
**) slot
);
1467 printf ("%s\n", tuple
->key
);
1472 declare_register (const char *name
, int number
)
1474 symbolS
*regS
= symbol_create (name
, reg_section
,
1475 &zero_address_frag
, number
);
1477 if (str_hash_insert (env
.reg_hash
, S_GET_NAME (regS
), regS
, 0) != NULL
)
1478 as_fatal (_("duplicate %s"), name
);
1487 * Declare register names with symbols
1490 env
.reg_hash
= str_htab_create ();
1492 for (int i
= 0; i
< kvx_regfiles
[KVX_REGFILE_REGISTERS
]; i
++)
1493 declare_register (kvx_registers
[i
].name
, kvx_registers
[i
].id
);
1495 /* Sort optab, so that identical mnemonics appear consecutively */
1498 for (nel
= 0; !STREQ ("", kvx_core_info
->optab
[nel
].as_op
); nel
++)
1500 qsort (kvx_core_info
->optab
, nel
, sizeof (kvx_core_info
->optab
[0]),
1504 /* The '?' is an operand separator */
1507 /* Create the opcode hash table */
1508 /* Each name should appear only once */
1510 env
.opcode_hash
= str_htab_create ();
1511 env
.reloc_hash
= str_htab_create ();
1515 const char *name
= 0;
1516 for (op
= kvx_core_info
->optab
; !(STREQ ("", op
->as_op
)); op
++)
1518 /* enter in hash table if this is a new name */
1519 if (!(STREQ (name
, op
->as_op
)))
1522 if (str_hash_insert (env
.opcode_hash
, name
, op
, 0))
1523 as_fatal ("internal error: can't hash opcode `%s'", name
);
1527 for (int i
= 0 ; op
->format
[i
] ; ++i
)
1529 const char *reloc_name
= TOKEN_NAME (op
->format
[i
]->type
);
1530 void *relocs
= op
->format
[i
]->relocs
;
1531 if (op
->format
[i
]->relocs
[0] != 0
1532 && !str_hash_find (env
.reloc_hash
, reloc_name
))
1533 if (str_hash_insert (env
.reloc_hash
, reloc_name
, relocs
, 0))
1534 as_fatal ("internal error: can't hash type `%s'", reloc_name
);
1539 if (env
.opts
.dump_table
)
1541 htab_traverse (env
.opcode_hash
, print_hash
, NULL
);
1545 if (env
.opts
.dump_insn
)
1547 for (struct kvxopc
*op
= kvx_core_info
->optab
; !(STREQ ("", op
->as_op
)); op
++)
1552 /* Here we enforce the minimum section alignment. Remember, in
1553 * the linker we can make the boudaries between the linked sections
1554 * on larger boundaries. The text segment is aligned to long words
1555 * because of the odd/even constraint on immediate extensions
1558 bfd_set_section_alignment (text_section
, 3); /* -- 8 bytes */
1559 bfd_set_section_alignment (data_section
, 2); /* -- 4 bytes */
1560 bfd_set_section_alignment (bss_section
, 2); /* -- 4 bytes */
1561 subseg_set (text_section
, 0);
1563 symbolS
*gotoff_sym
= symbol_create (".<gotoff>", undefined_section
, &zero_address_frag
, 0);
1564 symbolS
*got_sym
= symbol_create (".<got>", undefined_section
, &zero_address_frag
, 0);
1565 symbolS
*plt_sym
= symbol_create (".<plt>", undefined_section
, &zero_address_frag
, 0);
1566 symbolS
*tlsgd_sym
= symbol_create (".<tlsgd>", undefined_section
, &zero_address_frag
, 0);
1567 symbolS
*tlsie_sym
= symbol_create (".<tlsie>", undefined_section
, &zero_address_frag
, 0);
1568 symbolS
*tlsle_sym
= symbol_create (".<tlsle>", undefined_section
, &zero_address_frag
, 0);
1569 symbolS
*tlsld_sym
= symbol_create (".<tlsld>", undefined_section
, &zero_address_frag
, 0);
1570 symbolS
*dtpoff_sym
= symbol_create (".<dtpoff>", undefined_section
, &zero_address_frag
, 0);
1571 symbolS
*plt64_sym
= symbol_create (".<plt64>", undefined_section
, &zero_address_frag
, 0);
1572 symbolS
*gotaddr_sym
= symbol_create (".<gotaddr>", undefined_section
, &zero_address_frag
, 0);
1573 symbolS
*pcrel16_sym
= symbol_create (".<pcrel16>", undefined_section
, &zero_address_frag
, 0);
1574 symbolS
*pcrel_sym
= symbol_create (".<pcrel>", undefined_section
, &zero_address_frag
, 0);
1575 symbolS
*signed32_sym
= symbol_create (".<signed32>", undefined_section
, &zero_address_frag
, 0);
1577 for (int i
= 0; i
< kvx_core_info
->nb_pseudo_funcs
; ++i
)
1580 if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "gotoff"))
1582 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "got"))
1584 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "plt"))
1586 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "tlsgd"))
1588 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "tlsle"))
1590 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "tlsld"))
1592 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "dtpoff"))
1594 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "tlsie"))
1596 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "plt64"))
1598 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "pcrel16"))
1600 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "pcrel"))
1602 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "gotaddr"))
1604 else if (!strcmp (kvx_core_info
->pseudo_funcs
[i
].name
, "signed32"))
1607 as_fatal ("internal error: Unknown pseudo func `%s'",
1608 kvx_core_info
->pseudo_funcs
[i
].name
);
1610 kvx_core_info
->pseudo_funcs
[i
].sym
= sym
;
1614 /***************************************************/
1615 /* ASSEMBLER CLEANUP STUFF */
1616 /***************************************************/
1618 /* Return non-zero if the indicated VALUE has overflowed the maximum
1619 range expressible by a signed number with the indicated number of
1622 This is from tc-aarch64.c
1626 signed_overflow (offsetT value
, unsigned bits
)
1629 if (bits
>= sizeof (offsetT
) * 8)
1631 lim
= (offsetT
) 1 << (bits
- 1);
1632 return (value
< -lim
|| value
>= lim
);
1635 /***************************************************/
1636 /* ASSEMBLER FIXUP STUFF */
1637 /***************************************************/
1640 md_apply_fix (fixS
* fixP
, valueT
* valueP
, segT segmentP ATTRIBUTE_UNUSED
)
1642 char *const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1643 valueT value
= *valueP
;
1647 rel
= (arelent
*) xmalloc (sizeof (arelent
));
1649 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
1650 if (rel
->howto
== NULL
)
1653 ("[md_apply_fix] unsupported relocation type (can't find howto)");
1656 /* Note whether this will delete the relocation. */
1657 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
1660 if (fixP
->fx_size
> 0)
1661 image
= md_chars_to_number (fixpos
, fixP
->fx_size
);
1664 if (fixP
->fx_addsy
!= NULL
)
1666 switch (fixP
->fx_r_type
)
1668 case BFD_RELOC_KVX_S37_TLS_LE_UP27
:
1669 case BFD_RELOC_KVX_S37_TLS_LE_LO10
:
1671 case BFD_RELOC_KVX_S43_TLS_LE_EX6
:
1672 case BFD_RELOC_KVX_S43_TLS_LE_UP27
:
1673 case BFD_RELOC_KVX_S43_TLS_LE_LO10
:
1675 case BFD_RELOC_KVX_S37_TLS_GD_LO10
:
1676 case BFD_RELOC_KVX_S37_TLS_GD_UP27
:
1678 case BFD_RELOC_KVX_S43_TLS_GD_LO10
:
1679 case BFD_RELOC_KVX_S43_TLS_GD_UP27
:
1680 case BFD_RELOC_KVX_S43_TLS_GD_EX6
:
1682 case BFD_RELOC_KVX_S37_TLS_IE_LO10
:
1683 case BFD_RELOC_KVX_S37_TLS_IE_UP27
:
1685 case BFD_RELOC_KVX_S43_TLS_IE_LO10
:
1686 case BFD_RELOC_KVX_S43_TLS_IE_UP27
:
1687 case BFD_RELOC_KVX_S43_TLS_IE_EX6
:
1689 case BFD_RELOC_KVX_S37_TLS_LD_LO10
:
1690 case BFD_RELOC_KVX_S37_TLS_LD_UP27
:
1692 case BFD_RELOC_KVX_S43_TLS_LD_LO10
:
1693 case BFD_RELOC_KVX_S43_TLS_LD_UP27
:
1694 case BFD_RELOC_KVX_S43_TLS_LD_EX6
:
1696 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
1703 /* If relocation has been marked for deletion, apply remaining changes */
1706 switch (fixP
->fx_r_type
)
1713 case BFD_RELOC_KVX_GLOB_DAT
:
1714 case BFD_RELOC_KVX_32_GOT
:
1715 case BFD_RELOC_KVX_64_GOT
:
1716 case BFD_RELOC_KVX_64_GOTOFF
:
1717 case BFD_RELOC_KVX_32_GOTOFF
:
1719 md_number_to_chars (fixpos
, image
, fixP
->fx_size
);
1722 case BFD_RELOC_KVX_PCREL17
:
1723 if (signed_overflow (value
, 17 + 2))
1724 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1725 _("branch out of range"));
1728 case BFD_RELOC_KVX_PCREL27
:
1729 if (signed_overflow (value
, 27 + 2))
1730 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1731 _("branch out of range"));
1734 case BFD_RELOC_KVX_S16_PCREL
:
1735 if (signed_overflow (value
, 16))
1736 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1737 _("signed16 PCREL value out of range"));
1740 case BFD_RELOC_KVX_S43_PCREL_LO10
:
1741 case BFD_RELOC_KVX_S43_PCREL_UP27
:
1742 case BFD_RELOC_KVX_S43_PCREL_EX6
:
1743 if (signed_overflow (value
, 10 + 27 + 6))
1744 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1745 _("signed43 PCREL value out of range"));
1748 case BFD_RELOC_KVX_S37_PCREL_LO10
:
1749 case BFD_RELOC_KVX_S37_PCREL_UP27
:
1750 if (signed_overflow (value
, 10 + 27))
1751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1752 _("signed37 PCREL value out of range"));
1755 case BFD_RELOC_KVX_S64_PCREL_LO10
:
1756 case BFD_RELOC_KVX_S64_PCREL_UP27
:
1757 case BFD_RELOC_KVX_S64_PCREL_EX27
:
1760 if (fixP
->fx_pcrel
|| fixP
->fx_addsy
)
1763 (((value
>> rel
->howto
->rightshift
) << rel
->howto
->bitpos
) & rel
->
1765 image
= (image
& ~(rel
->howto
->dst_mask
)) | value
;
1766 md_number_to_chars (fixpos
, image
, fixP
->fx_size
);
1769 case BFD_RELOC_KVX_S64_GOTADDR_LO10
:
1770 case BFD_RELOC_KVX_S64_GOTADDR_UP27
:
1771 case BFD_RELOC_KVX_S64_GOTADDR_EX27
:
1773 case BFD_RELOC_KVX_S43_GOTADDR_LO10
:
1774 case BFD_RELOC_KVX_S43_GOTADDR_UP27
:
1775 case BFD_RELOC_KVX_S43_GOTADDR_EX6
:
1777 case BFD_RELOC_KVX_S37_GOTADDR_LO10
:
1778 case BFD_RELOC_KVX_S37_GOTADDR_UP27
:
1782 case BFD_RELOC_KVX_S32_UP27
:
1784 case BFD_RELOC_KVX_S37_UP27
:
1786 case BFD_RELOC_KVX_S43_UP27
:
1788 case BFD_RELOC_KVX_S64_UP27
:
1789 case BFD_RELOC_KVX_S64_EX27
:
1790 case BFD_RELOC_KVX_S64_LO10
:
1792 case BFD_RELOC_KVX_S43_TLS_LE_UP27
:
1793 case BFD_RELOC_KVX_S43_TLS_LE_EX6
:
1795 case BFD_RELOC_KVX_S37_TLS_LE_UP27
:
1797 case BFD_RELOC_KVX_S37_GOTOFF_UP27
:
1799 case BFD_RELOC_KVX_S43_GOTOFF_UP27
:
1800 case BFD_RELOC_KVX_S43_GOTOFF_EX6
:
1802 case BFD_RELOC_KVX_S43_GOT_UP27
:
1803 case BFD_RELOC_KVX_S43_GOT_EX6
:
1805 case BFD_RELOC_KVX_S37_GOT_UP27
:
1807 case BFD_RELOC_KVX_S32_LO5
:
1808 case BFD_RELOC_KVX_S37_LO10
:
1810 case BFD_RELOC_KVX_S43_LO10
:
1811 case BFD_RELOC_KVX_S43_EX6
:
1813 case BFD_RELOC_KVX_S43_TLS_LE_LO10
:
1814 case BFD_RELOC_KVX_S37_TLS_LE_LO10
:
1816 case BFD_RELOC_KVX_S37_GOTOFF_LO10
:
1817 case BFD_RELOC_KVX_S43_GOTOFF_LO10
:
1819 case BFD_RELOC_KVX_S43_GOT_LO10
:
1820 case BFD_RELOC_KVX_S37_GOT_LO10
:
1823 as_fatal ("[md_apply_fix]:"
1824 "unsupported relocation type (type not handled : %d)",
1831 * Warning: Can be called only in fixup_segment() after fx_addsy field
1832 * has been updated by calling symbol_get_value_expression(...->X_add_symbol)
1835 kvx_validate_sub_fix (fixS
* fixP
)
1837 segT add_symbol_segment
, sub_symbol_segment
;
1839 switch (fixP
->fx_r_type
)
1844 if (fixP
->fx_addsy
!= NULL
)
1845 add_symbol_segment
= S_GET_SEGMENT (fixP
->fx_addsy
);
1848 if (fixP
->fx_subsy
!= NULL
)
1849 sub_symbol_segment
= S_GET_SEGMENT (fixP
->fx_subsy
);
1853 if ((strcmp (S_GET_NAME (fixP
->fx_addsy
),
1854 S_GET_NAME (fixP
->fx_subsy
)) == 0) &&
1855 (add_symbol_segment
== sub_symbol_segment
))
1865 /* This is called whenever some data item (not an instruction) needs a
1868 kvx_cons_fix_new (fragS
* f
, int where
, int nbytes
, expressionS
* exp
,
1869 bfd_reloc_code_real_type code
)
1871 if (exp
->X_op
== O_pseudo_fixup
)
1873 exp
->X_op
= O_symbol
;
1874 struct pseudo_func
*pf
=
1875 kvx_get_pseudo_func_data_scn (exp
->X_op_symbol
);
1876 assert (pf
!= NULL
);
1877 code
= pf
->pseudo_relocs
.single
;
1879 if (code
== BFD_RELOC_UNUSED
)
1880 as_fatal ("Unsupported relocation");
1890 code
= BFD_RELOC_16
;
1893 code
= BFD_RELOC_32
;
1896 code
= BFD_RELOC_64
;
1899 as_fatal ("unsupported BFD relocation size %u", nbytes
);
1903 fix_new_exp (f
, where
, nbytes
, exp
, 0, code
);
1907 * generate a relocation record
1911 tc_gen_reloc (asection
* sec ATTRIBUTE_UNUSED
, fixS
* fixp
)
1914 bfd_reloc_code_real_type code
;
1916 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1918 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1919 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1920 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1922 code
= fixp
->fx_r_type
;
1923 if (code
== BFD_RELOC_32
&& fixp
->fx_pcrel
)
1924 code
= BFD_RELOC_32_PCREL
;
1925 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1927 if (reloc
->howto
== NULL
)
1929 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1930 "cannot represent `%s' relocation in object file",
1931 bfd_get_reloc_code_name (code
));
1935 // if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1937 // as_fatal ("internal error? cannot generate `%s' relocation",
1938 // bfd_get_reloc_code_name (code));
1940 // assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1942 reloc
->addend
= fixp
->fx_offset
;
1945 * Ohhh, this is ugly. The problem is that if this is a local global
1946 * symbol, the relocation will entirely be performed at link time, not
1947 * at assembly time. bfd_perform_reloc doesn't know about this sort
1948 * of thing, and as a result we need to fake it out here.
1951 /* GD I'm not sure what this is used for in the kvx case but it sure */
1952 /* messes up the relocs when emit_all_relocs is used as they are not */
1953 /* resolved with respect to a global sysmbol (e.g. .text), and hence */
1954 /* they are ALWAYS resolved at link time */
1957 /* clarkes: 030827: This code (and the other half of the fix in write.c)
1958 * have caused problems with the PIC relocations.
1959 * The root problem is that bfd_install_relocation adds in to the reloc
1960 * addend the section offset of a symbol defined in the current object.
1961 * This causes problems on numerous other targets too, and there are
1962 * several different methods used to get around it:
1963 * 1. In tc_gen_reloc, subtract off the value that bfd_install_relocation
1964 * added. That is what we do here, and it is also done the
1965 * same way for alpha.
1966 * 2. In md_apply_fix, subtract off the value that bfd_install_relocation
1967 * will add. This is done on SH (non-ELF) and sparc targets.
1968 * 3. In the howto structure for the relocations, specify a
1969 * special function that does not return bfd_reloc_continue.
1970 * This causes bfd_install_relocaion to terminate before it
1971 * adds in the symbol offset. This is done on SH ELF targets.
1972 * Note that on ST200 we specify bfd_elf_generic_reloc as
1973 * the special function. This will return bfd_reloc_continue
1974 * only in some circumstances, but in particular if the reloc
1975 * is marked as partial_inplace in the bfd howto structure, then
1976 * bfd_elf_generic_reloc will return bfd_reloc_continue.
1977 * Some ST200 relocations are marked as partial_inplace
1978 * (this is an error in my opinion because ST200 always uses
1979 * a separate addend), but some are not. The PIC relocations
1980 * are not marked as partial_inplace, so for them,
1981 * bfd_elf_generic_reloc returns bfd_reloc_ok, and the addend
1982 * is not modified by bfd_install_relocation. The relocations
1983 * R_KVX_16 and R_KVX_32 are marked partial_inplace, and so for
1984 * these we need to correct the addend.
1985 * In the code below, the condition in the emit_all_relocs branch
1986 * (now moved to write.c) is the inverse of the condition that
1987 * bfd_elf_generic_reloc uses to short-circuit the code in
1988 * bfd_install_relocation that modifies the addend. The condition
1989 * in the else branch match the condition used in the alpha version
1990 * of tc_gen_reloc (see tc-alpha.c).
1991 * I do not know why we need to use different conditions in these
1992 * two branches, it seems to me that the condition should be the same
1993 * whether or not emit_all_relocs is true.
1994 * I also do not understand why it was necessary to move the emit_all_relocs
1995 * condition to write.c.
1998 if (S_IS_EXTERNAL (fixp
->fx_addsy
) &&
1999 !S_IS_COMMON (fixp
->fx_addsy
) && reloc
->howto
->partial_inplace
)
2000 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
2005 /* Round up segment to appropriate boundary */
2008 md_section_align (asection
* seg ATTRIBUTE_UNUSED
, valueT size
)
2011 /* This is not right for ELF; a.out wants it, and COFF will force
2012 * the alignment anyways. */
2013 int align
= bfd_get_section_alignment (stdoutput
, seg
);
2014 valueT mask
= ((valueT
) 1 << align
) - 1;
2015 return (size
+ mask
) & ~mask
;
2022 md_estimate_size_before_relax (register fragS
* fragP ATTRIBUTE_UNUSED
,
2023 segT segtype ATTRIBUTE_UNUSED
)
2025 as_fatal ("estimate_size_before_relax called");
2029 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
2030 asection
* sec ATTRIBUTE_UNUSED
,
2031 fragS
* fragp ATTRIBUTE_UNUSED
)
2033 as_fatal ("kvx convert_frag");
2037 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
2043 md_atof (int type ATTRIBUTE_UNUSED
,
2044 char *litp ATTRIBUTE_UNUSED
, int *sizep ATTRIBUTE_UNUSED
)
2046 return ieee_md_atof (type
, litp
, sizep
, TARGET_BYTES_BIG_ENDIAN
);
2050 * calculate the base for a pcrel fixup
2051 * -- for relocation, we might need to add addend ?
2055 md_pcrel_from (fixS
* fixP
)
2057 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
);
2060 /************************************************************/
2061 /* Hooks into standard processing -- we hook into label */
2062 /* handling code to detect double ':' and we hook before */
2063 /* a line of code is processed to do some simple sed style */
2065 /************************************************************/
2067 static symbolS
*last_proc_sym
= NULL
;
2068 static int update_last_proc_sym
= 0;
2071 kvx_frob_label (symbolS
*sym
)
2073 if (update_last_proc_sym
)
2075 last_proc_sym
= sym
;
2076 update_last_proc_sym
= 0;
2081 struct label_fix
*fix
;
2082 fix
= malloc (sizeof (*fix
));
2083 fix
->next
= label_fixes
;
2088 dwarf2_emit_label (sym
);
2092 kvx_check_label (symbolS
*sym
)
2094 /* Labels followed by a second semi-colon are considered external symbols. */
2095 if (*input_line_pointer
== ':')
2097 S_SET_EXTERNAL (sym
);
2098 input_line_pointer
++;
2102 /* Emit single bundle nop. This is needed by .nop asm directive
2103 * Have to manage end of bundle done usually by start_line_hook
2104 * using BE pseudo op
2107 kvx_emit_single_noop (void)
2110 char *end_of_bundle
;
2112 if (asprintf (&nop
, "nop") < 0)
2113 as_fatal ("%s", xstrerror (errno
));
2115 if (asprintf (&end_of_bundle
, "be") < 0)
2116 as_fatal ("%s", xstrerror (errno
));
2118 char *saved_ilp
= input_line_pointer
;
2120 md_assemble (end_of_bundle
);
2121 input_line_pointer
= saved_ilp
;
2123 free (end_of_bundle
);
2126 /* edit out some syntactic sugar that confuses GAS */
2127 /* input_line_pointer is guaranteed to point to the */
2128 /* the current line but may include text from following */
2129 /* lines. Thus, '\n' must be scanned for as well as '\0' */
2132 kvx_md_start_line_hook (void)
2136 for (t
= input_line_pointer
; t
&& t
[0] == ' '; t
++);
2138 /* Detect illegal syntax patterns:
2139 * - two bundle ends on the same line: ;; ;;
2140 * - illegal token: ;;;
2142 if (t
&& (t
[0] == ';') && (t
[1] == ';'))
2145 bool newline_seen
= false;
2148 as_fatal ("Syntax error: Illegal ;;; token");
2152 while (tmp_t
&& tmp_t
[0])
2154 while (tmp_t
&& tmp_t
[0] &&
2155 ((tmp_t
[0] == ' ') || (tmp_t
[0] == '\n')))
2157 if (tmp_t
[0] == '\n')
2158 newline_seen
= true;
2161 if (tmp_t
[0] == ';' && tmp_t
[1] == ';')
2163 /* if there's no newline between the two bundle stops
2164 * then raise a syntax error now, otherwise a strange error
2165 * message from read.c will be raised: "junk at end of line..."
2167 if (tmp_t
[2] == ';')
2168 as_fatal ("Syntax error: Illegal ;;; token");
2171 as_fatal ("Syntax error: More than one bundle stop on a line");
2172 newline_seen
= false; /* reset */
2174 /* this is an empty bundle, transform it into an
2175 * empty statement */
2186 /* check for bundle end */
2187 /* we transform these into a special opcode BE */
2188 /* because gas has ';' hardwired as a statement end */
2189 if (t
&& (t
[0] == ';') && (t
[1] == ';'))
2198 kvx_check_resources (int f
)
2200 env
.opts
.check_resource_usage
= f
;
2203 /** called before write_object_file */
2209 if (!env
.params
.core_set
)
2210 env
.params
.core
= kvx_core_info
->elf_core
;
2212 /* (pp) the flags must be set at once */
2213 newflags
= env
.params
.core
| env
.params
.abi
| env
.params
.pic_flags
;
2215 if (env
.params
.arch_size
== 64)
2216 newflags
|= ELF_KVX_ABI_64B_ADDR_BIT
;
2218 bfd_set_private_flags (stdoutput
, newflags
);
2222 if (inside_bundle
&& insncnt
!= 0)
2223 as_bad ("unexpected end-of-file while processing a bundle."
2224 " Please check that ;; is on its own line.");
2228 kvx_type (int start ATTRIBUTE_UNUSED
)
2233 char *typename
= NULL
;
2235 elf_symbol_type
*elfsym
;
2237 c
= get_symbol_name (&name
);
2238 sym
= symbol_find_or_make (name
);
2239 elfsym
= (elf_symbol_type
*) symbol_get_bfdsym (sym
);
2240 *input_line_pointer
= c
;
2242 if (!*S_GET_NAME (sym
))
2243 as_bad (_("Missing symbol name in directive"));
2246 if (*input_line_pointer
== ',')
2247 ++input_line_pointer
;
2251 if (*input_line_pointer
== '#'
2252 || *input_line_pointer
== '@'
2253 || *input_line_pointer
== '"' || *input_line_pointer
== '%')
2254 ++input_line_pointer
;
2256 /* typename = input_line_pointer; */
2257 /* c = get_symbol_end(); */
2258 c
= get_symbol_name (&typename
);
2261 if (strcmp (typename
, "function") == 0
2262 || strcmp (typename
, "STT_FUNC") == 0)
2263 type
= BSF_FUNCTION
;
2264 else if (strcmp (typename
, "object") == 0
2265 || strcmp (typename
, "STT_OBJECT") == 0)
2267 else if (strcmp (typename
, "tls_object") == 0
2268 || strcmp (typename
, "STT_TLS") == 0)
2269 type
= BSF_OBJECT
| BSF_THREAD_LOCAL
;
2270 else if (strcmp (typename
, "common") == 0
2271 || strcmp (typename
, "STT_COMMON") == 0)
2272 type
= BSF_ELF_COMMON
;
2273 else if (strcmp (typename
, "gnu_unique_object") == 0
2274 || strcmp (typename
, "STB_GNU_UNIQUE") == 0)
2276 elf_tdata (stdoutput
)->has_gnu_osabi
|= elf_gnu_osabi_unique
;
2277 type
= BSF_OBJECT
| BSF_GNU_UNIQUE
;
2279 else if (strcmp (typename
, "notype") == 0
2280 || strcmp (typename
, "STT_NOTYPE") == 0)
2282 #ifdef md_elf_symbol_type
2283 else if ((type
= md_elf_symbol_type (typename
, sym
, elfsym
)) != -1)
2287 as_bad (_("unrecognized symbol type \"%s\""), typename
);
2289 *input_line_pointer
= c
;
2291 if (*input_line_pointer
== '"')
2292 ++input_line_pointer
;
2294 elfsym
->symbol
.flags
|= type
;
2295 symbol_get_bfdsym (sym
)->flags
|= type
;
2297 demand_empty_rest_of_line ();
2300 #define ENDPROCEXTENSION "$endproc"
2301 #define MINUSEXPR ".-"
2303 static int proc_endp_status
= 0;
2306 kvx_endp (int start ATTRIBUTE_UNUSED
)
2312 as_warn (".endp directive inside a bundle.");
2313 /* function name is optionnal and is ignored */
2314 /* there may be several names separated by commas... */
2318 c
= get_symbol_name (&name
);
2319 (void) restore_line_pointer (c
);
2321 if (*input_line_pointer
!= ',')
2323 ++input_line_pointer
;
2325 demand_empty_rest_of_line ();
2327 if (!proc_endp_status
)
2329 as_warn (".endp directive doesn't follow .proc -- ignoring ");
2333 proc_endp_status
= 0;
2335 /* TB begin : add BSF_FUNCTION attribute to last_proc_sym symbol */
2336 if (size_type_function
)
2340 as_bad ("Cannot set function attributes (bad symbol)");
2344 /* last_proc_sym->symbol.flags |= BSF_FUNCTION; */
2345 symbol_get_bfdsym (last_proc_sym
)->flags
|= BSF_FUNCTION
;
2346 /* Add .size funcname,.-funcname in order to add size
2347 * attribute to the current function */
2349 const int newdirective_sz
=
2350 strlen (S_GET_NAME (last_proc_sym
)) + strlen (MINUSEXPR
) + 1;
2351 char *newdirective
= malloc (newdirective_sz
);
2352 char *savep
= input_line_pointer
;
2355 memset (newdirective
, 0, newdirective_sz
);
2357 /* BUILD :".-funcname" expression */
2358 strcat (newdirective
, MINUSEXPR
);
2359 strcat (newdirective
, S_GET_NAME (last_proc_sym
));
2360 input_line_pointer
= newdirective
;
2363 if (exp
.X_op
== O_constant
)
2365 S_SET_SIZE (last_proc_sym
, exp
.X_add_number
);
2366 if (symbol_get_obj (last_proc_sym
)->size
)
2368 xfree (symbol_get_obj (last_proc_sym
)->size
);
2369 symbol_get_obj (last_proc_sym
)->size
= NULL
;
2374 symbol_get_obj (last_proc_sym
)->size
=
2375 (expressionS
*) xmalloc (sizeof (expressionS
));
2376 *symbol_get_obj (last_proc_sym
)->size
= exp
;
2379 /* just restore the real input pointer */
2380 input_line_pointer
= savep
;
2381 free (newdirective
);
2386 last_proc_sym
= NULL
;
2390 kvx_proc (int start ATTRIBUTE_UNUSED
)
2394 /* there may be several names separated by commas... */
2398 c
= get_symbol_name (&name
);
2399 (void) restore_line_pointer (c
);
2402 if (*input_line_pointer
!= ',')
2404 ++input_line_pointer
;
2406 demand_empty_rest_of_line ();
2408 if (proc_endp_status
)
2410 as_warn (".proc follows .proc -- ignoring");
2414 proc_endp_status
= 1;
2416 /* this code emit a global symbol to mark the end of each function */
2417 /* the symbol emitted has a name formed by the original function name */
2418 /* concatenated with $endproc so if _foo is a function name the symbol */
2419 /* marking the end of it is _foo$endproc */
2420 /* It is also required for generation of .size directive in kvx_endp() */
2422 if (size_type_function
)
2423 update_last_proc_sym
= 1;
2427 kvx_force_reloc (fixS
* fixP
)
2432 if (generic_force_reloc (fixP
))
2435 switch (fixP
->fx_r_type
)
2437 case BFD_RELOC_KVX_32_GOTOFF
:
2438 case BFD_RELOC_KVX_S37_GOTOFF_UP27
:
2439 case BFD_RELOC_KVX_S37_GOTOFF_LO10
:
2441 case BFD_RELOC_KVX_64_GOTOFF
:
2442 case BFD_RELOC_KVX_S43_GOTOFF_UP27
:
2443 case BFD_RELOC_KVX_S43_GOTOFF_LO10
:
2444 case BFD_RELOC_KVX_S43_GOTOFF_EX6
:
2446 case BFD_RELOC_KVX_32_GOT
:
2447 case BFD_RELOC_KVX_64_GOT
:
2448 case BFD_RELOC_KVX_S37_GOT_UP27
:
2449 case BFD_RELOC_KVX_S37_GOT_LO10
:
2451 case BFD_RELOC_KVX_GLOB_DAT
:
2457 sym
= fixP
->fx_addsy
;
2460 symsec
= S_GET_SEGMENT (sym
);
2461 /* if (bfd_is_abs_section (symsec)) return 0; */
2462 if (!SEG_NORMAL (symsec
))
2469 kvx_force_reloc_sub_same (fixS
* fixP
, segT sec
)
2473 const char *sec_name
= NULL
;
2475 if (generic_force_reloc (fixP
))
2478 switch (fixP
->fx_r_type
)
2480 case BFD_RELOC_KVX_32_GOTOFF
:
2481 case BFD_RELOC_KVX_S37_GOTOFF_UP27
:
2482 case BFD_RELOC_KVX_S37_GOTOFF_LO10
:
2484 case BFD_RELOC_KVX_64_GOTOFF
:
2485 case BFD_RELOC_KVX_S43_GOTOFF_UP27
:
2486 case BFD_RELOC_KVX_S43_GOTOFF_LO10
:
2487 case BFD_RELOC_KVX_S43_GOTOFF_EX6
:
2489 case BFD_RELOC_KVX_32_GOT
:
2490 case BFD_RELOC_KVX_64_GOT
:
2491 case BFD_RELOC_KVX_S37_GOT_UP27
:
2492 case BFD_RELOC_KVX_S37_GOT_LO10
:
2494 case BFD_RELOC_KVX_S37_LO10
:
2495 case BFD_RELOC_KVX_S37_UP27
:
2497 case BFD_RELOC_KVX_GLOB_DAT
:
2504 sym
= fixP
->fx_addsy
;
2507 symsec
= S_GET_SEGMENT (sym
);
2508 /* if (bfd_is_abs_section (symsec)) return 0; */
2509 if (!SEG_NORMAL (symsec
))
2513 * for .debug_arrange, .debug_frame, .eh_frame sections, containing
2514 * expressions of the form "sym2 - sym1 + addend", solve them even when
2515 * --emit-all-relocs is set. Otherwise, a relocation on two symbols
2516 * is necessary and fails at elf level. Binopt should not be impacted by
2517 * the resolution of this relocatable expression on symbols inside a
2520 sec_name
= segment_name (sec
);
2521 if ((strcmp (sec_name
, ".eh_frame") == 0) ||
2522 (strcmp (sec_name
, ".except_table") == 0) ||
2523 (strncmp (sec_name
, ".debug_", sizeof (".debug_")) == 0))
2529 /* Implement HANDLE_ALIGN. */
2532 kvx_make_nops (char *buf
, bfd_vma bytes
)
2537 static unsigned int nop_single
= 0;
2541 const struct kvxopc
*opcode
=
2542 (struct kvxopc
*) str_hash_find (env
.opcode_hash
, "nop");
2546 ("internal error: could not find opcode for 'nop' during padding");
2548 nop_single
= opcode
->codewords
[0].opcode
;
2551 /* KVX instructions are always 4-bytes aligned. If we are at a position */
2552 /* that is not 4 bytes aligned, it means this is not part of an instruction, */
2553 /* so it is safe to use a zero byte for padding. */
2555 for (j
= bytes
% 4; j
> 0; j
--)
2558 for (j
= 0; j
< (bytes
- i
); j
+= 4)
2560 unsigned nop
= nop_single
;
2562 // nop has bundle end only if #4 nop or last padding nop.
2563 // Sets the parallel bit when neither conditions are matched.
2564 // 4*4 = biggest nop bundle we can get
2565 // 12 = offset when writting the last nop possible in a 4 nops bundle
2566 // bytes-i-4 = offset for the last 4-words in the padding
2567 if (j
% (4 * 4) != 12 && j
!= (bytes
- i
- 4))
2568 nop
|= PARALLEL_BIT
;
2570 memcpy (buf
+ i
+ j
, &nop
, sizeof (nop
));
2574 /* Pads code section with bundle of nops when possible, 0 if not. */
2576 kvx_handle_align (fragS
*fragP
)
2578 switch (fragP
->fr_type
)
2582 bfd_signed_vma bytes
= (fragP
->fr_next
->fr_address
2583 - fragP
->fr_address
- fragP
->fr_fix
);
2584 char *p
= fragP
->fr_literal
+ fragP
->fr_fix
;
2589 /* Insert zeros or nops to get 4 byte alignment. */
2590 kvx_make_nops (p
, bytes
);
2591 fragP
->fr_fix
+= bytes
;
2600 * This is just used for debugging
2605 print_operand (expressionS
* e
, FILE * out
)
2612 fprintf (out
, "%s", kvx_registers
[e
->X_add_number
].name
);
2616 if (e
->X_add_symbol
)
2618 if (e
->X_add_number
)
2619 fprintf (out
, "(%s + %d)", S_GET_NAME (e
->X_add_symbol
),
2620 (int) e
->X_add_number
);
2622 fprintf (out
, "%s", S_GET_NAME (e
->X_add_symbol
));
2625 fprintf (out
, "%d", (int) e
->X_add_number
);
2629 if (e
->X_add_symbol
)
2631 if (e
->X_add_number
)
2632 fprintf (out
, "(%s + %d)", S_GET_NAME (e
->X_add_symbol
),
2633 (int) e
->X_add_number
);
2635 fprintf (out
, "%s", S_GET_NAME (e
->X_add_symbol
));
2638 fprintf (out
, "%d", (int) e
->X_add_number
);
2642 fprintf (out
, "o,ptype-%d", e
->X_op
);
2648 kvx_cfi_frame_initial_instructions (void)
2650 cfi_add_CFA_def_cfa (KVX_SP_REGNO
, 0);
2654 kvx_regname_to_dw2regnum (const char *regname
)
2656 unsigned int regnum
= -1;
2660 if (regname
[0] == 'r')
2663 regnum
= strtoul (p
, &q
, 10);
2664 if (p
== q
|| *q
|| regnum
>= 64)