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