gdb/testsuite/gdb.base/stap-probe: Minor clean-up
[deliverable/binutils-gdb.git] / gas / config / tc-xc16x.c
CommitLineData
d70c5fc7 1/* tc-xc16x.c -- Assembler for the Infineon XC16X.
b3adc24a 2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
3739860c 3 Contributed by KPIT Cummins Infosystems
d70c5fc7
NC
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
ec2655a6 9 the Free Software Foundation; either version 3, or (at your option)
d70c5fc7
NC
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22
d70c5fc7
NC
23#include "as.h"
24#include "safe-ctype.h"
25#include "subsegs.h"
26#include "symcat.h"
27#include "opcodes/xc16x-desc.h"
28#include "opcodes/xc16x-opc.h"
29#include "cgen.h"
d70c5fc7
NC
30#include "dwarf2dbg.h"
31
32
33#ifdef OBJ_ELF
34#include "elf/xc16x.h"
35#endif
36
37/* Structure to hold all of the different components describing
38 an individual instruction. */
39typedef struct
40{
41 const CGEN_INSN * insn;
42 const CGEN_INSN * orig_insn;
43 CGEN_FIELDS fields;
44#if CGEN_INT_INSN_P
45 CGEN_INSN_INT buffer [1];
46#define INSN_VALUE(buf) (*(buf))
47#else
48 unsigned char buffer [CGEN_MAX_INSN_SIZE];
49#define INSN_VALUE(buf) (buf)
50#endif
51 char * addr;
52 fragS * frag;
53 int num_fixups;
54 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
55 int indices [MAX_OPERAND_INSTANCES];
56}
57xc16x_insn;
58
59const char comment_chars[] = ";";
60const char line_comment_chars[] = "#";
61const char line_separator_chars[] = "";
62const char EXP_CHARS[] = "eE";
63const char FLT_CHARS[] = "dD";
64
65#define XC16X_SHORTOPTS ""
66const char * md_shortopts = XC16X_SHORTOPTS;
67
68struct option md_longopts[] =
69{
70 {NULL, no_argument, NULL, 0}
71};
72size_t md_longopts_size = sizeof (md_longopts);
73
74static void
75xc16xlmode (int arg ATTRIBUTE_UNUSED)
76{
77 if (stdoutput != NULL)
78 if (!bfd_set_arch_mach (stdoutput, bfd_arch_xc16x, bfd_mach_xc16xl))
79 as_warn (_("could not set architecture and machine"));
80}
81
82static void
83xc16xsmode (int arg ATTRIBUTE_UNUSED)
84{
85 if (!bfd_set_arch_mach (stdoutput, bfd_arch_xc16x, bfd_mach_xc16xs))
86 as_warn (_("could not set architecture and machine"));
87}
88
89static void
90xc16xmode (int arg ATTRIBUTE_UNUSED)
91{
92 if (!bfd_set_arch_mach (stdoutput, bfd_arch_xc16x, bfd_mach_xc16x))
93 as_warn (_("could not set architecture and machine"));
94}
95
96/* The target specific pseudo-ops which we support. */
97const pseudo_typeS md_pseudo_table[] =
98{
99 { "word", cons, 2 },
100 {"xc16xl", xc16xlmode, 0},
101 {"xc16xs", xc16xsmode, 0},
102 {"xc16x", xc16xmode, 0},
103 { NULL, NULL, 0 }
104};
105
106void
107md_begin (void)
108{
109 /* Initialize the `cgen' interface. */
110
111 /* Set the machine number and endian. */
112 gas_cgen_cpu_desc = xc16x_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
113 CGEN_CPU_OPEN_ENDIAN,
114 CGEN_ENDIAN_LITTLE,
115 CGEN_CPU_OPEN_END);
116 xc16x_cgen_init_asm (gas_cgen_cpu_desc);
117
118 /* This is a callback from cgen to gas to parse operands. */
119 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
120}
121
122void
123md_assemble (char *str)
124{
125 xc16x_insn insn;
126 char *errmsg;
127
128 /* Initialize GAS's cgen interface for a new instruction. */
129 gas_cgen_init_parse ();
130
131 insn.insn = xc16x_cgen_assemble_insn
132 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
133
134 if (!insn.insn)
135 {
20203fb9 136 as_bad ("%s", errmsg);
d70c5fc7
NC
137 return;
138 }
139
140 /* Doesn't really matter what we pass for RELAX_P here. */
141 gas_cgen_finish_insn (insn.insn, insn.buffer,
142 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
143}
144
145/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
146 Returns BFD_RELOC_NONE if no reloc type can be found.
147 *FIXP may be modified if desired. */
148
149bfd_reloc_code_real_type
150md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
151 const CGEN_OPERAND *operand,
152 fixS *fixP)
153{
154 switch (operand->type)
155 {
156 case XC16X_OPERAND_REL:
23f5dfcb 157 /* ??? Adjust size? */
d70c5fc7
NC
158 fixP->fx_where += 1;
159 fixP->fx_pcrel = 1;
160 return BFD_RELOC_8_PCREL;
161
162 case XC16X_OPERAND_CADDR:
23f5dfcb 163 fixP->fx_size = 2;
d70c5fc7
NC
164 fixP->fx_where += 2;
165 return BFD_RELOC_16;
166
167 case XC16X_OPERAND_UIMM7:
23f5dfcb 168 /* ??? Adjust size? */
d70c5fc7
NC
169 fixP->fx_where += 1;
170 fixP->fx_pcrel = 1;
171 return BFD_RELOC_8_PCREL;
172
173 case XC16X_OPERAND_UIMM16:
174 case XC16X_OPERAND_MEMORY:
23f5dfcb 175 fixP->fx_size = 2;
d70c5fc7
NC
176 fixP->fx_where += 2;
177 return BFD_RELOC_16;
178
179 case XC16X_OPERAND_UPOF16:
23f5dfcb 180 fixP->fx_size = 2;
d70c5fc7
NC
181 fixP->fx_where += 2;
182 return BFD_RELOC_XC16X_POF;
183
184 case XC16X_OPERAND_UPAG16:
23f5dfcb 185 fixP->fx_size = 2;
d70c5fc7
NC
186 fixP->fx_where += 2;
187 return BFD_RELOC_XC16X_PAG;
188
189 case XC16X_OPERAND_USEG8:
23f5dfcb 190 /* ??? This is an 8 bit field, why the 16 bit reloc? */
d70c5fc7
NC
191 fixP->fx_where += 1;
192 return BFD_RELOC_XC16X_SEG;
193
194 case XC16X_OPERAND_USEG16:
195 case XC16X_OPERAND_USOF16:
23f5dfcb 196 fixP->fx_size = 2;
d70c5fc7
NC
197 fixP->fx_where += 2;
198 return BFD_RELOC_XC16X_SOF;
199
662a2e45 200 default : /* Avoid -Wall warning. */
d70c5fc7
NC
201 break;
202 }
203
23f5dfcb 204 return BFD_RELOC_NONE;
d70c5fc7
NC
205}
206
207/* Write a value out to the object file, using the appropriate endianness. */
208
209void
210md_number_to_chars (char * buf, valueT val, int n)
211{
212 number_to_chars_littleendian (buf, val, n);
213}
214
215void
216md_show_usage (FILE * stream)
217{
218 fprintf (stream, _(" XC16X specific command line options:\n"));
219}
220
221int
222md_parse_option (int c ATTRIBUTE_UNUSED,
17b9d67d 223 const char *arg ATTRIBUTE_UNUSED)
d70c5fc7
NC
224{
225 return 0;
226}
227
6d4af3c2 228const char *
d70c5fc7
NC
229md_atof (int type, char *litP, int *sizeP)
230{
499ac353 231 return ieee_md_atof (type, litP, sizeP, FALSE);
d70c5fc7
NC
232}
233
234valueT
235md_section_align (segT segment, valueT size)
236{
fd361982 237 int align = bfd_section_alignment (segment);
8d3842cd 238 return ((size + (1 << align) - 1) & -(1 << align));
d70c5fc7
NC
239}
240
241symbolS *
242md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
243{
244 return NULL;
245}
246
247int
248md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
249 segT segment_type ATTRIBUTE_UNUSED)
250{
662a2e45 251 printf (_("call to md_estimate_size_before_relax \n"));
d70c5fc7
NC
252 abort ();
253}
254
255
256long
257md_pcrel_from (fixS *fixP)
258{
259 long temp_val;
260 temp_val=fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
261
262 return temp_val;
263}
264
265long
266md_pcrel_from_section (fixS *fixP, segT sec)
267{
268 if (fixP->fx_addsy != (symbolS *) NULL
269 && (! S_IS_DEFINED (fixP->fx_addsy)
270 || S_GET_SEGMENT (fixP->fx_addsy) != sec
271 || S_IS_EXTERNAL (fixP->fx_addsy)
272 || S_IS_WEAK (fixP->fx_addsy)))
273 {
274 return 0;
275 }
276
277 return md_pcrel_from (fixP);
278}
279
280arelent *
281tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
282{
283 arelent *rel;
284 bfd_reloc_code_real_type r_type;
285
286 if (fixp->fx_addsy && fixp->fx_subsy)
287 {
288 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
289 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
290 {
291 as_bad_where (fixp->fx_file, fixp->fx_line,
662a2e45 292 _("Difference of symbols in different sections is not supported"));
d70c5fc7
NC
293 return NULL;
294 }
295 }
296
325801bd
TS
297 rel = XNEW (arelent);
298 rel->sym_ptr_ptr = XNEW (asymbol *);
d70c5fc7
NC
299 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
300 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
301 rel->addend = fixp->fx_offset;
302
303 r_type = fixp->fx_r_type;
304
305#define DEBUG 0
306#if DEBUG
307 fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
662a2e45 308 fflush (stderr);
d70c5fc7
NC
309#endif
310
311 rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
312 if (rel->howto == NULL)
313 {
314 as_bad_where (fixp->fx_file, fixp->fx_line,
315 _("Cannot represent relocation type %s"),
316 bfd_get_reloc_code_name (r_type));
317 return NULL;
318 }
319
320 return rel;
321}
322
323void
324md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
325{
662a2e45 326 if (!strstr (seg->name,".debug"))
d70c5fc7
NC
327 {
328 if (*valP < 128)
329 *valP /= 2;
330 if (*valP>268435455)
331 {
332 *valP = *valP * (-1);
333 *valP /= 2;
334 *valP = 256 - (*valP);
335 }
336 }
3739860c 337
d70c5fc7
NC
338 gas_cgen_md_apply_fix (fixP, valP, seg);
339 return;
340}
341
342void
343md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
344 segT seg ATTRIBUTE_UNUSED,
345 fragS *fragP ATTRIBUTE_UNUSED)
346{
347 printf (_("call to md_convert_frag \n"));
348 abort ();
349}
This page took 0.801293 seconds and 4 git commands to generate.