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