Update copyright years
[deliverable/binutils-gdb.git] / gas / config / tc-xgate.c
CommitLineData
f6c1a2d5 1/* tc-xgate.c -- Assembler code for Freescale XGATE
4b95cf5c 2 Copyright (C) 2010-2014 Free Software Foundation, Inc.
f6c1a2d5
NC
3 Contributed by Sean Keys <skeys@ipdatasys.com>
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
9 the Free Software Foundation; either version 3, or (at your option)
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
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22#include "as.h"
23#include "safe-ctype.h"
24#include "subsegs.h"
25#include "opcode/xgate.h"
26#include "dwarf2dbg.h"
27#include "elf/xgate.h"
28
29const char comment_chars[] = ";!";
30const char line_comment_chars[] = "#*";
31const char line_separator_chars[] = "";
32const char EXP_CHARS[] = "eE";
33const char FLT_CHARS[] = "dD";
34
0e1c2434
SK
35/* Max opcodes per opcode handle. */
36#define MAX_OPCODES 0x05
37
234fa27c
AM
38#define SIXTEENTH_BIT 0x8000
39#define N_BITS_IN_WORD 16
40#define MAX_NUM_OPERANDS 3
f6c1a2d5
NC
41
42/* #define STATE_CONDITIONAL_BRANCH (1) */
43#define STATE_PC_RELATIVE (2)
44#define REGISTER_P(ptr) (ptr == 'r')
45#define INCREMENT 01
46#define DECREMENT 02
47#define MAXREGISTER 07
48#define MINREGISTER 00
49
50#define OPTION_MMCU 'm'
51
52/* This macro has no side-effects. */
53#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
54
19f55fe4
SK
55/* Each unique opcode name has a handle. That handle may
56 contain pointers to opcodes with the same name but
57 different address modes. */
f6c1a2d5
NC
58struct xgate_opcode_handle
59{
60 int number_of_modes;
61 char *name;
62 struct xgate_opcode *opc0[MAX_OPCODES];
63};
64
234fa27c
AM
65/* XGATE's registers all are 16-bit general purpose.
66 They are numbered according to the specifications. */
3879925e
SK
67typedef enum register_id
68{
69 REG_NONE = -1,
70 REG_R0 = 0,
71 REG_R1 = 1,
72 REG_R2 = 2,
73 REG_R3 = 3,
74 REG_R4 = 4,
75 REG_R5 = 5,
76 REG_R6 = 6,
77 REG_R7 = 7,
78 REG_PC = 8,
79 REG_CCR = 9
80} register_id;
81
82/* Operand Modifiers */
83typedef enum op_modifiers
84{
85 MOD_NONE = -1,
86 MOD_POSTINC = 1,
87 MOD_PREDEC = 2,
88 MOD_CONSTANT = 3,
89 MOD_LOAD_HIGH = 4,
90 MOD_LOAD_LOW = 5
91}op_modifiers;
92
93typedef struct s_operand
94{
95 expressionS exp;
96 register_id reg;
97 op_modifiers mod;
98} s_operand;
99
100
234fa27c
AM
101/* Forward declarations. */
102static inline char *skip_whitespace (char *);
103static void get_default_target (void);
104static char *extract_word (char *, char *, int);
105static struct xgate_opcode *xgate_find_match (struct xgate_opcode_handle *,
0e1c2434 106 int, s_operand [], unsigned int);
234fa27c
AM
107static int cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
108static void xgate_print_table (void);
109static unsigned int xgate_get_operands (char *, s_operand []);
110static register_id reg_name_search (char *);
111static op_modifiers xgate_determine_modifiers(char **);
112static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
113static unsigned int xgate_parse_operand (struct xgate_opcode *, int *, int,
114 char **, s_operand);
f6c1a2d5 115
f6c1a2d5
NC
116static struct hash_control *xgate_hash;
117
118/* Previous opcode. */
119static unsigned int prev = 0;
120
121static unsigned char fixup_required = 0;
122
123/* Used to enable clipping of 16 bit operands into 8 bit constraints. */
234fa27c 124static unsigned char autoHiLo = 0;
f6c1a2d5
NC
125
126static char oper_check;
127static char flag_print_insn_syntax = 0;
128static char flag_print_opcodes = 0;
129
130static int current_architecture;
131static const char *default_cpu;
132
133/* ELF flags to set in the output file header. */
134static int elf_flags = E_XGATE_F64;
135
136/* This table describes how you change sizes for the various types of variable
137 size expressions. This version only supports two kinds. */
138
139/* The fields are:
140 How far Forward this mode will reach.
141 How far Backward this mode will reach.
142 How many bytes this mode will add to the size of the frag.
143 Which mode to go to if the offset won't fit in this one. */
144
145relax_typeS md_relax_table[] =
146{
147 {1, 1, 0, 0}, /* First entries aren't used. */
148 {1, 1, 0, 0}, /* For no good reason except. */
149 {1, 1, 0, 0}, /* that the VAX doesn't either. */
150 {1, 1, 0, 0},
151 /* XGATE 9 and 10 bit pc rel todo complete and test */
152/*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
153 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
154 {0, 0, 0, 0}
155};
156
f6c1a2d5
NC
157/* This table describes all the machine specific pseudo-ops the assembler
158 has to support. The fields are: pseudo-op name without dot function to
159 call to execute this pseudo-op Integer arg to pass to the function. */
160const pseudo_typeS md_pseudo_table[] =
161{
162 /* The following pseudo-ops are supported for MRI compatibility. */
163 {0, 0, 0}
164};
165
166const char *md_shortopts = "m:";
167
168struct option md_longopts[] =
169{
170#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
171 { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
172
173#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
174 { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
175
176#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
177 { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
178
179#define OPTION_MSHORT (OPTION_MD_BASE + 3)
180 { "mshort", no_argument, NULL, OPTION_MSHORT },
181
182#define OPTION_MLONG (OPTION_MD_BASE + 4)
183 { "mlong", no_argument, NULL, OPTION_MLONG },
184
185#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
186 { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
187
188#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
189 { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
190
191 { NULL, no_argument, NULL, 0 }
192};
193
194size_t md_longopts_size = sizeof(md_longopts);
195
196char *
197md_atof (int type, char *litP, int *sizeP)
198{
199 return ieee_md_atof (type, litP, sizeP, TRUE);
200}
201
202int
203md_parse_option (int c, char *arg)
204{
205 switch (c)
206 {
207 case OPTION_MMCU:
208 if (strcasecmp (arg, "v1") == 0)
209 current_architecture = XGATE_V1;
210 else if (strcasecmp (arg, "v2") == 0)
211 current_architecture = XGATE_V2;
212 else if (strcasecmp (arg, "v3") == 0)
213 current_architecture = XGATE_V3;
214 else
215 as_bad (_(" architecture variant invalid"));
216 break;
217
218 case OPTION_PRINT_INSN_SYNTAX:
219 flag_print_insn_syntax = 1;
220 break;
221
222 case OPTION_PRINT_OPCODES:
223 flag_print_opcodes = 1;
224 break;
225
226 case OPTION_GENERATE_EXAMPLE:
227 flag_print_opcodes = 2;
228 break;
229
230 case OPTION_MSHORT:
231 elf_flags &= ~E_XGATE_I32;
232 break;
233
234 case OPTION_MLONG:
235 elf_flags |= E_XGATE_I32;
236 break;
237
238 case OPTION_MSHORT_DOUBLE:
239 elf_flags &= ~E_XGATE_F64;
240 break;
241
242 case OPTION_MLONG_DOUBLE:
243 elf_flags |= E_XGATE_F64;
244 break;
245
246 default:
247 return 0;
248 }
249 return 1;
250}
251
252const char *
253xgate_arch_format (void)
254{
255 get_default_target ();
256
257 if (current_architecture & cpuxgate)
258 return "elf32-xgate";
259
260 return "error";
261}
262
263static void
264get_default_target (void)
265{
266 const bfd_target *target;
267 bfd abfd;
268
269 if (current_architecture != 0)
270 return;
271
272 default_cpu = "unknown";
273 target = bfd_find_target (0, &abfd);
274
275 if (target && target->name)
276 {
277 if (strcmp (target->name, "elf32-xgate") == 0)
234fa27c
AM
278 {
279 current_architecture = cpuxgate;
280 default_cpu = "XGATE V1";
281 return;
282 }
f6c1a2d5
NC
283
284 as_bad (_("Default target `%s' is not supported."), target->name);
285 }
286}
287
288void
289md_begin (void)
290{
291 struct xgate_opcode *xgate_opcode_ptr = NULL;
292 struct xgate_opcode *xgate_op_table = NULL;
293 struct xgate_opcode_handle *op_handles = 0;
294 char *prev_op_name = 0;
295 int handle_enum = 0;
19f55fe4 296 int number_of_op_handles = 0;
f6c1a2d5
NC
297 int i, j = 0;
298
299 /* Create a local copy of our opcode table
300 including an extra line for NULL termination. */
301 xgate_op_table = (struct xgate_opcode *)
19f55fe4 302 xmalloc ((xgate_num_opcodes) * sizeof (struct xgate_opcode));
f6c1a2d5
NC
303
304 memset (xgate_op_table, 0,
19f55fe4 305 sizeof(struct xgate_opcode) * (xgate_num_opcodes));
f6c1a2d5
NC
306
307 for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0;
234fa27c 308 i < xgate_num_opcodes; i++)
f6c1a2d5
NC
309 xgate_op_table[i] = xgate_opcode_ptr[i];
310
311 qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode),
312 (int (*)(const void *, const void *)) cmp_opcode);
313
314 /* Calculate number of handles since this will be
315 smaller than the raw number of opcodes in the table. */
19f55fe4
SK
316 prev_op_name = "";
317 for (xgate_opcode_ptr = xgate_op_table, i = 0; i < xgate_num_opcodes;
234fa27c 318 xgate_opcode_ptr++, i++)
f6c1a2d5 319 {
19f55fe4 320 if (strcmp (prev_op_name, xgate_opcode_ptr->name))
234fa27c 321 number_of_op_handles++;
f6c1a2d5
NC
322 prev_op_name = xgate_opcode_ptr->name;
323 }
324
325 op_handles = (struct xgate_opcode_handle *)
19f55fe4 326 xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_op_handles));
f6c1a2d5 327
19f55fe4 328 /* Insert unique opcode names into hash table, aliasing duplicates. */
f6c1a2d5
NC
329 xgate_hash = hash_new ();
330
19f55fe4 331 prev_op_name = "";
f6c1a2d5 332 for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
234fa27c 333 i++, xgate_opcode_ptr++)
f6c1a2d5 334 {
19f55fe4 335 if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
234fa27c
AM
336 {
337 handle_enum++;
338 op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
339 }
19f55fe4 340 else
234fa27c
AM
341 {
342 handle_enum = 0;
343 if (i)
344 j++;
345 op_handles[j].name = xgate_opcode_ptr->name;
346 op_handles[j].opc0[0] = xgate_opcode_ptr;
347 hash_insert (xgate_hash, (char *) op_handles[j].name,
348 (char *) &(op_handles[j]));
349 }
f6c1a2d5
NC
350 op_handles[j].number_of_modes = handle_enum;
351 prev_op_name = op_handles[j].name;
352 }
353
f4b1f6a9
SK
354 if (flag_print_opcodes)
355 {
464e3686 356 xgate_print_table ();
f4b1f6a9
SK
357 exit (EXIT_SUCCESS);
358 }
f6c1a2d5
NC
359}
360
361void
362xgate_init_after_args (void)
363{
364}
365
366void
367md_show_usage (FILE * stream)
368{
369 get_default_target ();
370
234fa27c 371 fprintf (stream,
f6c1a2d5 372 _("\
234fa27c
AM
373Freescale XGATE co-processor options:\n\
374 -mshort use 16-bit int ABI (default)\n\
375 -mlong use 32-bit int ABI\n\
376 -mshort-double use 32-bit double ABI\n\
377 -mlong-double use 64-bit double ABI (default)\n\
378 --mxgate specify the processor variant[default %s]\n\
379 --print-insn-syntax print the syntax of instruction in case of error\n\
380 --print-opcodes print the list of instructions with syntax\n\
381 --generate-example generate an example of each instruction"),
f6c1a2d5
NC
382 default_cpu);
383}
384
385enum bfd_architecture
386xgate_arch (void)
387{
388 get_default_target ();
389 return bfd_arch_xgate;
390}
391
392int
393xgate_mach (void)
394{
395 return 0;
396}
397
234fa27c 398static void
f6c1a2d5
NC
399xgate_print_syntax (char *name)
400{
401 int i;
402
403 for (i = 0; i < xgate_num_opcodes; i++)
404 {
405 if (!strcmp (xgate_opcodes[i].name, name))
234fa27c
AM
406 {
407 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
408 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
f6c1a2d5 409 xgate_opcodes[i].name);
234fa27c
AM
410 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
411 printf ("\tFormat is %s\n", xgate_opcodes[i].name);
412 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
413 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
414 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
415 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
416 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
417 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
418 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
419 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
420 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
421 printf ("\tFormat is %s\tRx, <8-bit value>\n",
f6c1a2d5 422 xgate_opcodes[i].name);
234fa27c
AM
423 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
424 printf ("\tFormat is %s\tRx, <16-bit value>\n",
f6c1a2d5 425 xgate_opcodes[i].name);
234fa27c
AM
426 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
427 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
428 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
429 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
430 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
431 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
432 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
433 printf ("\tFormat is %s\tRx, <16-bit value>\n",
f6c1a2d5 434 xgate_opcodes[i].name);
234fa27c 435 }
f6c1a2d5
NC
436 }
437}
438
234fa27c 439static void
f6c1a2d5
NC
440xgate_print_table (void)
441{
442 int i;
443
444 for (i = 0; i < xgate_num_opcodes; i++)
445 xgate_print_syntax (xgate_opcodes[i].name);
446
447 return;
448}
449
450const char *
451xgate_listing_header (void)
452{
453 if (current_architecture & cpuxgate)
454 return "XGATE GAS ";
455
456 return "ERROR MC9S12X GAS ";
457}
458
459symbolS *
460md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
461{
462 return 0;
463}
464
465/* GAS will call this function for each section at the end of the assembly,
466 to permit the CPU backend to adjust the alignment of a section. */
467
468valueT
469md_section_align (asection * seg, valueT addr)
470{
471 int align = bfd_get_section_alignment (stdoutput, seg);
472 return ((addr + (1 << align) - 1) & (-1 << align));
473}
474
475void
476md_assemble (char *input_line)
477{
478 struct xgate_opcode *opcode = 0;
479 struct xgate_opcode *macro_opcode = 0;
480 struct xgate_opcode_handle *opcode_handle = 0;
481 /* Caller expects it to be returned as it was passed. */
482 char *saved_input_line = input_line;
483 char op_name[9] = { 0 };
0e1c2434 484 unsigned int operandCount = 0;
f6c1a2d5
NC
485 char *p = 0;
486
3879925e
SK
487 s_operand new_operands[MAX_NUM_OPERANDS];
488
f6c1a2d5
NC
489 fixup_required = 0;
490 oper_check = 0; /* set error flags */
491 input_line = extract_word (input_line, op_name, sizeof(op_name));
492
493 /* Check to make sure we are not reading a bogus line. */
494 if (!op_name[0])
495 as_bad (_("opcode missing or not found on input line"));
496
497 if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
234fa27c 498 op_name)))
f6c1a2d5
NC
499 {
500 as_bad (_("opcode %s not found in opcode hash table"), op_name);
501 }
502 else
503 {
3879925e
SK
504 /* Parse operands so we can find the proper opcode bin. */
505
0e1c2434 506 operandCount = xgate_get_operands (input_line, new_operands);
f6c1a2d5
NC
507
508 opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
0e1c2434 509 new_operands, operandCount);
f6c1a2d5
NC
510
511 if (!opcode)
234fa27c
AM
512 {
513 as_bad (_("matching operands to opcode "));
514 xgate_print_syntax (opcode_handle->opc0[0]->name);
515 }
f6c1a2d5 516 else if (opcode->size == 2)
234fa27c 517 {
f6c1a2d5 518 /* Size is one word - assemble that native insn. */
234fa27c
AM
519 xgate_scan_operands (opcode, new_operands);
520 }
f6c1a2d5 521 else
234fa27c 522 {
f6c1a2d5 523 /* Insn is a simplified instruction - expand it out. */
234fa27c
AM
524 autoHiLo = 1;
525 unsigned int i;
526
527 /* skip past our ';' separator. */
528 for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
529 i--, p++)
530 {
531 if (*p == ';')
532 {
533 p++;
534 break;
535 }
536 }
537 input_line = skip_whitespace (input_line);
538 char *macro_inline = input_line;
539
540 /* Loop though the macro's opcode list and apply operands to
541 each real opcode. */
542 for (i = 0; *p && i < (opcode->size / 2); i++)
543 {
f6c1a2d5 544 /* Loop though macro operand list. */
234fa27c
AM
545 input_line = macro_inline; /* Rewind. */
546 p = extract_word (p, op_name, 10);
f6c1a2d5 547
234fa27c 548 if (!(opcode_handle = (struct xgate_opcode_handle *)
f6c1a2d5 549 hash_find (xgate_hash, op_name)))
234fa27c
AM
550 {
551 as_bad (_(": processing macro, real opcode handle"
552 " not found in hash"));
553 break;
554 }
555 else
556 {
0e1c2434
SK
557 operandCount = xgate_get_operands(input_line, new_operands);
558 macro_opcode = xgate_find_match (opcode_handle,
559 opcode_handle->number_of_modes, new_operands,
560 operandCount);
234fa27c 561 xgate_scan_operands (macro_opcode, new_operands);
234fa27c
AM
562 }
563 }
564 }
f6c1a2d5 565 }
8d8ad4eb 566 autoHiLo = 0;
f6c1a2d5
NC
567 input_line = saved_input_line;
568}
569
570/* Force truly undefined symbols to their maximum size, and generally set up
571 the frag list to be relaxed. */
572
573int
574md_estimate_size_before_relax (fragS *fragp, asection *seg)
575{
576 /* If symbol is undefined or located in a different section,
577 select the largest supported relocation. */
578 relax_substateT subtype;
234fa27c 579 relax_substateT rlx_state[] = { 0, 2 };
f6c1a2d5
NC
580
581 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
582 {
583 if (fragp->fr_subtype == rlx_state[subtype]
234fa27c
AM
584 && (!S_IS_DEFINED (fragp->fr_symbol)
585 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
586 {
587 fragp->fr_subtype = rlx_state[subtype + 1];
588 break;
589 }
f6c1a2d5
NC
590 }
591
592 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
593 abort ();
594
595 return md_relax_table[fragp->fr_subtype].rlx_length;
596}
597
598
599/* Relocation, relaxation and frag conversions. */
600
601/* PC-relative offsets are relative to the start of the
602 next instruction. That is, the address of the offset, plus its
603 size, since the offset is always the last part of the insn. */
604
605long
606md_pcrel_from (fixS * fixP)
607{
608 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
609}
610
611/* If while processing a fixup, a reloc really needs to be created
612 then it is done here. */
613
614arelent *
615tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
616{
617 arelent * reloc;
618
619 reloc = (arelent *) xmalloc (sizeof(arelent));
620 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *));
621 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
622 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
623
624 if (fixp->fx_r_type == 0)
234fa27c 625 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
f6c1a2d5 626 else
234fa27c 627 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
f6c1a2d5
NC
628
629 if (reloc->howto == (reloc_howto_type *) NULL)
630 {
631 as_bad_where (fixp->fx_file, fixp->fx_line, _
234fa27c
AM
632 ("Relocation %d is not supported by object file format."),
633 (int) fixp->fx_r_type);
f6c1a2d5
NC
634 return NULL;
635 }
636
637 /* Since we use Rel instead of Rela, encode the vtable entry to be
638 used in the relocation's section offset. */
639 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
640 reloc->address = fixp->fx_offset;
641 reloc->addend = 0;
642 return reloc;
643}
644
645/* Patch the instruction with the resolved operand. Elf relocation
646 info will also be generated to take care of linker/loader fixups.
647 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
648 for the support of --gstabs. */
649
650void
651md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
652{
653 char *where;
654 long value = *valP;
655 int opcode = 0;
656 ldiv_t result;
657
234fa27c
AM
658 /* If the fixup is done mark it done so no further symbol resolution
659 will take place. */
f6c1a2d5 660 if (fixP->fx_addsy == (symbolS *) NULL)
234fa27c 661 fixP->fx_done = 1;
f6c1a2d5
NC
662
663 /* We don't actually support subtracting a symbol. */
664 if (fixP->fx_subsy != (symbolS *) NULL)
665 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
666
667 where = fixP->fx_frag->fr_literal + fixP->fx_where;
668 opcode = bfd_getl16 (where);
669 int mask = 0;
670
671 switch (fixP->fx_r_type)
672 {
673 case R_XGATE_PCREL_9:
674 if (value < -512 || value > 511)
675 as_bad_where (fixP->fx_file, fixP->fx_line,
234fa27c
AM
676 _("Value %ld too large for 9-bit PC-relative branch."),
677 value);
f6c1a2d5
NC
678 result = ldiv (value, 2); /* from bytes to words */
679 value = result.quot;
680 if (result.rem)
681 as_bad_where (fixP->fx_file, fixP->fx_line, _
234fa27c
AM
682 ("Value %ld not aligned by 2 for 9-bit"
683 " PC-relative branch."), value);
684 /* Clip into 8-bit field.
685 FIXME I'm sure there is a more proper place for this. */
686 mask = 0x1FF;
f6c1a2d5
NC
687 value &= mask;
688 number_to_chars_bigendian (where, (opcode | value), 2);
689 break;
690 case R_XGATE_PCREL_10:
691 if (value < -1024 || value > 1023)
692 as_bad_where (fixP->fx_file, fixP->fx_line,
234fa27c
AM
693 _("Value %ld too large for 10-bit PC-relative branch."),
694 value);
f6c1a2d5
NC
695 result = ldiv (value, 2); /* from bytes to words */
696 value = result.quot;
697 if (result.rem)
698 as_bad_where (fixP->fx_file, fixP->fx_line, _
234fa27c
AM
699 ("Value %ld not aligned by 2 for 10-bit"
700 " PC-relative branch."), value);
701 /* Clip into 9-bit field.
702 FIXME I'm sure there is a more proper place for this. */
703 mask = 0x3FF;
f6c1a2d5
NC
704 value &= mask;
705 number_to_chars_bigendian (where, (opcode | value), 2);
706 break;
707 case BFD_RELOC_XGATE_IMM8_HI:
708 if (value < -65537 || value > 65535)
709 as_bad_where (fixP->fx_file, fixP->fx_line,
710 _("Value out of 16-bit range."));
711 value >>= 8;
712 value &= 0x00ff;
713 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
714 break;
715 case BFD_RELOC_XGATE_24:
716 case BFD_RELOC_XGATE_IMM8_LO:
717 if (value < -65537 || value > 65535)
718 as_bad_where (fixP->fx_file, fixP->fx_line,
719 _("Value out of 16-bit range."));
720 value &= 0x00ff;
721 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
722 break;
723 case BFD_RELOC_XGATE_IMM3:
724 if (value < 0 || value > 7)
725 as_bad_where (fixP->fx_file, fixP->fx_line,
726 _("Value out of 3-bit range."));
727 value <<= 8; /* make big endian */
728 number_to_chars_bigendian (where, (opcode | value), 2);
729 break;
730 case BFD_RELOC_XGATE_IMM4:
731 if (value < 0 || value > 15)
732 as_bad_where (fixP->fx_file, fixP->fx_line,
733 _("Value out of 4-bit range."));
734 value <<= 4; /* align the operand bits */
735 number_to_chars_bigendian (where, (opcode | value), 2);
736 break;
737 case BFD_RELOC_XGATE_IMM5:
738 if (value < 0 || value > 31)
739 as_bad_where (fixP->fx_file, fixP->fx_line,
740 _("Value out of 5-bit range."));
741 value <<= 5; /* align the operand bits */
742 number_to_chars_bigendian (where, (opcode | value), 2);
743 break;
744 case BFD_RELOC_8:
745 ((bfd_byte *) where)[0] = (bfd_byte) value;
746 break;
747 case BFD_RELOC_32:
748 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
f6c1a2d5
NC
749 break;
750 case BFD_RELOC_16:
751 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
752 break;
753 default:
754 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
755 fixP->fx_r_type);
756 break;
757 }
758}
759
760/* See whether we need to force a relocation into the output file. */
761
762int
763tc_xgate_force_relocation (fixS * fixP)
764{
765 if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
766 return 1;
767 return generic_force_reloc (fixP);
768}
769
770/* Here we decide which fixups can be adjusted to make them relative
771 to the beginning of the section instead of the symbol. Basically
772 we need to make sure that the linker relaxation is done
773 correctly, so in some cases we force the original symbol to be
774 used. */
775
776int
777tc_xgate_fix_adjustable (fixS * fixP)
778{
779 switch (fixP->fx_r_type)
780 {
781 /* For the linker relaxation to work correctly, these relocs
782 need to be on the symbol itself. */
783 case BFD_RELOC_16:
784 case BFD_RELOC_XGATE_RL_JUMP:
785 case BFD_RELOC_XGATE_RL_GROUP:
786 case BFD_RELOC_VTABLE_INHERIT:
787 case BFD_RELOC_VTABLE_ENTRY:
788 case BFD_RELOC_32:
789 return 0;
790 default:
791 return 1;
792 }
793}
794
795void
796md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
797 asection * sec ATTRIBUTE_UNUSED,
798 fragS * fragP ATTRIBUTE_UNUSED)
799{
800 as_bad (("md_convert_frag not implemented yet"));
801 abort ();
802}
803
804/* Set the ELF specific flags. */
805
806void
807xgate_elf_final_processing (void)
808{
809 elf_flags |= EF_XGATE_MACH;
810 elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
811 elf_elfheader (stdoutput)->e_flags |= elf_flags;
812}
813
814static inline char *
815skip_whitespace (char *s)
816{
817 while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
818 s++;
819
820 return s;
821}
822
823/* Extract a word (continuous alpha-numeric chars) from the input line. */
824
825static char *
826extract_word (char *from, char *to, int limit)
827{
828 char *op_end;
829 int size = 0;
830
831 /* Drop leading whitespace. */
832 from = skip_whitespace (from);
833 *to = 0;
834 /* Find the op code end. */
835 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
836 {
837 to[size++] = *op_end++;
838 if (size + 1 >= limit)
234fa27c 839 break;
f6c1a2d5
NC
840 }
841 to[size] = 0;
842 return op_end;
843}
844
845static char *
846xgate_new_instruction (int size)
847{
848 char *f = frag_more (size);
849 dwarf2_emit_insn (size);
850 return f;
851}
852
234fa27c 853static unsigned short
f6c1a2d5
NC
854xgate_apply_operand (unsigned short new_mask,
855 unsigned short *availiable_mask_bits,
856 unsigned short mask,
857 unsigned char n_bits)
858{
859 unsigned short n_shifts;
860 unsigned int n_drop_bits;
861
234fa27c
AM
862 /* Shift until you find an available operand bit "1" and record
863 the number of shifts. */
f6c1a2d5
NC
864 for (n_shifts = 0;
865 !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
866 n_shifts++)
867 *availiable_mask_bits <<= 1;
868
234fa27c
AM
869 /* Shift for the number of bits your operand requires while bits
870 are available. */
f6c1a2d5
NC
871 for (n_drop_bits = n_bits;
872 n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
873 --n_drop_bits)
874 *availiable_mask_bits <<= 1;
875
876 if (n_drop_bits)
877 as_bad (_(":operand has too many bits"));
878 *availiable_mask_bits >>= n_shifts + n_bits;
879 if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
880 {
881 oper_check = 1; /* flag operand check as good */
882 }
883 new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
884 mask |= new_mask;
885 return mask;
886}
887
888/* Parse ordinary expression. */
889
890static char *
891xgate_parse_exp (char *s, expressionS * op)
892{
893 input_line_pointer = s;
894 expression(op);
895 if (op->X_op == O_absent)
896 as_bad (_("missing operand"));
897 return input_line_pointer;
898}
899
3879925e
SK
900static int
901cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
902{
903 return strcmp (op1->name, op2->name);
904}
905
906static struct xgate_opcode *
907xgate_find_match (struct xgate_opcode_handle *opcode_handle,
0e1c2434 908 int numberOfModes, s_operand oprs[], unsigned int operandCount)
3879925e
SK
909{
910 int i;
f6c1a2d5 911
3879925e
SK
912 if (numberOfModes == 0)
913 return opcode_handle->opc0[0];
914
915 for (i = 0; i <= numberOfModes; i++)
0e1c2434
SK
916 {
917 switch (operandCount)
918 {
919 case 0:
920 if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_INH))
921 return opcode_handle->opc0[i];
922 break;
923 case 1:
924 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
925 if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_MON))
926 return opcode_handle->opc0[i];
927 if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_DYA_MON))
928 return opcode_handle->opc0[i];
929 if (oprs[0].reg == REG_NONE)
930 if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM3))
931 return opcode_handle->opc0[i];
932 break;
933 case 2:
934 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
935 {
936 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
937 if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_DYA))
938 return opcode_handle->opc0[i];
939 if (oprs[1].reg == REG_CCR)
940 if (!strcmp(opcode_handle->opc0[i]->constraints,
941 XGATE_OP_MON_R_C))
942 return opcode_handle->opc0[i];
943 if (oprs[1].reg == REG_PC)
944 if (!strcmp(opcode_handle->opc0[i]->constraints,
945 XGATE_OP_MON_R_P))
946 return opcode_handle->opc0[i];
947 if (oprs[1].reg == REG_NONE)
948 if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM16)
949 || !strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM8)
950 || !strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_IMM4)
951 || !strcmp(opcode_handle->opc0[i]->constraints,
952 XGATE_OP_IMM16mADD)
953 || !strcmp(opcode_handle->opc0[i]->constraints,
954 XGATE_OP_IMM16mAND)
955 || !strcmp(opcode_handle->opc0[i]->constraints,
956 XGATE_OP_IMM16mCPC)
957 || !strcmp(opcode_handle->opc0[i]->constraints,
958 XGATE_OP_IMM16mSUB)
959 || !strcmp(opcode_handle->opc0[i]->constraints,
960 XGATE_OP_IMM16mLDW))
961 return opcode_handle->opc0[i];
962 }
963 if (oprs[0].reg == REG_CCR)
964 if (!strcmp(opcode_handle->opc0[i]->constraints, XGATE_OP_MON_C_R))
965 return opcode_handle->opc0[i];
966 break;
967 case 3:
968 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
969 {
970 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
971 {
972 if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
973 {
974 if (!strcmp(opcode_handle->opc0[i]->constraints,
975 XGATE_OP_IDR)
976 || !strcmp(opcode_handle->opc0[i]->constraints,
977 XGATE_OP_TRI))
978 return opcode_handle->opc0[i];
979 }
980
981 if (oprs[2].reg == REG_NONE)
982 if (!strcmp(opcode_handle->opc0[i]->constraints,
983 XGATE_OP_IDO5))
984 return opcode_handle->opc0[i];
985 }
986 }
987 break;
988 default:
989 as_bad(_("unknown operand count"));
990 break;
991 }
992 }
993 return NULL ;
3879925e
SK
994}
995
996/* Because we are dealing with two different core that view the system
997 memory with different offsets, we must differentiate what core a
998 symbol belongs to, in order for the linker to cross-link. */
999
1000int
1001xgate_frob_symbol (symbolS *sym)
f6c1a2d5 1002{
3879925e
SK
1003 asymbol *bfdsym;
1004 elf_symbol_type *elfsym;
f6c1a2d5 1005
3879925e
SK
1006 bfdsym = symbol_get_bfdsym (sym);
1007 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
f6c1a2d5 1008
3879925e 1009 gas_assert(elfsym);
f6c1a2d5 1010
3879925e
SK
1011 /* Mark the symbol as being *from XGATE */
1012 elfsym->internal_elf_sym.st_target_internal = 1;
f6c1a2d5 1013
3879925e 1014 return 0;
f6c1a2d5 1015}
f6c1a2d5 1016
234fa27c 1017static unsigned int
3879925e 1018xgate_get_operands (char *line, s_operand oprs[])
f6c1a2d5 1019{
3879925e
SK
1020 int num_operands;
1021
1022 /* If there are no operands, then it must be inherent. */
1023 if (*line == 0 || *line == '\n' || *line == '\r')
0e1c2434 1024 return 0;
3879925e
SK
1025
1026 for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
234fa27c 1027 num_operands++)
3879925e
SK
1028 {
1029 line = skip_whitespace (line);
1030 if (*line == '#')
234fa27c 1031 line++;
3879925e 1032
8d8ad4eb 1033 oprs[num_operands].mod = xgate_determine_modifiers (&line);
3879925e
SK
1034
1035 if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
234fa27c 1036 line = xgate_parse_exp (line, &oprs[num_operands].exp);
3879925e
SK
1037
1038 /* skip to next operand */
1039 while (*line != 0)
234fa27c
AM
1040 {
1041 if (*line == ',')
1042 {
1043 line++;
1044 break;
1045 }
1046 line++;
1047 }
3879925e 1048 }
3879925e
SK
1049 if (num_operands > MAX_NUM_OPERANDS)
1050 return 0;
0e1c2434 1051 return num_operands;
3879925e
SK
1052}
1053
1054/* reg_name_search() finds the register number given its name.
1055 Returns the register number or REG_NONE on failure. */
1056static register_id
1057reg_name_search (char *name)
1058{
1059 if (strncasecmp (name, "r0", 2) == 0)
1060 return REG_R0;
1061 if (strncasecmp (name, "r1", 2) == 0)
1062 return REG_R1;
1063 if (strncasecmp (name, "r2", 2) == 0)
1064 return REG_R2;
1065 if (strncasecmp (name, "r3", 2) == 0)
1066 return REG_R3;
1067 if (strncasecmp (name, "r4", 2) == 0)
1068 return REG_R4;
1069 if (strncasecmp (name, "r5", 2) == 0)
1070 return REG_R5;
1071 if (strncasecmp (name, "r6", 2) == 0)
1072 return REG_R6;
1073 if (strncasecmp (name, "r7", 2) == 0)
1074 return REG_R7;
1075 if (strncasecmp (name, "pc", 2) == 0)
1076 return REG_PC;
1077 if (strncasecmp (name, "ccr", 3) == 0)
1078 return REG_CCR;
1079 return REG_NONE;
1080}
1081
8d8ad4eb
SK
1082/* Parse operand modifiers such as inc/dec/hi/low. */
1083
234fa27c 1084static op_modifiers
8d8ad4eb 1085xgate_determine_modifiers(char **line)
3879925e
SK
1086{
1087 char *local_line = line[0];
1088
1089 if (strncasecmp (local_line, "%hi", 3) == 0)
1090 {
1091 *line += 3;
1092 return MOD_LOAD_HIGH;
1093 }
1094 if (strncasecmp (local_line, "%lo", 3) == 0)
1095 {
1096 *line += 3;
1097 return MOD_LOAD_LOW;
1098 }
3879925e 1099 if (*(local_line + 2) == '+')
234fa27c 1100 return MOD_POSTINC;
3879925e
SK
1101 if (strncasecmp (local_line, "-r", 2) == 0)
1102 {
1103 *line += 1;
1104 return MOD_PREDEC;
234fa27c 1105 }
3879925e 1106 return MOD_NONE;
f6c1a2d5
NC
1107}
1108
1109/* Parse instruction operands. */
1110
234fa27c 1111static void
3879925e 1112xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
f6c1a2d5
NC
1113{
1114 char *frag = xgate_new_instruction (opcode->size);
1115 int where = frag - frag_now->fr_literal;
1116 char *op = opcode->constraints;
1117 unsigned int bin = (int) opcode->bin_opcode;
f6c1a2d5
NC
1118 unsigned short oper_mask = 0;
1119 int operand_bit_length = 0;
1120 unsigned int operand = 0;
1121 char n_operand_bits = 0;
1122 char first_operand_equals_second = 0;
1123 int i = 0;
1124 char c = 0;
1125
1126 /* Generate available operand bits mask. */
1127 for (i = 0; (c = opcode->format[i]); i++)
1128 {
1129 if (ISDIGIT (c) || (c == 's'))
234fa27c
AM
1130 {
1131 oper_mask <<= 1;
1132 }
f6c1a2d5 1133 else
234fa27c
AM
1134 {
1135 oper_mask <<= 1;
1136 oper_mask += 1;
1137 n_operand_bits++;
1138 }
f6c1a2d5
NC
1139 }
1140
f6c1a2d5
NC
1141 /* Parse first operand. */
1142 if (*op)
1143 {
1144 if (*op == '=')
234fa27c
AM
1145 {
1146 first_operand_equals_second = 1;
1147 ++op;
1148 }
1149 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1150 &op, oprs[0]);
f6c1a2d5
NC
1151 ++op;
1152 bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
3879925e
SK
1153
1154 if(first_operand_equals_second)
234fa27c
AM
1155 bin = xgate_apply_operand (operand, &oper_mask, bin,
1156 operand_bit_length);
f6c1a2d5
NC
1157 /* Parse second operand. */
1158 if (*op)
234fa27c
AM
1159 {
1160 if (*op == ',')
1161 ++op;
1162 if (first_operand_equals_second)
1163 {
1164 bin = xgate_apply_operand (operand, &oper_mask, bin,
1165 operand_bit_length);
1166 ++op;
1167 }
1168 else
1169 {
1170 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1171 &op, oprs[1]);
1172 bin = xgate_apply_operand (operand, &oper_mask, bin,
1173 operand_bit_length);
1174 ++op;
1175 }
1176 }
f6c1a2d5
NC
1177 /* Parse the third register. */
1178 if (*op)
234fa27c
AM
1179 {
1180 if (*op == ',')
1181 ++op;
1182 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1183 &op, oprs[2]);
1184 bin = xgate_apply_operand (operand, &oper_mask, bin,
1185 operand_bit_length);
1186 }
f6c1a2d5
NC
1187 }
1188 if (opcode->size == 2 && fixup_required)
1189 {
1190 bfd_putl16 (bin, frag);
1191 }
0e1c2434
SK
1192 else if ( !strcmp (opcode->constraints, XGATE_OP_REL9)
1193 || !strcmp (opcode->constraints, XGATE_OP_REL10))
f6c1a2d5
NC
1194 {
1195 /* Write our data to a frag for further processing. */
3879925e 1196 bfd_putl16 (opcode->bin_opcode, frag);
f6c1a2d5
NC
1197 }
1198 else
1199 {
1200 /* Apply operand mask(s)to bin opcode and write the output. */
1201 /* Since we are done write this frag in xgate BE format. */
3879925e 1202 number_to_chars_bigendian (frag, bin, opcode->size);
f6c1a2d5
NC
1203 }
1204 prev = bin;
f6c1a2d5
NC
1205 return;
1206}
1207
1208static unsigned int
3879925e 1209xgate_parse_operand (struct xgate_opcode *opcode,
234fa27c
AM
1210 int *bit_width,
1211 int where,
1212 char **op_con,
1213 s_operand operand)
f6c1a2d5 1214{
f6c1a2d5
NC
1215 char *op_constraint = *op_con;
1216 unsigned int op_mask = 0;
f6c1a2d5
NC
1217 unsigned int pp_fix = 0;
1218 unsigned short max_size = 0;
1219 int i;
1220
1221 *bit_width = 0;
1222 /* Reset. */
1223
1224 switch (*op_constraint)
1225 {
1226 case '+': /* Indexed register operand +/- or plain r. */
f6c1a2d5
NC
1227 /* Default to neither inc or dec. */
1228 pp_fix = 0;
1229 *bit_width = 5;
3879925e 1230
8d8ad4eb 1231 if (operand.reg == REG_NONE)
234fa27c 1232 as_bad (_(": expected register name r0-r7 ") );
8d8ad4eb
SK
1233 op_mask = operand.reg;
1234 if(operand.mod == MOD_POSTINC)
234fa27c 1235 pp_fix = INCREMENT;
8d8ad4eb 1236 if(operand.mod == MOD_PREDEC)
234fa27c 1237 pp_fix = DECREMENT;
f6c1a2d5
NC
1238 op_mask <<= 2;
1239 op_mask |= pp_fix;
1240 break;
1241
1242 case 'r': /* Register operand. */
234fa27c
AM
1243 if (operand.reg == REG_NONE)
1244 as_bad (_(": expected register name r0-r7 "));
3879925e 1245
234fa27c 1246 *bit_width = 3;
3879925e 1247
234fa27c 1248 op_mask = operand.reg;
f6c1a2d5
NC
1249 break;
1250
1251 case 'i': /* Immediate value or expression expected. */
1252 /* Advance the original format pointer. */
1253 (*op_con)++;
1254 op_constraint++;
1255 if (ISDIGIT (*op_constraint))
234fa27c 1256 *bit_width = (int) *op_constraint - '0';
f6c1a2d5 1257 else if (*op_constraint == 'a')
234fa27c 1258 *bit_width = 0x0A;
f6c1a2d5 1259 else if (*op_constraint == 'f')
234fa27c
AM
1260 *bit_width = 0x0F;
1261
f6c1a2d5 1262 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
8d8ad4eb 1263 if (operand.exp.X_op == O_constant)
234fa27c
AM
1264 {
1265 op_mask = operand.exp.X_add_number;
1266 if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
1267 || operand.mod == MOD_LOAD_LOW)
1268 op_mask &= 0x00FF;
1269 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1270 && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
1271 op_mask >>= 8;
1272
1273 /* Make sure it fits. */
1274 for (i = *bit_width; i; i--)
1275 {
1276 max_size <<= 1;
1277 max_size += 1;
1278 }
1279 if (op_mask > max_size)
1280 as_bad (_(":operand value(%d) too big for constraint"), op_mask);
1281 }
f6c1a2d5 1282 else
234fa27c
AM
1283 {
1284 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1285 TODO fix. */
1286 fixup_required = 1;
1287 if (*op_constraint == '8')
1288 {
1289 if (((opcode->name[strlen (opcode->name) - 1] == 'l')
1290 && autoHiLo) || operand.mod == MOD_LOAD_LOW)
1291 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1292 BFD_RELOC_XGATE_24);
1293 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1294 && autoHiLo) || operand.mod == MOD_LOAD_HIGH )
1295 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1296 BFD_RELOC_XGATE_IMM8_HI);
1297 else
1298 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1299 "to load a 16-bit value."));
1300 }
1301 else if (*op_constraint == '5')
1302 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1303 BFD_RELOC_XGATE_IMM5);
1304 else if (*op_constraint == '4')
1305 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1306 BFD_RELOC_XGATE_IMM4);
1307 else if (*op_constraint == '3')
1308 fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1309 BFD_RELOC_XGATE_IMM3);
1310 else
1311 as_bad (_(":unknown relocation constraint size"));
1312 }
8d8ad4eb 1313 break;
f6c1a2d5
NC
1314
1315 case 'c': /* CCR register expected. */
3879925e 1316 *bit_width = 0;
8d8ad4eb 1317 if (operand.reg != REG_CCR)
234fa27c 1318 as_bad (_(": expected register name ccr "));
8d8ad4eb 1319 break;
f6c1a2d5
NC
1320
1321 case 'p': /* PC register expected. */
3879925e 1322 *bit_width = 0;
234fa27c
AM
1323 if (operand.reg != REG_PC)
1324 as_bad (_(": expected register name pc "));
f6c1a2d5
NC
1325 break;
1326
1327 case 'b': /* Branch expected. */
f6c1a2d5
NC
1328 (*op_con)++;
1329 op_constraint++;
f6c1a2d5 1330
8d8ad4eb 1331 if (operand.exp.X_op != O_register)
234fa27c
AM
1332 {
1333 if (*op_constraint == '9')
1334 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1335 R_XGATE_PCREL_9);
1336 else if (*op_constraint == 'a')
1337 fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1338 R_XGATE_PCREL_10);
1339 }
3879925e 1340 else
234fa27c
AM
1341 as_fatal (_("Operand `%x' not recognized in fixup8."),
1342 operand.exp.X_op);
3879925e
SK
1343 break;
1344 case '?':
1345 break;
fe540416 1346
3879925e
SK
1347 default:
1348 as_bad (_("unknown constraint `%c'"), *op_constraint);
1349 break;
1350 }
1351 return op_mask;
fe540416 1352}
This page took 0.151836 seconds and 4 git commands to generate.