Based on notes from Peter Eriksson <peter@ifm.liu.se>. The target
[deliverable/binutils-gdb.git] / gas / config / tc-mn10300.c
CommitLineData
ae1b99e4 1/* tc-mn10300.c -- Assembler code for the Matsushita 10300
0f91d763
JL
2
3 Copyright (C) 1996 Free Software Foundation.
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 2, 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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include <stdio.h>
23#include <ctype.h>
24#include "as.h"
25#include "subsegs.h"
ae1b99e4 26#include "opcode/mn10300.h"
0f91d763
JL
27\f
28/* Structure to hold information about predefined registers. */
29struct reg_name
30{
31 const char *name;
32 int value;
33};
34
35/* Generic assembler global variables which must be defined by all targets. */
36
37/* Characters which always start a comment. */
38const char comment_chars[] = "#";
39
40/* Characters which start a comment at the beginning of a line. */
41const char line_comment_chars[] = ";#";
42
43/* Characters which may be used to separate multiple commands on a
44 single line. */
45const char line_separator_chars[] = ";";
46
47/* Characters which are used to indicate an exponent in a floating
48 point number. */
49const char EXP_CHARS[] = "eE";
50
51/* Characters which mean that a number is a floating point constant,
52 as in 0d1.0. */
53const char FLT_CHARS[] = "dD";
54\f
55
56/* local functions */
43d695a1
JL
57static void mn10300_insert_operand PARAMS ((unsigned long *, unsigned long *,
58 const struct mn10300_operand *,
59 offsetT, char *, unsigned,
60 unsigned));
61static unsigned long check_operand PARAMS ((unsigned long,
62 const struct mn10300_operand *,
63 offsetT));
0f91d763 64static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
ca82e4eb
JL
65static boolean data_register_name PARAMS ((expressionS *expressionP));
66static boolean address_register_name PARAMS ((expressionS *expressionP));
67static boolean other_register_name PARAMS ((expressionS *expressionP));
0f91d763
JL
68
69
70/* fixups */
71#define MAX_INSN_FIXUPS (5)
ae1b99e4 72struct mn10300_fixup
0f91d763
JL
73{
74 expressionS exp;
75 int opindex;
76 bfd_reloc_code_real_type reloc;
77};
ae1b99e4 78struct mn10300_fixup fixups[MAX_INSN_FIXUPS];
0f91d763
JL
79static int fc;
80\f
81const char *md_shortopts = "";
82struct option md_longopts[] = {
83 {NULL, no_argument, NULL, 0}
84};
85size_t md_longopts_size = sizeof(md_longopts);
86
87/* The target specific pseudo-ops which we support. */
88const pseudo_typeS md_pseudo_table[] =
89{
90 { NULL, NULL, 0 }
91};
92
93/* Opcode hash table. */
ae1b99e4 94static struct hash_control *mn10300_hash;
0f91d763
JL
95
96/* This table is sorted. Suitable for searching by a binary search. */
1217102f 97static const struct reg_name data_registers[] =
0f91d763 98{
ca82e4eb
JL
99 { "d0", 0 },
100 { "d1", 1 },
101 { "d2", 2 },
102 { "d3", 3 },
0f91d763 103};
1217102f 104#define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
0f91d763 105
1217102f 106static const struct reg_name address_registers[] =
0f91d763 107{
ca82e4eb
JL
108 { "a0", 0 },
109 { "a1", 1 },
110 { "a2", 2 },
111 { "a3", 3 },
0f91d763 112};
1217102f 113#define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
0f91d763 114
1217102f 115static const struct reg_name other_registers[] =
0f91d763 116{
ca82e4eb
JL
117 { "mdr", 0 },
118 { "psw", 0 },
119 { "sp", 0 },
0f91d763 120};
1217102f 121#define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
0f91d763
JL
122
123/* reg_name_search does a binary search of the given register table
124 to see if "name" is a valid regiter name. Returns the register
125 number from the array on success, or -1 on failure. */
126
127static int
128reg_name_search (regs, regcount, name)
129 const struct reg_name *regs;
130 int regcount;
131 const char *name;
132{
133 int middle, low, high;
134 int cmp;
135
136 low = 0;
137 high = regcount - 1;
138
139 do
140 {
141 middle = (low + high) / 2;
142 cmp = strcasecmp (name, regs[middle].name);
143 if (cmp < 0)
144 high = middle - 1;
145 else if (cmp > 0)
146 low = middle + 1;
147 else
148 return regs[middle].value;
149 }
150 while (low <= high);
151 return -1;
152}
153
154
155/* Summary of register_name().
156 *
157 * in: Input_line_pointer points to 1st char of operand.
158 *
159 * out: A expressionS.
160 * The operand may have been a register: in this case, X_op == O_register,
161 * X_add_number is set to the register number, and truth is returned.
162 * Input_line_pointer->(next non-blank) char after operand, or is in
163 * its original state.
164 */
165static boolean
1217102f 166data_register_name (expressionP)
0f91d763
JL
167 expressionS *expressionP;
168{
169 int reg_number;
170 char *name;
171 char *start;
172 char c;
173
174 /* Find the spelling of the operand */
175 start = name = input_line_pointer;
176
177 c = get_symbol_end ();
1217102f 178 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
0f91d763
JL
179
180 /* look to see if it's in the register table */
181 if (reg_number >= 0)
182 {
183 expressionP->X_op = O_register;
184 expressionP->X_add_number = reg_number;
185
186 /* make the rest nice */
187 expressionP->X_add_symbol = NULL;
188 expressionP->X_op_symbol = NULL;
189 *input_line_pointer = c; /* put back the delimiting char */
190 return true;
191 }
192 else
193 {
194 /* reset the line as if we had not done anything */
195 *input_line_pointer = c; /* put back the delimiting char */
196 input_line_pointer = start; /* reset input_line pointer */
197 return false;
198 }
199}
200
1217102f 201/* Summary of register_name().
0f91d763
JL
202 *
203 * in: Input_line_pointer points to 1st char of operand.
204 *
205 * out: A expressionS.
206 * The operand may have been a register: in this case, X_op == O_register,
207 * X_add_number is set to the register number, and truth is returned.
208 * Input_line_pointer->(next non-blank) char after operand, or is in
209 * its original state.
210 */
211static boolean
1217102f 212address_register_name (expressionP)
0f91d763
JL
213 expressionS *expressionP;
214{
215 int reg_number;
216 char *name;
217 char *start;
218 char c;
219
220 /* Find the spelling of the operand */
221 start = name = input_line_pointer;
222
223 c = get_symbol_end ();
1217102f 224 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
0f91d763
JL
225
226 /* look to see if it's in the register table */
227 if (reg_number >= 0)
228 {
229 expressionP->X_op = O_register;
230 expressionP->X_add_number = reg_number;
231
232 /* make the rest nice */
233 expressionP->X_add_symbol = NULL;
234 expressionP->X_op_symbol = NULL;
235 *input_line_pointer = c; /* put back the delimiting char */
236 return true;
237 }
238 else
239 {
240 /* reset the line as if we had not done anything */
241 *input_line_pointer = c; /* put back the delimiting char */
242 input_line_pointer = start; /* reset input_line pointer */
243 return false;
244 }
245}
246
1217102f 247/* Summary of register_name().
0f91d763
JL
248 *
249 * in: Input_line_pointer points to 1st char of operand.
250 *
251 * out: A expressionS.
252 * The operand may have been a register: in this case, X_op == O_register,
253 * X_add_number is set to the register number, and truth is returned.
254 * Input_line_pointer->(next non-blank) char after operand, or is in
255 * its original state.
256 */
257static boolean
1217102f 258other_register_name (expressionP)
0f91d763
JL
259 expressionS *expressionP;
260{
261 int reg_number;
262 char *name;
263 char *start;
264 char c;
265
266 /* Find the spelling of the operand */
267 start = name = input_line_pointer;
268
269 c = get_symbol_end ();
1217102f 270 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
0f91d763
JL
271
272 /* look to see if it's in the register table */
273 if (reg_number >= 0)
274 {
1217102f 275 expressionP->X_op = O_register;
0f91d763
JL
276 expressionP->X_add_number = reg_number;
277
278 /* make the rest nice */
279 expressionP->X_add_symbol = NULL;
280 expressionP->X_op_symbol = NULL;
281 *input_line_pointer = c; /* put back the delimiting char */
282 return true;
283 }
284 else
285 {
286 /* reset the line as if we had not done anything */
287 *input_line_pointer = c; /* put back the delimiting char */
288 input_line_pointer = start; /* reset input_line pointer */
289 return false;
290 }
291}
292
293void
294md_show_usage (stream)
295 FILE *stream;
296{
ae1b99e4 297 fprintf(stream, "MN10300 options:\n\
0f91d763
JL
298none yet\n");
299}
300
301int
302md_parse_option (c, arg)
303 int c;
304 char *arg;
305{
306 return 0;
307}
308
309symbolS *
310md_undefined_symbol (name)
311 char *name;
312{
313 return 0;
314}
315
316char *
317md_atof (type, litp, sizep)
318 int type;
319 char *litp;
320 int *sizep;
321{
322 int prec;
323 LITTLENUM_TYPE words[4];
324 char *t;
325 int i;
326
327 switch (type)
328 {
329 case 'f':
330 prec = 2;
331 break;
332
333 case 'd':
334 prec = 4;
335 break;
336
337 default:
338 *sizep = 0;
339 return "bad call to md_atof";
340 }
341
342 t = atof_ieee (input_line_pointer, type, words);
343 if (t)
344 input_line_pointer = t;
345
346 *sizep = prec * 2;
347
348 for (i = prec - 1; i >= 0; i--)
349 {
350 md_number_to_chars (litp, (valueT) words[i], 2);
351 litp += 2;
352 }
353
354 return NULL;
355}
356
357
358void
359md_convert_frag (abfd, sec, fragP)
360 bfd *abfd;
361 asection *sec;
362 fragS *fragP;
363{
364 /* printf ("call to md_convert_frag \n"); */
365 abort ();
366}
367
368valueT
369md_section_align (seg, addr)
370 asection *seg;
371 valueT addr;
372{
373 int align = bfd_get_section_alignment (stdoutput, seg);
374 return ((addr + (1 << align) - 1) & (-1 << align));
375}
376
377void
378md_begin ()
379{
380 char *prev_name = "";
ae1b99e4 381 register const struct mn10300_opcode *op;
0f91d763 382
ae1b99e4 383 mn10300_hash = hash_new();
0f91d763 384
ae1b99e4 385 /* Insert unique names into hash table. The MN10300 instruction set
0f91d763
JL
386 has many identical opcode names that have different opcodes based
387 on the operands. This hash table then provides a quick index to
388 the first opcode with a particular name in the opcode table. */
389
d9a9c18f 390 op = mn10300_opcodes;
0f91d763
JL
391 while (op->name)
392 {
393 if (strcmp (prev_name, op->name))
394 {
395 prev_name = (char *) op->name;
ae1b99e4 396 hash_insert (mn10300_hash, op->name, (char *) op);
0f91d763
JL
397 }
398 op++;
399 }
d9a9c18f
JL
400
401 /* This is both a simplification (we don't have to write md_apply_fix)
402 and support for future optimizations (branch shortening and similar
403 stuff in the linker. */
404 linkrelax = 1;
0f91d763
JL
405}
406
0f91d763
JL
407void
408md_assemble (str)
409 char *str;
410{
411 char *s;
ae1b99e4
JL
412 struct mn10300_opcode *opcode;
413 struct mn10300_opcode *next_opcode;
0f91d763
JL
414 const unsigned char *opindex_ptr;
415 int next_opindex;
ca82e4eb 416 unsigned long insn, extension, size = 0;
0f91d763
JL
417 char *f;
418 int i;
419 int match;
0f91d763
JL
420
421 /* Get the opcode. */
422 for (s = str; *s != '\0' && ! isspace (*s); s++)
423 ;
424 if (*s != '\0')
425 *s++ = '\0';
426
427 /* find the first opcode with the proper name */
ae1b99e4 428 opcode = (struct mn10300_opcode *)hash_find (mn10300_hash, str);
0f91d763
JL
429 if (opcode == NULL)
430 {
431 as_bad ("Unrecognized opcode: `%s'", str);
432 return;
433 }
434
435 str = s;
436 while (isspace (*str))
437 ++str;
438
439 input_line_pointer = str;
440
441 for(;;)
442 {
443 const char *errmsg = NULL;
1217102f 444 int op_idx;
1217102f 445 char *hold;
68328dc6 446 int extra_shift = 0;
0f91d763
JL
447
448 fc = 0;
449 match = 0;
450 next_opindex = 0;
451 insn = opcode->opcode;
bfe5059c 452 extension = 0;
1217102f
JL
453 for (op_idx = 1, opindex_ptr = opcode->operands;
454 *opindex_ptr != 0;
455 opindex_ptr++, op_idx++)
0f91d763 456 {
ae1b99e4 457 const struct mn10300_operand *operand;
0f91d763
JL
458 expressionS ex;
459
460 if (next_opindex == 0)
461 {
ae1b99e4 462 operand = &mn10300_operands[*opindex_ptr];
0f91d763
JL
463 }
464 else
465 {
ae1b99e4 466 operand = &mn10300_operands[next_opindex];
0f91d763
JL
467 next_opindex = 0;
468 }
469
470 errmsg = NULL;
471
7f02192d 472 while (*str == ' ' || *str == ',')
0f91d763
JL
473 ++str;
474
475 /* Gather the operand. */
476 hold = input_line_pointer;
477 input_line_pointer = str;
478
a6be605a
JL
479 if (operand->flags & MN10300_OPERAND_PAREN)
480 {
481 if (*input_line_pointer != ')' && *input_line_pointer != '(')
482 {
483 input_line_pointer = hold;
484 str = hold;
485 goto error;
486 }
1217102f 487 input_line_pointer++;
a6be605a 488 goto keep_going;
1217102f 489 }
1217102f 490 /* See if we can match the operands. */
a6be605a 491 else if (operand->flags & MN10300_OPERAND_DREG)
0f91d763 492 {
1217102f 493 if (!data_register_name (&ex))
0f91d763 494 {
1217102f
JL
495 input_line_pointer = hold;
496 str = hold;
0f91d763
JL
497 goto error;
498 }
1217102f
JL
499 }
500 else if (operand->flags & MN10300_OPERAND_AREG)
501 {
502 if (!address_register_name (&ex))
0f91d763 503 {
1217102f
JL
504 input_line_pointer = hold;
505 str = hold;
506 goto error;
0f91d763 507 }
1217102f
JL
508 }
509 else if (operand->flags & MN10300_OPERAND_SP)
510 {
511 char *start = input_line_pointer;
512 char c = get_symbol_end ();
513
514 if (strcmp (start, "sp") != 0)
515 {
516 *input_line_pointer = c;
517 input_line_pointer = hold;
518 str = hold;
519 goto error;
520 }
521 *input_line_pointer = c;
522 goto keep_going;
523 }
524 else if (operand->flags & MN10300_OPERAND_PSW)
525 {
526 char *start = input_line_pointer;
527 char c = get_symbol_end ();
528
529 if (strcmp (start, "psw") != 0)
0f91d763 530 {
1217102f
JL
531 *input_line_pointer = c;
532 input_line_pointer = hold;
533 str = hold;
534 goto error;
535 }
536 *input_line_pointer = c;
537 goto keep_going;
538 }
539 else if (operand->flags & MN10300_OPERAND_MDR)
540 {
541 char *start = input_line_pointer;
542 char c = get_symbol_end ();
0f91d763 543
1217102f
JL
544 if (strcmp (start, "mdr") != 0)
545 {
546 *input_line_pointer = c;
547 input_line_pointer = hold;
548 str = hold;
549 goto error;
0f91d763 550 }
1217102f
JL
551 *input_line_pointer = c;
552 goto keep_going;
553 }
7f02192d
JL
554 else if (operand->flags & MN10300_OPERAND_REG_LIST)
555 {
556 unsigned int value = 0;
557 if (*input_line_pointer != '[')
558 {
559 input_line_pointer = hold;
560 str = hold;
561 goto error;
562 }
563
564 /* Eat the '['. */
565 input_line_pointer++;
566
567 /* A null register list can not be specified. */
568 if (*input_line_pointer == ']')
569 {
570 input_line_pointer = hold;
571 str = hold;
572 goto error;
573 }
574
575 while (*input_line_pointer != ']')
576 {
577 char *start;
578 char c;
579
580 if (*input_line_pointer == ',')
581 input_line_pointer++;
582
583 start = input_line_pointer;
584 c = get_symbol_end ();
585
ca82e4eb 586 if (strcmp (start, "d2") == 0)
7f02192d
JL
587 {
588 value |= 0x80;
589 *input_line_pointer = c;
590 }
ca82e4eb 591 else if (strcmp (start, "d3") == 0)
7f02192d
JL
592 {
593 value |= 0x40;
594 *input_line_pointer = c;
595 }
ca82e4eb 596 else if (strcmp (start, "a2") == 0)
7f02192d
JL
597 {
598 value |= 0x20;
599 *input_line_pointer = c;
600 }
ca82e4eb 601 else if (strcmp (start, "a3") == 0)
7f02192d
JL
602 {
603 value |= 0x10;
604 *input_line_pointer = c;
605 }
ca82e4eb 606 else if (strcmp (start, "other") == 0)
7f02192d
JL
607 {
608 value |= 0x08;
609 *input_line_pointer = c;
610 }
611 else
612 {
613 input_line_pointer = hold;
614 str = hold;
615 goto error;
616 }
617 }
618 input_line_pointer++;
619 mn10300_insert_operand (&insn, &extension, operand,
620 value, (char *) NULL, 0, 0);
621 goto keep_going;
622
623 }
1217102f
JL
624 else if (data_register_name (&ex))
625 {
626 input_line_pointer = hold;
627 str = hold;
628 goto error;
629 }
630 else if (address_register_name (&ex))
631 {
632 input_line_pointer = hold;
633 str = hold;
634 goto error;
635 }
636 else if (other_register_name (&ex))
637 {
638 input_line_pointer = hold;
639 str = hold;
640 goto error;
0f91d763 641 }
a6be605a
JL
642 else if (*str == ')' || *str == '(')
643 {
644 input_line_pointer = hold;
645 str = hold;
646 goto error;
647 }
0f91d763
JL
648 else
649 {
1217102f
JL
650 expression (&ex);
651 }
652
0f91d763
JL
653 switch (ex.X_op)
654 {
655 case O_illegal:
656 errmsg = "illegal operand";
657 goto error;
658 case O_absent:
659 errmsg = "missing operand";
660 goto error;
661 case O_register:
ca82e4eb
JL
662 if ((operand->flags
663 & (MN10300_OPERAND_DREG | MN10300_OPERAND_AREG)) == 0)
1217102f
JL
664 {
665 input_line_pointer = hold;
666 str = hold;
667 goto error;
668 }
0f91d763 669
68328dc6
JL
670 if (opcode->format == FMT_D1 || opcode->format == FMT_S1)
671 extra_shift = 8;
672 else if (opcode->format == FMT_D2 || opcode->format == FMT_D4
673 || opcode->format == FMT_S2 || opcode->format == FMT_S4
674 || opcode->format == FMT_S6 || opcode->format == FMT_D5)
675 extra_shift = 16;
676 else
677 extra_shift = 0;
678
bfe5059c
JL
679 mn10300_insert_operand (&insn, &extension, operand,
680 ex.X_add_number, (char *) NULL,
681 0, extra_shift);
68328dc6 682
0f91d763
JL
683 break;
684
685 case O_constant:
1217102f
JL
686 /* If this operand can be promoted, and it doesn't
687 fit into the allocated bitfield for this insn,
688 then promote it (ie this opcode does not match). */
689 if (operand->flags & MN10300_OPERAND_PROMOTE
690 && ! check_operand (insn, operand, ex.X_add_number))
691 {
692 input_line_pointer = hold;
693 str = hold;
694 goto error;
695 }
696
bfe5059c
JL
697 mn10300_insert_operand (&insn, &extension, operand,
698 ex.X_add_number, (char *) NULL,
699 0, 0);
0f91d763
JL
700 break;
701
702 default:
1217102f
JL
703 /* If this operand can be promoted, then this opcode didn't
704 match since we can't know if it needed promotion! */
705 if (operand->flags & MN10300_OPERAND_PROMOTE)
706 {
707 input_line_pointer = hold;
708 str = hold;
709 goto error;
710 }
711
0f91d763
JL
712 /* We need to generate a fixup for this expression. */
713 if (fc >= MAX_INSN_FIXUPS)
714 as_fatal ("too many fixups");
715 fixups[fc].exp = ex;
716 fixups[fc].opindex = *opindex_ptr;
717 fixups[fc].reloc = BFD_RELOC_UNUSED;
718 ++fc;
719 break;
720 }
721
1217102f 722keep_going:
0f91d763
JL
723 str = input_line_pointer;
724 input_line_pointer = hold;
725
7f02192d 726 while (*str == ' ' || *str == ',')
0f91d763 727 ++str;
1217102f 728
1217102f 729 }
a6be605a
JL
730
731 /* Make sure we used all the operands! */
732 if (*str != ',')
1217102f 733 match = 1;
0f91d763
JL
734
735 error:
736 if (match == 0)
737 {
738 next_opcode = opcode + 1;
42aa2435 739 if (!strcmp(next_opcode->name, opcode->name))
0f91d763
JL
740 {
741 opcode = next_opcode;
742 continue;
743 }
744
745 as_bad ("%s", errmsg);
746 return;
747 }
748 break;
749 }
750
751 while (isspace (*str))
752 ++str;
753
754 if (*str != '\0')
755 as_bad ("junk at end of line: `%s'", str);
756
757 input_line_pointer = str;
758
778c521b
JL
759 /* Determine the size of the instruction. */
760 if (opcode->format == FMT_S0)
1217102f 761 size = 1;
0f91d763 762
778c521b 763 if (opcode->format == FMT_S1 || opcode->format == FMT_D0)
0f91d763 764 size = 2;
0f91d763 765
778c521b 766 if (opcode->format == FMT_S2 || opcode->format == FMT_D1)
1217102f 767 size = 3;
0f91d763 768
778c521b 769 if (opcode->format == FMT_S4)
1217102f 770 size = 5;
0f91d763 771
778c521b 772 if (opcode->format == FMT_S6 || opcode->format == FMT_D5)
1217102f 773 size = 7;
0f91d763 774
778c521b 775 if (opcode->format == FMT_D2)
1217102f 776 size = 4;
0f91d763 777
778c521b 778 if (opcode->format == FMT_D4)
1217102f
JL
779 size = 6;
780
8ca71631 781 /* Allocate space for the instruction. */
1217102f 782 f = frag_more (size);
8ca71631
JL
783
784 /* Fill in bytes for the instruction. Note that opcode fields
785 are written big-endian, 16 & 32bit immediates are written
786 little endian. Egad. */
787 if (opcode->format == FMT_S0
788 || opcode->format == FMT_S1
789 || opcode->format == FMT_D0
790 || opcode->format == FMT_D1)
791 {
792 number_to_chars_bigendian (f, insn, size);
793 }
794 else if (opcode->format == FMT_S2
795 && opcode->opcode != 0xdf0000
796 && opcode->opcode != 0xde0000)
797 {
798 /* A format S2 instruction that is _not_ "ret" and "retf". */
799 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
800 number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
801 }
802 else if (opcode->format == FMT_S2)
803 {
804 /* This must be a ret or retf, which is written entirely in big-endian
805 format. */
806 number_to_chars_bigendian (f, insn, 3);
807 }
808 else if (opcode->format == FMT_S4
809 && opcode->opcode != 0xdc000000)
810 {
811 /* This must be a format S4 "call" instruction. What a pain. */
812 unsigned long temp = (insn >> 8) & 0xffff;
813 number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
814 number_to_chars_littleendian (f + 1, temp, 2);
815 number_to_chars_bigendian (f + 3, insn & 0xff, 1);
816 number_to_chars_bigendian (f + 4, extension & 0xff, 1);
817 }
818 else if (opcode->format == FMT_S4)
819 {
820 /* This must be a format S4 "jmp" instruction. */
821 unsigned long temp = ((insn & 0xffffff) << 8) | (extension & 0xff);
822 number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
823 number_to_chars_littleendian (f + 1, temp, 4);
824 }
825 else if (opcode->format == FMT_S6)
826 {
827 unsigned long temp = ((insn & 0xffffff) << 8)
828 | ((extension >> 16) & 0xff);
829 number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
830 number_to_chars_littleendian (f + 1, temp, 4);
831 number_to_chars_bigendian (f + 5, (extension >> 8) & 0xff, 1);
832 number_to_chars_bigendian (f + 6, extension & 0xff, 1);
833 }
834 else if (opcode->format == FMT_D2
835 && opcode->opcode != 0xfaf80000
836 && opcode->opcode != 0xfaf00000
837 && opcode->opcode != 0xfaf40000)
838 {
839 /* A format D2 instruction where the 16bit immediate is
840 really a single 16bit value, not two 8bit values. */
841 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
842 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
843 }
844 else if (opcode->format == FMT_D2)
845 {
846 /* A format D2 instruction where the 16bit immediate
847 is really two 8bit immediates. */
848 number_to_chars_bigendian (f, insn, 4);
849 }
850 else if (opcode->format == FMT_D4)
851 {
852 unsigned long temp = ((insn & 0xffff) << 16) | (extension & 0xffff);
853 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
854 number_to_chars_littleendian (f + 2, temp, 4);
855 }
856 else if (opcode->format == FMT_D5)
857 {
858 unsigned long temp = ((insn & 0xffff) << 16) | ((extension >> 8) & 0xffff);
859 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
860 number_to_chars_littleendian (f + 2, temp, 4);
861 number_to_chars_bigendian (f + 6, extension & 0xff, 1);
862 }
d9a9c18f
JL
863
864 /* Create any fixups. */
865 for (i = 0; i < fc; i++)
866 {
867 const struct mn10300_operand *operand;
868
869 operand = &mn10300_operands[fixups[i].opindex];
870 if (fixups[i].reloc != BFD_RELOC_UNUSED)
871 {
872 reloc_howto_type *reloc_howto;
873 int size;
874 int offset;
875 fixS *fixP;
876
877 reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
878
879 if (!reloc_howto)
880 abort();
881
882 size = bfd_get_reloc_size (reloc_howto);
883
884 if (size < 1 || size > 4)
885 abort();
886
887 offset = 4 - size;
888 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, size,
889 &fixups[i].exp,
890 reloc_howto->pc_relative,
891 fixups[i].reloc);
892 }
893 else
894 {
895 int reloc, pcrel, reloc_size, offset;
896
ca82e4eb 897 reloc = BFD_RELOC_NONE;
d9a9c18f
JL
898 /* How big is the reloc? Remember SPLIT relocs are
899 implicitly 32bits. */
900 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
901 reloc_size = 32;
902 else
903 reloc_size = operand->bits;
904
905 /* Is the reloc pc-relative? */
906 pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
907
908 /* Gross. This disgusting hack is to make sure we
909 get the right offset for the 16/32 bit reloc in
910 "call" instructions. Basically they're a pain
911 because the reloc isn't at the end of the instruction. */
912 if ((size == 5 || size == 7)
913 && (((insn >> 24) & 0xff) == 0xcd
914 || ((insn >> 24) & 0xff) == 0xdd))
915 size -= 2;
916
917 /* Similarly for certain bit instructions which don't
918 hav their 32bit reloc at the tail of the instruction. */
919 if (size == 7
920 && (((insn >> 16) & 0xffff) == 0xfe00
921 || ((insn >> 16) & 0xffff) == 0xfe01
922 || ((insn >> 16) & 0xffff) == 0xfe02))
923 size -= 1;
924
d9a9c18f
JL
925 offset = size - reloc_size / 8;
926
927 /* Choose a proper BFD relocation type. */
928 if (pcrel)
929 {
0671e7f6
JL
930 if (size == 6)
931 reloc = BFD_RELOC_MN10300_32_PCREL;
932 else if (size == 4)
933 reloc = BFD_RELOC_MN10300_16_PCREL;
934 else if (reloc_size == 32)
d9a9c18f
JL
935 reloc = BFD_RELOC_32_PCREL;
936 else if (reloc_size == 16)
937 reloc = BFD_RELOC_16_PCREL;
938 else if (reloc_size == 8)
939 reloc = BFD_RELOC_8_PCREL;
940 else
941 abort ();
942 }
943 else
944 {
945 if (reloc_size == 32)
8ca71631 946 reloc = BFD_RELOC_32
d9a9c18f 947 else if (reloc_size == 16)
8ca71631 948 reloc = BFD_RELOC_16
d9a9c18f
JL
949 else if (reloc_size == 8)
950 reloc = BFD_RELOC_8;
951 else
952 abort ();
953 }
954
955 /* Convert the size of the reloc into what fix_new_exp wants. */
956 reloc_size = reloc_size / 8;
957 if (reloc_size == 8)
958 reloc_size = 0;
959 else if (reloc_size == 16)
960 reloc_size = 1;
961 else if (reloc_size == 32)
962 reloc_size = 2;
963
964 fix_new_exp (frag_now, f - frag_now->fr_literal + offset, reloc_size,
965 &fixups[i].exp, pcrel,
966 ((bfd_reloc_code_real_type) reloc));
967 }
968 }
0f91d763
JL
969}
970
971
972/* if while processing a fixup, a reloc really needs to be created */
973/* then it is done here */
974
975arelent *
976tc_gen_reloc (seg, fixp)
977 asection *seg;
978 fixS *fixp;
979{
980 arelent *reloc;
981 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
982 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
983 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
984 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
985 if (reloc->howto == (reloc_howto_type *) NULL)
986 {
987 as_bad_where (fixp->fx_file, fixp->fx_line,
988 "reloc %d not supported by object file format", (int)fixp->fx_r_type);
989 return NULL;
990 }
ca82e4eb 991 reloc->addend = fixp->fx_offset;
0f91d763
JL
992 /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
993 return reloc;
994}
995
996int
997md_estimate_size_before_relax (fragp, seg)
998 fragS *fragp;
999 asection *seg;
1000{
1001 return 0;
1002}
1003
1004long
1005md_pcrel_from (fixp)
1006 fixS *fixp;
1007{
0671e7f6
JL
1008 return fixp->fx_frag->fr_address;
1009#if 0
0f91d763
JL
1010 if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
1011 {
1012 /* The symbol is undefined. Let the linker figure it out. */
1013 return 0;
1014 }
1015 return fixp->fx_frag->fr_address + fixp->fx_where;
0671e7f6 1016#endif
0f91d763
JL
1017}
1018
1019int
1020md_apply_fix3 (fixp, valuep, seg)
1021 fixS *fixp;
1022 valueT *valuep;
1023 segT seg;
1024{
d9a9c18f
JL
1025 /* We shouldn't ever get here because linkrelax is nonzero. */
1026 abort ();
1217102f
JL
1027 fixp->fx_done = 1;
1028 return 0;
0f91d763
JL
1029}
1030
0f91d763
JL
1031/* Insert an operand value into an instruction. */
1032
bfe5059c
JL
1033static void
1034mn10300_insert_operand (insnp, extensionp, operand, val, file, line, shift)
1035 unsigned long *insnp;
1036 unsigned long *extensionp;
ae1b99e4 1037 const struct mn10300_operand *operand;
0f91d763
JL
1038 offsetT val;
1039 char *file;
1040 unsigned int line;
68328dc6 1041 unsigned int shift;
0f91d763 1042{
43d695a1
JL
1043 /* No need to check 32bit operands for a bit. Note that
1044 MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
1045 if (operand->bits != 32
1046 && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
0f91d763
JL
1047 {
1048 long min, max;
1049 offsetT test;
1050
1217102f
JL
1051 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
1052 {
1053 max = (1 << (operand->bits - 1)) - 1;
1054 min = - (1 << (operand->bits - 1));
1055 }
1056 else
0f91d763
JL
1057 {
1058 max = (1 << operand->bits) - 1;
1059 min = 0;
1060 }
1061
1062 test = val;
1063
1064
1065 if (test < (offsetT) min || test > (offsetT) max)
1066 {
1067 const char *err =
1068 "operand out of range (%s not between %ld and %ld)";
1069 char buf[100];
1070
1071 sprint_value (buf, test);
1072 if (file == (char *) NULL)
1073 as_warn (err, buf, min, max);
1074 else
1075 as_warn_where (file, line, err, buf, min, max);
1076 }
1077 }
1078
cdde2f5c
JL
1079 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
1080 {
ca82e4eb 1081 *insnp |= (val >> (32 - operand->bits)) & ((1 << operand->bits) - 1);
43d695a1
JL
1082 *extensionp |= ((val & ((1 << (32 - operand->bits)) - 1))
1083 << operand->shift);
cdde2f5c
JL
1084 }
1085 else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0)
bfe5059c
JL
1086 {
1087 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1088 << (operand->shift + shift));
1089
1090 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1091 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1092 << (operand->shift + shift + 2));
1093 }
1094 else
1095 {
1096 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1097 << (operand->shift + shift));
68328dc6 1098
bfe5059c
JL
1099 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1100 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1101 << (operand->shift + shift + 2));
1102 }
0f91d763 1103}
1217102f
JL
1104
1105static unsigned long
1106check_operand (insn, operand, val)
1107 unsigned long insn;
1108 const struct mn10300_operand *operand;
1109 offsetT val;
1110{
43d695a1
JL
1111 /* No need to check 32bit operands for a bit. Note that
1112 MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
1113 if (operand->bits != 32
1114 && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
1217102f
JL
1115 {
1116 long min, max;
1117 offsetT test;
1118
1119 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
1120 {
1121 max = (1 << (operand->bits - 1)) - 1;
1122 min = - (1 << (operand->bits - 1));
1123 }
1124 else
1125 {
1126 max = (1 << operand->bits) - 1;
1127 min = 0;
1128 }
1129
1130 test = val;
1131
1132
1133 if (test < (offsetT) min || test > (offsetT) max)
1134 return 0;
1135 else
1136 return 1;
1137 }
1138 return 1;
1139}
This page took 0.083782 seconds and 4 git commands to generate.