1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2    Copyright (C) 1996-2014 Free Software Foundation, Inc.
3 
4    This file is part of GAS, the GNU Assembler.
5 
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19    Boston, MA 02110-1301, USA.  */
20 
21 #include "as.h"
22 #include "safe-ctype.h"
23 #include "subsegs.h"
24 #include "opcode/mn10200.h"
25 
26 /* Structure to hold information about predefined registers.  */
27 struct reg_name
28 {
29   const char *name;
30   int value;
31 };
32 
33 /* Generic assembler global variables which must be defined by all
34    targets.  */
35 
36 /* Characters which always start a comment.  */
37 const char comment_chars[] = "#";
38 
39 /* Characters which start a comment at the beginning of a line.  */
40 const char line_comment_chars[] = ";#";
41 
42 /* Characters which may be used to separate multiple commands on a
43    single line.  */
44 const char line_separator_chars[] = ";";
45 
46 /* Characters which are used to indicate an exponent in a floating
47    point number.  */
48 const char EXP_CHARS[] = "eE";
49 
50 /* Characters which mean that a number is a floating point constant,
51    as in 0d1.0.  */
52 const char FLT_CHARS[] = "dD";
53 
54 const relax_typeS md_relax_table[] =
55  {
56   /* bCC relaxing  */
57   {0x81, -0x7e, 2, 1},
58   {0x8004, -0x7ffb, 5, 2},
59   {0x800006, -0x7ffff9, 7, 0},
60   /* bCCx relaxing  */
61   {0x81, -0x7e, 3, 4},
62   {0x8004, -0x7ffb, 6, 5},
63   {0x800006, -0x7ffff9, 8, 0},
64   /* jsr relaxing  */
65   {0x8004, -0x7ffb, 3, 7},
66   {0x800006, -0x7ffff9, 5, 0},
67   /* jmp relaxing  */
68   {0x81, -0x7e, 2, 9},
69   {0x8004, -0x7ffb, 3, 10},
70   {0x800006, -0x7ffff9, 5, 0},
71 
72 };
73 
74 
75 /* Fixups.  */
76 #define MAX_INSN_FIXUPS 5
77 
78 struct mn10200_fixup
79 {
80   expressionS exp;
81   int opindex;
82   bfd_reloc_code_real_type reloc;
83 };
84 
85 struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
86 static int fc;
87 
88 const char *md_shortopts = "";
89 
90 struct option md_longopts[] =
91 {
92   {NULL, no_argument, NULL, 0}
93 };
94 
95 size_t md_longopts_size = sizeof (md_longopts);
96 
97 /* The target specific pseudo-ops which we support.  */
98 const pseudo_typeS md_pseudo_table[] =
99 {
100   { NULL,       NULL,           0 }
101 };
102 
103 /* Opcode hash table.  */
104 static struct hash_control *mn10200_hash;
105 
106 /* This table is sorted. Suitable for searching by a binary search.  */
107 static const struct reg_name data_registers[] =
108 {
109   { "d0", 0 },
110   { "d1", 1 },
111   { "d2", 2 },
112   { "d3", 3 },
113 };
114 #define DATA_REG_NAME_CNT				\
115   (sizeof (data_registers) / sizeof (struct reg_name))
116 
117 static const struct reg_name address_registers[] =
118 {
119   { "a0", 0 },
120   { "a1", 1 },
121   { "a2", 2 },
122   { "a3", 3 },
123 };
124 #define ADDRESS_REG_NAME_CNT					\
125   (sizeof (address_registers) / sizeof (struct reg_name))
126 
127 static const struct reg_name other_registers[] =
128 {
129   { "mdr", 0 },
130   { "psw", 0 },
131 };
132 #define OTHER_REG_NAME_CNT				\
133   (sizeof (other_registers) / sizeof (struct reg_name))
134 
135 /* reg_name_search does a binary search of the given register table
136    to see if "name" is a valid regiter name.  Returns the register
137    number from the array on success, or -1 on failure.  */
138 
139 static int
reg_name_search(const struct reg_name * regs,int regcount,const char * name)140 reg_name_search (const struct reg_name *regs,
141 		 int regcount,
142 		 const char *name)
143 {
144   int middle, low, high;
145   int cmp;
146 
147   low = 0;
148   high = regcount - 1;
149 
150   do
151     {
152       middle = (low + high) / 2;
153       cmp = strcasecmp (name, regs[middle].name);
154       if (cmp < 0)
155 	high = middle - 1;
156       else if (cmp > 0)
157 	low = middle + 1;
158       else
159 	return regs[middle].value;
160     }
161   while (low <= high);
162   return -1;
163 }
164 
165 /* Summary of register_name().
166 
167    in: Input_line_pointer points to 1st char of operand.
168 
169    out: An expressionS.
170   	The operand may have been a register: in this case, X_op == O_register,
171   	X_add_number is set to the register number, and truth is returned.
172   	Input_line_pointer->(next non-blank) char after operand, or is in
173   	its original state.  */
174 
175 static bfd_boolean
data_register_name(expressionS * expressionP)176 data_register_name (expressionS *expressionP)
177 {
178   int reg_number;
179   char *name;
180   char *start;
181   char c;
182 
183   /* Find the spelling of the operand.  */
184   start = name = input_line_pointer;
185 
186   c = get_symbol_end ();
187   reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
188 
189   /* Put back the delimiting char.  */
190   *input_line_pointer = c;
191 
192   /* Look to see if it's in the register table.  */
193   if (reg_number >= 0)
194     {
195       expressionP->X_op = O_register;
196       expressionP->X_add_number = reg_number;
197 
198       /* Make the rest nice.  */
199       expressionP->X_add_symbol = NULL;
200       expressionP->X_op_symbol = NULL;
201 
202       return TRUE;
203     }
204 
205   /* Reset the line as if we had not done anything.  */
206   input_line_pointer = start;
207   return FALSE;
208 }
209 
210 /* Summary of register_name().
211 
212    in: Input_line_pointer points to 1st char of operand.
213 
214    out: An expressionS.
215   	The operand may have been a register: in this case, X_op == O_register,
216   	X_add_number is set to the register number, and truth is returned.
217   	Input_line_pointer->(next non-blank) char after operand, or is in
218   	its original state.  */
219 
220 static bfd_boolean
address_register_name(expressionS * expressionP)221 address_register_name (expressionS *expressionP)
222 {
223   int reg_number;
224   char *name;
225   char *start;
226   char c;
227 
228   /* Find the spelling of the operand.  */
229   start = name = input_line_pointer;
230 
231   c = get_symbol_end ();
232   reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
233 
234   /* Put back the delimiting char.  */
235   *input_line_pointer = c;
236 
237   /* Look to see if it's in the register table.  */
238   if (reg_number >= 0)
239     {
240       expressionP->X_op = O_register;
241       expressionP->X_add_number = reg_number;
242 
243       /* Make the rest nice.  */
244       expressionP->X_add_symbol = NULL;
245       expressionP->X_op_symbol = NULL;
246 
247       return TRUE;
248     }
249 
250   /* Reset the line as if we had not done anything.  */
251   input_line_pointer = start;
252   return FALSE;
253 }
254 
255 /* Summary of register_name().
256 
257    in: Input_line_pointer points to 1st char of operand.
258 
259    out: An expressionS.
260   	The operand may have been a register: in this case, X_op == O_register,
261   	X_add_number is set to the register number, and truth is returned.
262   	Input_line_pointer->(next non-blank) char after operand, or is in
263   	its original state.  */
264 
265 static bfd_boolean
other_register_name(expressionS * expressionP)266 other_register_name (expressionS *expressionP)
267 {
268   int reg_number;
269   char *name;
270   char *start;
271   char c;
272 
273   /* Find the spelling of the operand.  */
274   start = name = input_line_pointer;
275 
276   c = get_symbol_end ();
277   reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
278 
279   /* Put back the delimiting char.  */
280   *input_line_pointer = c;
281 
282   /* Look to see if it's in the register table.  */
283   if (reg_number >= 0)
284     {
285       expressionP->X_op = O_register;
286       expressionP->X_add_number = reg_number;
287 
288       /* Make the rest nice.  */
289       expressionP->X_add_symbol = NULL;
290       expressionP->X_op_symbol = NULL;
291 
292       return TRUE;
293     }
294 
295   /* Reset the line as if we had not done anything.  */
296   input_line_pointer = start;
297   return FALSE;
298 }
299 
300 void
md_show_usage(FILE * stream)301 md_show_usage (FILE *stream)
302 {
303   fprintf (stream, _("MN10200 options:\n\
304 none yet\n"));
305 }
306 
307 int
md_parse_option(int c ATTRIBUTE_UNUSED,char * arg ATTRIBUTE_UNUSED)308 md_parse_option (int c ATTRIBUTE_UNUSED,
309 		 char *arg ATTRIBUTE_UNUSED)
310 {
311   return 0;
312 }
313 
314 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)315 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
316 {
317   return 0;
318 }
319 
320 char *
md_atof(int type,char * litp,int * sizep)321 md_atof (int type, char *litp, int *sizep)
322 {
323   return ieee_md_atof (type, litp, sizep, FALSE);
324 }
325 
326 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,fragS * fragP)327 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
328 		 asection *sec,
329 		 fragS *fragP)
330 {
331   static unsigned long label_count = 0;
332   char buf[40];
333 
334   subseg_change (sec, 0);
335   if (fragP->fr_subtype == 0)
336     {
337       fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
338 	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
339       fragP->fr_var = 0;
340       fragP->fr_fix += 2;
341     }
342   else if (fragP->fr_subtype == 1)
343     {
344       /* Reverse the condition of the first branch.  */
345       int offset = fragP->fr_fix;
346       int opcode = fragP->fr_literal[offset] & 0xff;
347 
348       switch (opcode)
349 	{
350 	case 0xe8:
351 	  opcode = 0xe9;
352 	  break;
353 	case 0xe9:
354 	  opcode = 0xe8;
355 	  break;
356 	case 0xe0:
357 	  opcode = 0xe2;
358 	  break;
359 	case 0xe2:
360 	  opcode = 0xe0;
361 	  break;
362 	case 0xe3:
363 	  opcode = 0xe1;
364 	  break;
365 	case 0xe1:
366 	  opcode = 0xe3;
367 	  break;
368 	case 0xe4:
369 	  opcode = 0xe6;
370 	  break;
371 	case 0xe6:
372 	  opcode = 0xe4;
373 	  break;
374 	case 0xe7:
375 	  opcode = 0xe5;
376 	  break;
377 	case 0xe5:
378 	  opcode = 0xe7;
379 	  break;
380 	default:
381 	  abort ();
382 	}
383       fragP->fr_literal[offset] = opcode;
384 
385       /* Create a fixup for the reversed conditional branch.  */
386       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
387       fix_new (fragP, fragP->fr_fix + 1, 1,
388 	       symbol_new (buf, sec, 0, fragP->fr_next),
389 	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
390 
391       /* Now create the unconditional branch + fixup to the
392 	 final target.  */
393       fragP->fr_literal[offset + 2] = 0xfc;
394       fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
395 	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
396       fragP->fr_var = 0;
397       fragP->fr_fix += 5;
398     }
399   else if (fragP->fr_subtype == 2)
400     {
401       /* Reverse the condition of the first branch.  */
402       int offset = fragP->fr_fix;
403       int opcode = fragP->fr_literal[offset] & 0xff;
404 
405       switch (opcode)
406 	{
407 	case 0xe8:
408 	  opcode = 0xe9;
409 	  break;
410 	case 0xe9:
411 	  opcode = 0xe8;
412 	  break;
413 	case 0xe0:
414 	  opcode = 0xe2;
415 	  break;
416 	case 0xe2:
417 	  opcode = 0xe0;
418 	  break;
419 	case 0xe3:
420 	  opcode = 0xe1;
421 	  break;
422 	case 0xe1:
423 	  opcode = 0xe3;
424 	  break;
425 	case 0xe4:
426 	  opcode = 0xe6;
427 	  break;
428 	case 0xe6:
429 	  opcode = 0xe4;
430 	  break;
431 	case 0xe7:
432 	  opcode = 0xe5;
433 	  break;
434 	case 0xe5:
435 	  opcode = 0xe7;
436 	  break;
437 	default:
438 	  abort ();
439 	}
440       fragP->fr_literal[offset] = opcode;
441 
442       /* Create a fixup for the reversed conditional branch.  */
443       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
444       fix_new (fragP, fragP->fr_fix + 1, 1,
445 	       symbol_new (buf, sec, 0, fragP->fr_next),
446 	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
447 
448       /* Now create the unconditional branch + fixup to the
449 	 final target.  */
450       fragP->fr_literal[offset + 2] = 0xf4;
451       fragP->fr_literal[offset + 3] = 0xe0;
452       fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
453 	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
454       fragP->fr_var = 0;
455       fragP->fr_fix += 7;
456     }
457   else if (fragP->fr_subtype == 3)
458     {
459       fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
460 	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
461       fragP->fr_var = 0;
462       fragP->fr_fix += 3;
463     }
464   else if (fragP->fr_subtype == 4)
465     {
466       /* Reverse the condition of the first branch.  */
467       int offset = fragP->fr_fix;
468       int opcode = fragP->fr_literal[offset + 1] & 0xff;
469 
470       switch (opcode)
471 	{
472 	case 0xfc:
473 	  opcode = 0xfd;
474 	  break;
475 	case 0xfd:
476 	  opcode = 0xfc;
477 	  break;
478 	case 0xfe:
479 	  opcode = 0xff;
480 	  break;
481 	case 0xff:
482 	  opcode = 0xfe;
483 	  break;
484 	case 0xe8:
485 	  opcode = 0xe9;
486 	  break;
487 	case 0xe9:
488 	  opcode = 0xe8;
489 	  break;
490 	case 0xe0:
491 	  opcode = 0xe2;
492 	  break;
493 	case 0xe2:
494 	  opcode = 0xe0;
495 	  break;
496 	case 0xe3:
497 	  opcode = 0xe1;
498 	  break;
499 	case 0xe1:
500 	  opcode = 0xe3;
501 	  break;
502 	case 0xe4:
503 	  opcode = 0xe6;
504 	  break;
505 	case 0xe6:
506 	  opcode = 0xe4;
507 	  break;
508 	case 0xe7:
509 	  opcode = 0xe5;
510 	  break;
511 	case 0xe5:
512 	  opcode = 0xe7;
513 	  break;
514 	case 0xec:
515 	  opcode = 0xed;
516 	  break;
517 	case 0xed:
518 	  opcode = 0xec;
519 	  break;
520 	case 0xee:
521 	  opcode = 0xef;
522 	  break;
523 	case 0xef:
524 	  opcode = 0xee;
525 	  break;
526 	default:
527 	  abort ();
528 	}
529       fragP->fr_literal[offset + 1] = opcode;
530 
531       /* Create a fixup for the reversed conditional branch.  */
532       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
533       fix_new (fragP, fragP->fr_fix + 2, 1,
534 	       symbol_new (buf, sec, 0, fragP->fr_next),
535 	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
536 
537       /* Now create the unconditional branch + fixup to the
538 	 final target.  */
539       fragP->fr_literal[offset + 3] = 0xfc;
540       fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
541 	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
542       fragP->fr_var = 0;
543       fragP->fr_fix += 6;
544     }
545   else if (fragP->fr_subtype == 5)
546     {
547       /* Reverse the condition of the first branch.  */
548       int offset = fragP->fr_fix;
549       int opcode = fragP->fr_literal[offset + 1] & 0xff;
550 
551       switch (opcode)
552 	{
553 	case 0xfc:
554 	  opcode = 0xfd;
555 	  break;
556 	case 0xfd:
557 	  opcode = 0xfc;
558 	  break;
559 	case 0xfe:
560 	  opcode = 0xff;
561 	  break;
562 	case 0xff:
563 	  opcode = 0xfe;
564 	  break;
565 	case 0xe8:
566 	  opcode = 0xe9;
567 	  break;
568 	case 0xe9:
569 	  opcode = 0xe8;
570 	  break;
571 	case 0xe0:
572 	  opcode = 0xe2;
573 	  break;
574 	case 0xe2:
575 	  opcode = 0xe0;
576 	  break;
577 	case 0xe3:
578 	  opcode = 0xe1;
579 	  break;
580 	case 0xe1:
581 	  opcode = 0xe3;
582 	  break;
583 	case 0xe4:
584 	  opcode = 0xe6;
585 	  break;
586 	case 0xe6:
587 	  opcode = 0xe4;
588 	  break;
589 	case 0xe7:
590 	  opcode = 0xe5;
591 	  break;
592 	case 0xe5:
593 	  opcode = 0xe7;
594 	  break;
595 	case 0xec:
596 	  opcode = 0xed;
597 	  break;
598 	case 0xed:
599 	  opcode = 0xec;
600 	  break;
601 	case 0xee:
602 	  opcode = 0xef;
603 	  break;
604 	case 0xef:
605 	  opcode = 0xee;
606 	  break;
607 	default:
608 	  abort ();
609 	}
610       fragP->fr_literal[offset + 1] = opcode;
611 
612       /* Create a fixup for the reversed conditional branch.  */
613       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
614       fix_new (fragP, fragP->fr_fix + 2, 1,
615 	       symbol_new (buf, sec, 0, fragP->fr_next),
616 	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
617 
618       /* Now create the unconditional branch + fixup to the
619 	 final target.  */
620       fragP->fr_literal[offset + 3] = 0xf4;
621       fragP->fr_literal[offset + 4] = 0xe0;
622       fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
623 	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
624       fragP->fr_var = 0;
625       fragP->fr_fix += 8;
626     }
627   else if (fragP->fr_subtype == 6)
628     {
629       fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
630 	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
631       fragP->fr_var = 0;
632       fragP->fr_fix += 3;
633     }
634   else if (fragP->fr_subtype == 7)
635     {
636       int offset = fragP->fr_fix;
637       fragP->fr_literal[offset] = 0xf4;
638       fragP->fr_literal[offset + 1] = 0xe1;
639 
640       fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
641 	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
642       fragP->fr_var = 0;
643       fragP->fr_fix += 5;
644     }
645   else if (fragP->fr_subtype == 8)
646     {
647       fragP->fr_literal[fragP->fr_fix] = 0xea;
648       fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
649 	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
650       fragP->fr_var = 0;
651       fragP->fr_fix += 2;
652     }
653   else if (fragP->fr_subtype == 9)
654     {
655       int offset = fragP->fr_fix;
656       fragP->fr_literal[offset] = 0xfc;
657 
658       fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
659 	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
660       fragP->fr_var = 0;
661       fragP->fr_fix += 3;
662     }
663   else if (fragP->fr_subtype == 10)
664     {
665       int offset = fragP->fr_fix;
666       fragP->fr_literal[offset] = 0xf4;
667       fragP->fr_literal[offset + 1] = 0xe0;
668 
669       fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
670 	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
671       fragP->fr_var = 0;
672       fragP->fr_fix += 5;
673     }
674   else
675     abort ();
676 }
677 
678 valueT
md_section_align(asection * seg,valueT addr)679 md_section_align (asection *seg, valueT addr)
680 {
681   int align = bfd_get_section_alignment (stdoutput, seg);
682   return ((addr + (1 << align) - 1) & (-1 << align));
683 }
684 
685 void
md_begin(void)686 md_begin (void)
687 {
688   char *prev_name = "";
689   const struct mn10200_opcode *op;
690 
691   mn10200_hash = hash_new ();
692 
693   /* Insert unique names into hash table.  The MN10200 instruction set
694      has many identical opcode names that have different opcodes based
695      on the operands.  This hash table then provides a quick index to
696      the first opcode with a particular name in the opcode table.  */
697 
698   op = mn10200_opcodes;
699   while (op->name)
700     {
701       if (strcmp (prev_name, op->name))
702 	{
703 	  prev_name = (char *) op->name;
704 	  hash_insert (mn10200_hash, op->name, (char *) op);
705 	}
706       op++;
707     }
708 
709   /* This is both a simplification (we don't have to write md_apply_fix)
710      and support for future optimizations (branch shortening and similar
711      stuff in the linker.  */
712   linkrelax = 1;
713 }
714 
715 static unsigned long
check_operand(unsigned long insn ATTRIBUTE_UNUSED,const struct mn10200_operand * operand,offsetT val)716 check_operand (unsigned long insn ATTRIBUTE_UNUSED,
717 	       const struct mn10200_operand *operand,
718 	       offsetT val)
719 {
720   /* No need to check 24bit or 32bit operands for a bit.  */
721   if (operand->bits < 24
722       && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
723     {
724       long min, max;
725       offsetT test;
726 
727       if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
728 	{
729 	  max = (1 << (operand->bits - 1)) - 1;
730 	  min = - (1 << (operand->bits - 1));
731 	}
732       else
733 	{
734 	  max = (1 << operand->bits) - 1;
735 	  min = 0;
736 	}
737 
738       test = val;
739 
740       if (test < (offsetT) min || test > (offsetT) max)
741 	return 0;
742       else
743 	return 1;
744     }
745   return 1;
746 }
747 /* If while processing a fixup, a reloc really needs to be created
748    Then it is done here.  */
749 
750 arelent *
tc_gen_reloc(asection * seg ATTRIBUTE_UNUSED,fixS * fixp)751 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
752 {
753   arelent *reloc;
754   reloc = xmalloc (sizeof (arelent));
755 
756   if (fixp->fx_subsy != NULL)
757     {
758       if (S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy)
759 	  && S_IS_DEFINED (fixp->fx_subsy))
760 	{
761 	  fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
762 	  fixp->fx_subsy = NULL;
763 	}
764       else
765 	/* FIXME: We should try more ways to resolve difference expressions
766 	   here.  At least this is better than silently ignoring the
767 	   subtrahend.  */
768 	as_bad_where (fixp->fx_file, fixp->fx_line,
769 		      _("can't resolve `%s' {%s section} - `%s' {%s section}"),
770 		      fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0",
771 		      segment_name (fixp->fx_addsy
772 				    ? S_GET_SEGMENT (fixp->fx_addsy)
773 				    : absolute_section),
774 		      S_GET_NAME (fixp->fx_subsy),
775 		      segment_name (S_GET_SEGMENT (fixp->fx_addsy)));
776     }
777 
778   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
779   if (reloc->howto == NULL)
780     {
781       as_bad_where (fixp->fx_file, fixp->fx_line,
782 		    _("reloc %d not supported by object file format"),
783 		    (int) fixp->fx_r_type);
784       return NULL;
785     }
786   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
787   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
788   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
789   reloc->addend = fixp->fx_offset;
790   return reloc;
791 }
792 
793 int
md_estimate_size_before_relax(fragS * fragp,asection * seg)794 md_estimate_size_before_relax (fragS *fragp, asection *seg)
795 {
796   if (fragp->fr_subtype == 6
797       && (!S_IS_DEFINED (fragp->fr_symbol)
798 	  || seg != S_GET_SEGMENT (fragp->fr_symbol)))
799     fragp->fr_subtype = 7;
800   else if (fragp->fr_subtype == 8
801 	   && (!S_IS_DEFINED (fragp->fr_symbol)
802 	       || seg != S_GET_SEGMENT (fragp->fr_symbol)))
803     fragp->fr_subtype = 10;
804 
805   if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
806     abort ();
807 
808   return md_relax_table[fragp->fr_subtype].rlx_length;
809 }
810 
811 long
md_pcrel_from(fixS * fixp)812 md_pcrel_from (fixS *fixp)
813 {
814   return fixp->fx_frag->fr_address;
815 }
816 
817 void
md_apply_fix(fixS * fixP,valueT * valP ATTRIBUTE_UNUSED,segT seg ATTRIBUTE_UNUSED)818 md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
819 {
820   /* We shouldn't ever get here because linkrelax is nonzero.  */
821   abort ();
822   fixP->fx_done = 1;
823 }
824 
825 /* Insert an operand value into an instruction.  */
826 
827 static void
mn10200_insert_operand(unsigned long * insnp,unsigned long * extensionp,const struct mn10200_operand * operand,offsetT val,char * file,unsigned int line,unsigned int shift)828 mn10200_insert_operand (unsigned long *insnp,
829 			unsigned long *extensionp,
830 			const struct mn10200_operand *operand,
831 			offsetT val,
832 			char *file,
833 			unsigned int line,
834 			unsigned int shift)
835 {
836   /* No need to check 24 or 32bit operands for a bit.  */
837   if (operand->bits < 24
838       && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
839     {
840       long min, max;
841       offsetT test;
842 
843       if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
844 	{
845 	  max = (1 << (operand->bits - 1)) - 1;
846 	  min = - (1 << (operand->bits - 1));
847 	}
848       else
849 	{
850 	  max = (1 << operand->bits) - 1;
851 	  min = 0;
852 	}
853 
854       test = val;
855 
856       if (test < (offsetT) min || test > (offsetT) max)
857 	as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
858     }
859 
860   if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
861     {
862       *insnp |= (((long) val & ((1 << operand->bits) - 1))
863 		 << (operand->shift + shift));
864 
865       if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
866 	*insnp |= (((long) val & ((1 << operand->bits) - 1))
867 		   << (operand->shift + shift + 2));
868     }
869   else
870     {
871       *extensionp |= (val >> 16) & 0xff;
872       *insnp |= val & 0xffff;
873     }
874 }
875 
876 void
md_assemble(char * str)877 md_assemble (char *str)
878 {
879   char *s;
880   struct mn10200_opcode *opcode;
881   struct mn10200_opcode *next_opcode;
882   const unsigned char *opindex_ptr;
883   int next_opindex, relaxable;
884   unsigned long insn, extension, size = 0;
885   char *f;
886   int i;
887   int match;
888 
889   /* Get the opcode.  */
890   for (s = str; *s != '\0' && !ISSPACE (*s); s++)
891     ;
892   if (*s != '\0')
893     *s++ = '\0';
894 
895   /* Find the first opcode with the proper name.  */
896   opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str);
897   if (opcode == NULL)
898     {
899       as_bad (_("Unrecognized opcode: `%s'"), str);
900       return;
901     }
902 
903   str = s;
904   while (ISSPACE (*str))
905     ++str;
906 
907   input_line_pointer = str;
908 
909   for (;;)
910     {
911       const char *errmsg = NULL;
912       int op_idx;
913       char *hold;
914       int extra_shift = 0;
915 
916       relaxable = 0;
917       fc = 0;
918       match = 0;
919       next_opindex = 0;
920       insn = opcode->opcode;
921       extension = 0;
922       for (op_idx = 1, opindex_ptr = opcode->operands;
923 	   *opindex_ptr != 0;
924 	   opindex_ptr++, op_idx++)
925 	{
926 	  const struct mn10200_operand *operand;
927 	  expressionS ex;
928 
929 	  if (next_opindex == 0)
930 	    {
931 	      operand = &mn10200_operands[*opindex_ptr];
932 	    }
933 	  else
934 	    {
935 	      operand = &mn10200_operands[next_opindex];
936 	      next_opindex = 0;
937 	    }
938 
939 	  errmsg = NULL;
940 
941 	  while (*str == ' ' || *str == ',')
942 	    ++str;
943 
944 	  if (operand->flags & MN10200_OPERAND_RELAX)
945 	    relaxable = 1;
946 
947 	  /* Gather the operand.  */
948 	  hold = input_line_pointer;
949 	  input_line_pointer = str;
950 
951 	  if (operand->flags & MN10200_OPERAND_PAREN)
952 	    {
953 	      if (*input_line_pointer != ')' && *input_line_pointer != '(')
954 		{
955 		  input_line_pointer = hold;
956 		  str = hold;
957 		  goto error;
958 		}
959 	      input_line_pointer++;
960 	      goto keep_going;
961 	    }
962 	  /* See if we can match the operands.  */
963 	  else if (operand->flags & MN10200_OPERAND_DREG)
964 	    {
965 	      if (!data_register_name (&ex))
966 		{
967 		  input_line_pointer = hold;
968 		  str = hold;
969 		  goto error;
970 		}
971 	    }
972 	  else if (operand->flags & MN10200_OPERAND_AREG)
973 	    {
974 	      if (!address_register_name (&ex))
975 		{
976 		  input_line_pointer = hold;
977 		  str = hold;
978 		  goto error;
979 		}
980 	    }
981 	  else if (operand->flags & MN10200_OPERAND_PSW)
982 	    {
983 	      char *start = input_line_pointer;
984 	      char c = get_symbol_end ();
985 
986 	      if (strcmp (start, "psw") != 0)
987 		{
988 		  *input_line_pointer = c;
989 		  input_line_pointer = hold;
990 		  str = hold;
991 		  goto error;
992 		}
993 	      *input_line_pointer = c;
994 	      goto keep_going;
995 	    }
996 	  else if (operand->flags & MN10200_OPERAND_MDR)
997 	    {
998 	      char *start = input_line_pointer;
999 	      char c = get_symbol_end ();
1000 
1001 	      if (strcmp (start, "mdr") != 0)
1002 		{
1003 		  *input_line_pointer = c;
1004 		  input_line_pointer = hold;
1005 		  str = hold;
1006 		  goto error;
1007 		}
1008 	      *input_line_pointer = c;
1009 	      goto keep_going;
1010 	    }
1011 	  else if (data_register_name (&ex))
1012 	    {
1013 	      input_line_pointer = hold;
1014 	      str = hold;
1015 	      goto error;
1016 	    }
1017 	  else if (address_register_name (&ex))
1018 	    {
1019 	      input_line_pointer = hold;
1020 	      str = hold;
1021 	      goto error;
1022 	    }
1023 	  else if (other_register_name (&ex))
1024 	    {
1025 	      input_line_pointer = hold;
1026 	      str = hold;
1027 	      goto error;
1028 	    }
1029 	  else if (*str == ')' || *str == '(')
1030 	    {
1031 	      input_line_pointer = hold;
1032 	      str = hold;
1033 	      goto error;
1034 	    }
1035 	  else
1036 	    {
1037 	      expression (&ex);
1038 	    }
1039 
1040 	  switch (ex.X_op)
1041 	    {
1042 	    case O_illegal:
1043 	      errmsg = _("illegal operand");
1044 	      goto error;
1045 	    case O_absent:
1046 	      errmsg = _("missing operand");
1047 	      goto error;
1048 	    case O_register:
1049 	      if ((operand->flags
1050 		   & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
1051 		{
1052 		  input_line_pointer = hold;
1053 		  str = hold;
1054 		  goto error;
1055 		}
1056 
1057 	      if (opcode->format == FMT_2 || opcode->format == FMT_5)
1058 		extra_shift = 8;
1059 	      else if (opcode->format == FMT_3 || opcode->format == FMT_6
1060 		       || opcode->format == FMT_7)
1061 		extra_shift = 16;
1062 	      else
1063 		extra_shift = 0;
1064 
1065 	      mn10200_insert_operand (&insn, &extension, operand,
1066 				      ex.X_add_number, NULL,
1067 				      0, extra_shift);
1068 
1069 	      break;
1070 
1071 	    case O_constant:
1072 	      /* If this operand can be promoted, and it doesn't
1073 		 fit into the allocated bitfield for this insn,
1074 		 then promote it (ie this opcode does not match).  */
1075 	      if (operand->flags
1076 		  & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
1077 		  && !check_operand (insn, operand, ex.X_add_number))
1078 		{
1079 		  input_line_pointer = hold;
1080 		  str = hold;
1081 		  goto error;
1082 		}
1083 
1084 	      mn10200_insert_operand (&insn, &extension, operand,
1085 				      ex.X_add_number, NULL,
1086 				      0, 0);
1087 	      break;
1088 
1089 	    default:
1090 	      /* If this operand can be promoted, then this opcode didn't
1091 		 match since we can't know if it needed promotion!  */
1092 	      if (operand->flags & MN10200_OPERAND_PROMOTE)
1093 		{
1094 		  input_line_pointer = hold;
1095 		  str = hold;
1096 		  goto error;
1097 		}
1098 
1099 	      /* We need to generate a fixup for this expression.  */
1100 	      if (fc >= MAX_INSN_FIXUPS)
1101 		as_fatal (_("too many fixups"));
1102 	      fixups[fc].exp = ex;
1103 	      fixups[fc].opindex = *opindex_ptr;
1104 	      fixups[fc].reloc = BFD_RELOC_UNUSED;
1105 	      ++fc;
1106 	      break;
1107 	    }
1108 
1109 keep_going:
1110 	  str = input_line_pointer;
1111 	  input_line_pointer = hold;
1112 
1113 	  while (*str == ' ' || *str == ',')
1114 	    ++str;
1115 
1116 	}
1117 
1118       /* Make sure we used all the operands!  */
1119       if (*str != ',')
1120 	match = 1;
1121 
1122     error:
1123       if (match == 0)
1124 	{
1125 	  next_opcode = opcode + 1;
1126 	  if (!strcmp (next_opcode->name, opcode->name))
1127 	    {
1128 	      opcode = next_opcode;
1129 	      continue;
1130 	    }
1131 
1132 	  as_bad ("%s", errmsg);
1133 	  return;
1134 	}
1135       break;
1136     }
1137 
1138   while (ISSPACE (*str))
1139     ++str;
1140 
1141   if (*str != '\0')
1142     as_bad (_("junk at end of line: `%s'"), str);
1143 
1144   input_line_pointer = str;
1145 
1146   if (opcode->format == FMT_1)
1147     size = 1;
1148   else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1149     size = 2;
1150   else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1151     size = 3;
1152   else if (opcode->format == FMT_6)
1153     size = 4;
1154   else if (opcode->format == FMT_7)
1155     size = 5;
1156   else
1157     abort ();
1158 
1159   /* Write out the instruction.  */
1160   dwarf2_emit_insn (0);
1161   if (relaxable && fc > 0)
1162     {
1163       /* On a 64-bit host the size of an 'int' is not the same
1164 	 as the size of a pointer, so we need a union to convert
1165 	 the opindex field of the fr_cgen structure into a char *
1166 	 so that it can be stored in the frag.  We do not have
1167 	 to worry about loosing accuracy as we are not going to
1168 	 be even close to the 32bit limit of the int.  */
1169       union
1170       {
1171 	int opindex;
1172 	char * ptr;
1173       }
1174       opindex_converter;
1175       int type;
1176 
1177       /* bCC  */
1178       if (size == 2 && opcode->opcode != 0xfc0000)
1179 	{
1180 	  /* Handle bra specially.  Basically treat it like jmp so
1181 	     that we automatically handle 8, 16 and 32 bit offsets
1182 	     correctly as well as jumps to an undefined address.
1183 
1184 	     It is also important to not treat it like other bCC
1185 	     instructions since the long forms of bra is different
1186 	     from other bCC instructions.  */
1187 	  if (opcode->opcode == 0xea00)
1188 	    type = 8;
1189 	  else
1190 	    type = 0;
1191 	}
1192       /* jsr  */
1193       else if (size == 3 && opcode->opcode == 0xfd0000)
1194 	type = 6;
1195       /* jmp  */
1196       else if (size == 3 && opcode->opcode == 0xfc0000)
1197 	type = 8;
1198       /* bCCx  */
1199       else
1200 	type = 3;
1201 
1202       opindex_converter.opindex = fixups[0].opindex;
1203       f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1204 		    fixups[0].exp.X_add_symbol,
1205 		    fixups[0].exp.X_add_number,
1206 		    opindex_converter.ptr);
1207       number_to_chars_bigendian (f, insn, size);
1208       if (8 - size > 4)
1209 	{
1210 	  number_to_chars_bigendian (f + size, 0, 4);
1211 	  number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1212 	}
1213       else
1214 	number_to_chars_bigendian (f + size, 0, 8 - size);
1215     }
1216   else
1217     {
1218       f = frag_more (size);
1219 
1220       /* Oh, what a mess.  The instruction is in big endian format, but
1221 	 16 and 24bit immediates are little endian!  */
1222       if (opcode->format == FMT_3)
1223 	{
1224 	  number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1225 	  number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1226 	}
1227       else if (opcode->format == FMT_6)
1228 	{
1229 	  number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1230 	  number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1231 	}
1232       else if (opcode->format == FMT_7)
1233 	{
1234 	  number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1235 	  number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1236 	  number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1237 	}
1238       else
1239 	number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1240 
1241       /* Create any fixups.  */
1242       for (i = 0; i < fc; i++)
1243 	{
1244 	  const struct mn10200_operand *operand;
1245 	  int reloc_size;
1246 
1247 	  operand = &mn10200_operands[fixups[i].opindex];
1248 	  if (fixups[i].reloc != BFD_RELOC_UNUSED)
1249 	    {
1250 	      reloc_howto_type *reloc_howto;
1251 	      int offset;
1252 	      fixS *fixP;
1253 
1254 	      reloc_howto = bfd_reloc_type_lookup (stdoutput,
1255 						   fixups[i].reloc);
1256 
1257 	      if (!reloc_howto)
1258 		abort ();
1259 
1260 	      reloc_size = bfd_get_reloc_size (reloc_howto);
1261 
1262 	      if (reloc_size < 1 || reloc_size > 4)
1263 		abort ();
1264 
1265 	      offset = 4 - reloc_size;
1266 	      fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1267 				  reloc_size,
1268 				  &fixups[i].exp,
1269 				  reloc_howto->pc_relative,
1270 				  fixups[i].reloc);
1271 
1272 	      /* PC-relative offsets are from the first byte of the
1273 		 next instruction, not from the start of the current
1274 		 instruction.  */
1275 	      if (reloc_howto->pc_relative)
1276 		fixP->fx_offset += reloc_size;
1277 	    }
1278 	  else
1279 	    {
1280 	      int reloc, pcrel, offset;
1281 	      fixS *fixP;
1282 
1283 	      reloc = BFD_RELOC_NONE;
1284 	      /* How big is the reloc?  Remember SPLIT relocs are
1285 		 implicitly 32bits.  */
1286 	      reloc_size = operand->bits;
1287 
1288 	      offset = size - reloc_size / 8;
1289 
1290 	      /* Is the reloc pc-relative?  */
1291 	      pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1292 
1293 	      /* Choose a proper BFD relocation type.  */
1294 	      if (pcrel)
1295 		{
1296 		  if (reloc_size == 8)
1297 		    reloc = BFD_RELOC_8_PCREL;
1298 		  else if (reloc_size == 24)
1299 		    reloc = BFD_RELOC_24_PCREL;
1300 		  else
1301 		    abort ();
1302 		}
1303 	      else
1304 		{
1305 		  if (reloc_size == 32)
1306 		    reloc = BFD_RELOC_32;
1307 		  else if (reloc_size == 16)
1308 		    reloc = BFD_RELOC_16;
1309 		  else if (reloc_size == 8)
1310 		    reloc = BFD_RELOC_8;
1311 		  else if (reloc_size == 24)
1312 		    reloc = BFD_RELOC_24;
1313 		  else
1314 		    abort ();
1315 		}
1316 
1317 	      /* Convert the size of the reloc into what fix_new_exp
1318                  wants.  */
1319 	      reloc_size = reloc_size / 8;
1320 	      if (reloc_size == 8)
1321 		reloc_size = 0;
1322 	      else if (reloc_size == 16)
1323 		reloc_size = 1;
1324 	      else if (reloc_size == 32 || reloc_size == 24)
1325 		reloc_size = 2;
1326 
1327 	      fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1328 				  reloc_size, &fixups[i].exp, pcrel,
1329 				  ((bfd_reloc_code_real_type) reloc));
1330 
1331 	      /* PC-relative offsets are from the first byte of the
1332 		 next instruction, not from the start of the current
1333 		 instruction.  */
1334 	      if (pcrel)
1335 		fixP->fx_offset += size;
1336 	    }
1337 	}
1338     }
1339 }
1340 
1341