1/* tc-kvx.h -- Header file for tc-kvx.c
2
3   Copyright (C) 2009-2024 Free Software Foundation, Inc.
4   Contributed by Kalray SA.
5
6   This file is part of GAS.
7
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.
12
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.
17
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/>.  */
21
22#ifndef TC_KVX
23#define TC_KVX
24
25#include "as.h"
26#include "include/hashtab.h"
27#include "opcode/kvx.h"
28
29#ifdef OBJ_ELF
30#include "elf/kvx.h"
31#endif
32
33#include <stdlib.h>
34
35#define TARGET_ARCH bfd_arch_kvx
36
37#define KVX_RA_REGNO (67)
38#define KVX_SP_REGNO (12)
39
40#define O_pseudo_fixup O_md1
41
42#define TOKEN_NAME(tok) \
43  ((tok) <= 0 ? "unknown token" : env.tokens_names[(tok) - 1])
44
45struct token_s {
46  char *insn;
47  int begin, end;
48  int category;
49  int64_t class_id;
50  uint64_t val;
51};
52
53struct token_list
54{
55  char *tok;
56  uint64_t val;
57  int64_t class_id;
58  int category;
59  int loc;
60  struct token_list *next;
61  int len;
62};
63
64
65struct token_class {
66  const char ** class_values;
67  int64_t class_id;
68  int sz;
69};
70
71enum token_category {
72  CAT_INSTRUCTION,
73  CAT_MODIFIER,
74  CAT_IMMEDIATE,
75  CAT_SEPARATOR,
76  CAT_REGISTER,
77  CAT_INVALID
78};
79
80struct token_classes {
81  struct token_class *reg_classes;
82  struct token_class *mod_classes;
83  struct token_class *imm_classes;
84  struct token_class *insn_classes;
85  struct token_class *sep_classes;
86};
87
88struct steering_rule {
89  int steering;
90  int jump_target;
91  int stack_it;
92};
93
94struct rule {
95  struct steering_rule *rules;
96};
97
98/* Default kvx_registers array. */
99extern const struct kvx_Register *kvx_registers;
100/* Default kvx_modifiers array. */
101extern const char ***kvx_modifiers;
102/* Default kvx_regfiles array. */
103extern const int *kvx_regfiles;
104/* Default values used if no assume directive is given */
105extern const struct kvx_core_info *kvx_core_info;
106
107struct kvx_as_options {
108  /* Arch string passed as argument with -march option.  */
109  char *march;
110  /* Resource usage checking.  */
111  int check_resource_usage;
112  /* Generate illegal code: only use for debugging !*/
113  int generate_illegal_code;
114  /* Dump asm tables: for debugging */
115  int dump_table;
116  /* Dump instructions: for documentation */
117  int dump_insn;
118  /* Enable multiline diagnostics */
119  int diagnostics;
120  /* Enable more helpful error messages */
121  int more;
122  /* Used for HW validation: allows all SFR in GET/SET/WFX */
123  int allow_all_sfr;
124};
125
126extern struct kvx_as_options kvx_options;
127
128struct kvx_as_params {
129  /* The target's ABI */
130  int abi;
131  /* The target's OS/ABI */
132  int osabi;
133  /* The target core (0: KV3-1, 1: KV3-2, 2: KV4-1) */
134  int core;
135  /* Guard to check if KVX_CORE has been set */
136  int core_set;
137  /* Guard to check if KVX_ABI has been set */
138  int abi_set;
139  /* Guard to check if KVX_OSABI has been set */
140  int osabi_set;
141  /* Flags controlling Position-Independent Code.  */
142  flagword pic_flags;
143  /* Either 32 or 64.  */
144  int arch_size;
145};
146
147extern struct kvx_as_params kvx_params;
148
149struct kvx_as_env {
150  const char ** tokens_names;
151  int fst_reg, sys_reg, fst_mod;
152  int (*promote_immediate) (int);
153  struct rule *rules;
154  struct token_classes *token_classes;
155  struct node_s *insns;
156  /* Records enabled options.  */
157  struct kvx_as_options opts;
158  /* Record the parameters of the target architecture.  */
159  struct kvx_as_params params;
160  /* The hash table of instruction opcodes.  */
161  htab_t opcode_hash;
162  /* The hash table of register symbols.  */
163  htab_t reg_hash;
164  /* The hash table of relocations for immediates.  */
165  htab_t reloc_hash;
166};
167
168extern struct kvx_as_env env;
169
170struct token_list* parse (struct token_s tok);
171void print_token_list (struct token_list *lst);
172void free_token_list (struct token_list* tok_list);
173void setup (int version);
174void cleanup (void);
175
176
177/* Hooks configuration.  */
178
179extern const char * kvx_target_format (void);
180#undef TARGET_FORMAT
181#define TARGET_FORMAT kvx_target_format ()
182
183/* default little endian */
184#define TARGET_BYTES_BIG_ENDIAN 0
185#define md_number_to_chars number_to_chars_littleendian
186
187/* for now we have no BFD target */
188
189/* lexing macros */
190/* Allow `$' in names.  */
191#define LEX_DOLLAR (LEX_BEGIN_NAME | LEX_NAME)
192/* Disable legacy `broken words' processing.  */
193#define WORKING_DOT_WORD
194
195extern void kvx_end (void);
196#undef md_finish
197#define md_finish kvx_end
198
199#define TC_FIX_TYPE struct _symbol_struct *
200#define TC_SYMFILED_TYPE struct list_info_struct *
201#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = NULL)
202#define REPEAT_CONS_EXPRESSIONS
203
204#define tc_frob_label(sym) kvx_frob_label(sym)
205#define tc_check_label(sym) kvx_check_label(sym)
206extern void kvx_frob_label (struct symbol *);
207extern void kvx_check_label (struct symbol *);
208
209
210/* GAS listings (enabled by `-a') */
211
212#define LISTING_HEADER "KVX GAS LISTING"
213#define LISTING_LHS_CONT_LINES 100
214
215
216#define md_start_line_hook kvx_md_start_line_hook
217extern void kvx_md_start_line_hook (void);
218#define md_emit_single_noop kvx_emit_single_noop()
219extern void kvx_emit_single_noop (void);
220
221/* Values passed to md_apply_fix don't include the symbol value.  */
222#define MD_APPLY_SYM_VALUE(FIX) 0
223
224/* Allow O_subtract in expressionS.  */
225#define DIFF_EXPR_OK 1
226
227/* Controls the emission of relocations even when the symbol may be resolved
228   directly by the assembler.  */
229extern int kvx_force_reloc (struct fix *);
230#undef TC_FORCE_RELOCATION
231#define TC_FORCE_RELOCATION(fixP) kvx_force_reloc(fixP)
232
233/* Force a relocation for global symbols.  */
234#define EXTERN_FORCE_RELOC 1
235
236/* Controls the resolution of fixup expressions involving the difference of two
237   symbols.  */
238extern int kvx_force_reloc_sub_same (struct fix *, segT);
239#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC)                                 \
240  (! SEG_NORMAL (S_GET_SEGMENT((FIX)->fx_addsy))                               \
241   || kvx_force_reloc_sub_same(FIX, SEC))
242
243/* This expression evaluates to true if the relocation is for a local object
244   for which we still want to do the relocation at runtime.  False if we are
245   willing to perform this relocation while building the .o file.
246
247   We can't resolve references to the GOT or the PLT when creating the object
248   file, since these tables are only created by the linker.  Also, if the symbol
249   is global, weak, common or not defined, the assembler can't compute the
250   appropriate reloc, since its location can only be determined at link time.
251   */
252
253#define TC_FORCE_RELOCATION_LOCAL(FIX) \
254  (!(FIX)->fx_pcrel || TC_FORCE_RELOCATION (FIX))
255
256/* This expression evaluates to false if the relocation is for a local object
257   for which we still want to do the relocation at runtime.  True if we are
258   willing to perform this relocation while building the .o file. This is only
259   used for pcrel relocations. Use this to ensure that a branch to a preemptible
260   symbol is not resolved by the assembler. */
261
262#define TC_RELOC_RTSYM_LOC_FIXUP(FIX)                                          \
263  ((FIX)->fx_r_type != BFD_RELOC_KVX_23_PCREL                                  \
264   || (FIX)->fx_addsy == NULL                                                  \
265   || (! S_IS_EXTERNAL ((FIX)->fx_addsy)                                       \
266       && ! S_IS_WEAK ((FIX)->fx_addsy)                                        \
267       && S_IS_DEFINED ((FIX)->fx_addsy)                                       \
268       && ! S_IS_COMMON ((FIX)->fx_addsy)))
269
270/* Local symbols will be adjusted against the section symbol.  */
271#define tc_fix_adjustable(fixP) 1
272
273/* This arranges for gas/write.c to not apply a relocation if
274   tc_fix_adjustable says it is not adjustable.  The "! symbol_used_in_reloc_p"
275   test is there specifically to cover the case of non-global symbols in
276   linkonce sections.  It's the generally correct thing to do though;  If a
277   reloc is going to be emitted against a symbol then we don't want to adjust
278   the fixup by applying the reloc during assembly.  The reloc will be applied
279   by the linker during final link.  */
280#define TC_FIX_ADJUSTABLE(fixP) \
281  (! symbol_used_in_reloc_p ((fixP)->fx_addsy) && tc_fix_adjustable (fixP))
282
283/* Force this to avoid -g to fail because of dwarf2 expression .L0 - .L0 */
284extern int kvx_validate_sub_fix (struct fix *fix);
285#define TC_VALIDATE_FIX_SUB(FIX, SEG)                                          \
286  (((FIX)->fx_r_type == BFD_RELOC_32 || (FIX)->fx_r_type == BFD_RELOC_16)      \
287   && kvx_validate_sub_fix((FIX)))
288
289/* Generate a fix for a data allocation pseudo-op*/
290#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP,RELOC) kvx_cons_fix_new(FRAG,OFF,LEN,EXP,RELOC)
291extern void kvx_cons_fix_new (fragS *f, int where, int nbytes,
292			      expressionS *exp, bfd_reloc_code_real_type);
293
294/* No post-alignment of sections */
295#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
296
297/* Enable special handling for the alignment directive.  */
298extern void kvx_handle_align (fragS *);
299#undef HANDLE_ALIGN
300#define HANDLE_ALIGN kvx_handle_align
301
302#ifdef OBJ_ELF
303
304/* Enable CFI support.  */
305#define TARGET_USE_CFIPOP 1
306
307extern void kvx_cfi_frame_initial_instructions (void);
308#undef tc_cfi_frame_initial_instructions
309#define tc_cfi_frame_initial_instructions kvx_cfi_frame_initial_instructions
310
311extern int kvx_regname_to_dw2regnum (const char *regname);
312#undef tc_regname_to_dw2regnum
313#define tc_regname_to_dw2regnum kvx_regname_to_dw2regnum
314
315/* All KVX instructions are multiples of 32 bits.  */
316#define DWARF2_LINE_MIN_INSN_LENGTH 1
317#define DWARF2_DEFAULT_RETURN_COLUMN (KVX_RA_REGNO)
318#define DWARF2_CIE_DATA_ALIGNMENT -4
319#endif
320#endif
321