* config/obj-ecoff.c (get_tag): Save tag name in permanent memory
[deliverable/binutils-gdb.git] / gas / config / tc-sh.c
1 /* tc-sh.c -- Assemble code for the Hitachi Super-H
2
3 Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /*
22 Written By Steve Chamberlain
23 sac@cygnus.com
24 */
25
26 #include <stdio.h>
27 #include "as.h"
28 #include "bfd.h"
29 #include "subsegs.h"
30 #define DEFINE_TABLE
31 #include "../opcodes/sh-opc.h"
32 #include <ctype.h>
33
34 const char comment_chars[] = "!";
35 const char line_separator_chars[] = ";";
36 const char line_comment_chars[] = "!";
37
38 /* This table describes all the machine specific pseudo-ops the assembler
39 has to support. The fields are:
40 pseudo-op name without dot
41 function to call to execute this pseudo-op
42 Integer arg to pass to the function
43 */
44
45 void cons ();
46 void s_align_bytes ();
47
48 const pseudo_typeS md_pseudo_table[] =
49 {
50 {"int", cons, 4},
51 {"word", cons, 2},
52 {"form", listing_psize, 0},
53 {"heading", listing_title, 0},
54 {"import", s_ignore, 0},
55 {"page", listing_eject, 0},
56 {"program", s_ignore, 0},
57 {0, 0, 0}
58 };
59
60 /*int md_reloc_size;*/
61
62 static int relax; /* set if -relax seen */
63
64 const char EXP_CHARS[] = "eE";
65
66 /* Chars that mean this number is a floating point constant */
67 /* As in 0f12.456 */
68 /* or 0d1.2345e12 */
69 const char FLT_CHARS[] = "rRsSfFdDxXpP";
70
71 #define C(a,b) ENCODE_RELAX(a,b)
72
73 #define JREG 14 /* Register used as a temp when relaxing */
74 #define ENCODE_RELAX(what,length) (((what) << 4) + (length))
75 #define GET_WHAT(x) ((x>>4))
76
77 /* These are the two types of relaxable instrction */
78 #define COND_JUMP 1
79 #define UNCOND_JUMP 2
80
81 #define UNDEF_DISP 0
82 #define COND8 1
83 #define COND12 2
84 #define COND32 3
85 #define UNCOND12 1
86 #define UNCOND32 2
87 #define UNDEF_WORD_DISP 4
88 #define END 5
89
90 #define UNCOND12 1
91 #define UNCOND32 2
92
93 #define COND8_F 254
94 #define COND8_M -256
95 #define COND8_LENGTH 2
96 #define COND12_F (4094 - 4) /* -4 since there are two extra */
97 /* instructions needed */
98 #define COND12_M -4096
99 #define COND12_LENGTH 6
100 #define COND32_F (1<<30)
101 #define COND32_M -(1<<30)
102 #define COND32_LENGTH 14
103
104 #define COND8_RANGE(x) ((x) > COND8_M && (x) < COND8_F)
105 #define COND12_RANGE(x) ((x) > COND12_M && (x) < COND12_F)
106
107 #define UNCOND12_F 4094
108 #define UNCOND12_M -4096
109 #define UNCOND12_LENGTH 2
110
111 #define UNCOND32_F (1<<30)
112 #define UNCOND32_M -(1<<30)
113 #define UNCOND32_LENGTH 14
114
115
116 const relax_typeS md_relax_table[C (END, 0)];
117
118 static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
119
120 /*
121 This function is called once, at assembler startup time. This should
122 set up all the tables, etc that the MD part of the assembler needs
123 */
124
125 void
126 md_begin ()
127 {
128 sh_opcode_info *opcode;
129 char *prev_name = "";
130
131 opcode_hash_control = hash_new ();
132
133 /* Insert unique names into hash table */
134 for (opcode = sh_table; opcode->name; opcode++)
135 {
136 if (strcmp (prev_name, opcode->name))
137 {
138 prev_name = opcode->name;
139 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
140 }
141 else
142 {
143 /* Make all the opcodes with the same name point to the same
144 string */
145 opcode->name = prev_name;
146 }
147 }
148
149 /* Initialize the relax table */
150 md_relax_table[C (COND_JUMP, COND8)].rlx_forward = COND8_F;
151 md_relax_table[C (COND_JUMP, COND8)].rlx_backward = COND8_M;
152 md_relax_table[C (COND_JUMP, COND8)].rlx_length = COND8_LENGTH;
153 md_relax_table[C (COND_JUMP, COND8)].rlx_more = C (COND_JUMP, COND12);
154
155 md_relax_table[C (COND_JUMP, COND12)].rlx_forward = COND12_F;
156 md_relax_table[C (COND_JUMP, COND12)].rlx_backward = COND12_M;
157 md_relax_table[C (COND_JUMP, COND12)].rlx_length = COND12_LENGTH;
158 md_relax_table[C (COND_JUMP, COND12)].rlx_more = C (COND_JUMP, COND32);
159
160 md_relax_table[C (COND_JUMP, COND32)].rlx_forward = COND32_F;
161 md_relax_table[C (COND_JUMP, COND32)].rlx_backward = COND32_M;
162 md_relax_table[C (COND_JUMP, COND32)].rlx_length = COND32_LENGTH;
163 md_relax_table[C (COND_JUMP, COND32)].rlx_more = 0;
164
165
166 md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_forward = UNCOND12_F;
167 md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_backward = UNCOND12_M;
168 md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length = UNCOND12_LENGTH;
169 md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_more = C (UNCOND_JUMP, UNCOND32);
170
171 md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_forward = UNCOND32_F;
172 md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_backward = UNCOND32_M;
173 md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length = UNCOND32_LENGTH;
174 md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_more = 0;
175
176
177 }
178
179 static int reg_m;
180 static int reg_n;
181 static expressionS immediate; /* absolute expression */
182
183 typedef struct
184 {
185 sh_arg_type type;
186 int reg;
187 }
188
189 sh_operand_info;
190
191 /* try and parse a reg name, returns number of chars consumed */
192 static int
193 parse_reg (src, mode, reg)
194 char *src;
195 int *mode;
196 int *reg;
197 {
198 if (src[0] == 'r')
199 {
200 if (src[1] == '1')
201 {
202 if (src[2] >= '0' && src[2] <= '5')
203 {
204 *mode = A_REG_N;
205 *reg = 10 + src[2] - '0';
206 return 3;
207 }
208 }
209 if (src[1] >= '0' && src[1] <= '9')
210 {
211 *mode = A_REG_N;
212 *reg = (src[1] - '0');
213 return 2;
214 }
215 }
216
217 if (src[0] == 's' && src[1] == 'r')
218 {
219 *mode = A_SR;
220 return 2;
221 }
222
223 if (src[0] == 's' && src[1] == 'p')
224 {
225 *mode = A_REG_N;
226 *reg = 15;
227 return 2;
228 }
229
230 if (src[0] == 'p' && src[1] == 'r')
231 {
232 *mode = A_PR;
233 return 2;
234 }
235 if (src[0] == 'p' && src[1] == 'c')
236 {
237 *mode = A_DISP_PC;
238 return 2;
239 }
240 if (src[0] == 'g' && src[1] == 'b' && src[2] == 'r')
241 {
242 *mode = A_GBR;
243 return 3;
244 }
245 if (src[0] == 'v' && src[1] == 'b' && src[2] == 'r')
246 {
247 *mode = A_VBR;
248 return 3;
249 }
250
251 if (src[0] == 'm' && src[1] == 'a' && src[2] == 'c')
252 {
253 if (src[3] == 'l')
254 {
255 *mode = A_MACL;
256 return 4;
257 }
258 if (src[3] == 'h')
259 {
260 *mode = A_MACH;
261 return 4;
262 }
263 }
264
265 return 0;
266 }
267
268 static
269 char *
270 parse_exp (s)
271 char *s;
272 {
273 char *save;
274 char *new;
275 segT seg;
276
277 save = input_line_pointer;
278
279
280 input_line_pointer = s;
281
282 seg = expr (0, &immediate);
283 new = input_line_pointer;
284 input_line_pointer = save;
285 if (SEG_NORMAL (seg))
286 return new;
287 switch (seg)
288 {
289 case SEG_ABSOLUTE:
290 case SEG_UNKNOWN:
291 case SEG_DIFFERENCE:
292 case SEG_BIG:
293 case SEG_REGISTER:
294 return new;
295 case SEG_ABSENT:
296 as_bad ("Missing operand");
297 return new;
298 default:
299 as_bad ("Don't understand operand of type %s", segment_name (seg));
300 return new;
301 }
302 }
303
304
305 /* The many forms of operand:
306
307 Rn Register direct
308 @Rn Register indirect
309 @Rn+ Autoincrement
310 @-Rn Autodecrement
311 @(disp:4,Rn)
312 @(disp:8,GBR)
313 @(disp:8,PC)
314
315 @(R0,Rn)
316 @(R0,GBR)
317
318 disp:8
319 disp:12
320 #imm8
321 pr, gbr, vbr, macl, mach
322
323 */
324
325 static
326 char *
327 parse_at (src, op)
328 char *src;
329 sh_operand_info *op;
330 {
331 int len;
332 int mode;
333 src++;
334 if (src[0] == '-')
335 {
336 /* Must be predecrement */
337 src++;
338
339 len = parse_reg (src, &mode, &(op->reg));
340 if (mode != A_REG_N)
341 as_bad ("illegal register after @-");
342
343 op->type = A_DEC_N;
344 src += len;
345 }
346 else if (src[0] == '(')
347 {
348 /* Could be @(disp, rn), @(disp, gbr), @(disp, pc), @(r0, gbr) or
349 @(r0, rn) */
350 src++;
351 len = parse_reg (src, &mode, &(op->reg));
352 if (len && mode == A_REG_N)
353 {
354 src += len;
355 if (op->reg != 0)
356 {
357 as_bad ("must be @(r0,...)");
358 }
359 if (src[0] == ',')
360 src++;
361 /* Now can be rn or gbr */
362 len = parse_reg (src, &mode, &(op->reg));
363 if (mode == A_GBR)
364 {
365 op->type = A_R0_GBR;
366 }
367 else if (mode == A_REG_N)
368 {
369 op->type = A_IND_R0_REG_N;
370 }
371 else
372 {
373 as_bad ("syntax error in @(r0,...)");
374 }
375 }
376 else
377 {
378 /* Must be an @(disp,.. thing) */
379 src = parse_exp (src);
380 if (src[0] == ',')
381 src++;
382 /* Now can be rn, gbr or pc */
383 len = parse_reg (src, &mode, &op->reg);
384 if (len)
385 {
386 if (mode == A_REG_N)
387 {
388 op->type = A_DISP_REG_N;
389 }
390 else if (mode == A_GBR)
391 {
392 op->type = A_DISP_GBR;
393 }
394 else if (mode == A_DISP_PC)
395 {
396 op->type = A_DISP_PC;
397 }
398 else
399 {
400 as_bad ("syntax error in @(disp,[Rn, gbr, pc])");
401 }
402 }
403 else
404 {
405 as_bad ("syntax error in @(disp,[Rn, gbr, pc])");
406 }
407 }
408 src += len;
409 if (src[0] != ')')
410 as_bad ("expecting )");
411 else
412 src++;
413 }
414 else
415 {
416 src += parse_reg (src, &mode, &(op->reg));
417 if (mode != A_REG_N)
418 {
419 as_bad ("illegal register after @");
420 }
421 if (src[0] == '+')
422 {
423 op->type = A_INC_N;
424 src++;
425 }
426 else
427 {
428 op->type = A_IND_N;
429 }
430 }
431 return src;
432 }
433
434 static void
435 get_operand (ptr, op)
436 char **ptr;
437 sh_operand_info *op;
438 {
439 char *src = *ptr;
440 int mode = -1;
441 unsigned int len;
442
443 if (src[0] == '#')
444 {
445 src++;
446 *ptr = parse_exp (src);
447 op->type = A_IMM;
448 return;
449 }
450
451 else if (src[0] == '@')
452 {
453 *ptr = parse_at (src, op);
454 return;
455 }
456 len = parse_reg (src, &mode, &(op->reg));
457 if (len)
458 {
459 *ptr = src + len;
460 op->type = mode;
461 return;
462 }
463 else
464 {
465 /* Not a reg, the only thing left is a displacement */
466 *ptr = parse_exp (src);
467 op->type = A_DISP_PC;
468 return;
469 }
470 }
471
472 static
473 char *
474 get_operands (info, args, operand)
475 sh_opcode_info *info;
476 char *args;
477 sh_operand_info *operand;
478
479 {
480 char *ptr = args;
481 if (info->arg[0])
482 {
483 ptr++;
484
485 get_operand (&ptr, operand + 0);
486 if (info->arg[1])
487 {
488 if (*ptr == ',')
489 {
490 ptr++;
491 }
492 get_operand (&ptr, operand + 1);
493 }
494 else
495 {
496 operand[1].type = 0;
497 }
498 }
499 else
500 {
501 operand[0].type = 0;
502 operand[1].type = 0;
503 }
504 return ptr;
505 }
506
507 /* Passed a pointer to a list of opcodes which use different
508 addressing modes, return the opcode which matches the opcodes
509 provided
510 */
511
512 static
513 sh_opcode_info *
514 get_specific (opcode, operands)
515 sh_opcode_info *opcode;
516 sh_operand_info *operands;
517 {
518 sh_opcode_info *this_try = opcode;
519 char *name = opcode->name;
520 int arg_to_test = 0;
521 int n = 0;
522 while (opcode->name)
523 {
524 this_try = opcode++;
525 if (this_try->name != name)
526 {
527 /* We've looked so far down the table that we've run out of
528 opcodes with the same name */
529 return 0;
530 }
531 /* look at both operands needed by the opcodes and provided by
532 the user - since an arg test will often fail on the same arg
533 again and again, we'll try and test the last failing arg the
534 first on each opcode try */
535
536 for (n = 0; this_try->arg[n]; n++)
537 {
538 sh_operand_info *user = operands + arg_to_test;
539 sh_arg_type arg = this_try->arg[arg_to_test];
540 switch (arg)
541 {
542 case A_IMM:
543 case A_BDISP12:
544 case A_BDISP8:
545 case A_DISP_GBR:
546 case A_DISP_PC:
547 case A_MACH:
548 case A_PR:
549 case A_MACL:
550 if (user->type != arg)
551 goto fail;
552 break;
553 case A_R0:
554 /* opcode needs r0 */
555 if (user->type != A_REG_N || user->reg != 0)
556 goto fail;
557 break;
558 case A_R0_GBR:
559 if (user->type != A_R0_GBR || user->reg != 0)
560 goto fail;
561 break;
562
563 case A_REG_N:
564 case A_INC_N:
565 case A_DEC_N:
566 case A_IND_N:
567 case A_IND_R0_REG_N:
568 case A_DISP_REG_N:
569 /* Opcode needs rn */
570 if (user->type != arg)
571 goto fail;
572 reg_n = user->reg;
573 break;
574 case A_GBR:
575 case A_SR:
576 case A_VBR:
577 if (user->type != arg)
578 goto fail;
579 break;
580
581 case A_REG_M:
582 case A_INC_M:
583 case A_DEC_M:
584 case A_IND_M:
585 case A_IND_R0_REG_M:
586 case A_DISP_REG_M:
587 /* Opcode needs rn */
588 if (user->type != arg - A_REG_M + A_REG_N)
589 goto fail;
590 reg_m = user->reg;
591 break;
592 default:
593 printf ("unhandled %d\n", arg);
594 goto fail;
595 }
596 /* If we did 0, test 1 next, else 0 */
597 arg_to_test = 1 - arg_to_test;
598 }
599 return this_try;
600 fail:;
601 }
602
603 return 0;
604 }
605
606 int
607 check (operand, low, high)
608 expressionS *operand;
609 int low;
610 int high;
611 {
612 if (operand->X_seg != SEG_ABSOLUTE
613 || operand->X_add_number < low
614 || operand->X_add_number > high)
615 {
616 as_bad ("operand must be absolute in range %d..%d", low, high);
617 }
618 return operand->X_add_number;
619 }
620
621
622 static void
623 insert (where, how, pcrel)
624 char *where;
625 int how;
626 int pcrel;
627 {
628 fix_new (frag_now,
629 where - frag_now->fr_literal,
630 4,
631 immediate.X_add_symbol,
632 immediate.X_subtract_symbol,
633 immediate.X_add_number,
634 pcrel,
635 how);
636
637 }
638
639 static void
640 build_relax (opcode)
641 sh_opcode_info *opcode;
642 {
643 int len;
644 char *p;
645 if (opcode->arg[0] == A_BDISP8)
646 {
647 p = frag_var (rs_machine_dependent,
648 md_relax_table[C (COND_JUMP, COND32)].rlx_length,
649 len = md_relax_table[C (COND_JUMP, COND8)].rlx_length,
650 C (COND_JUMP, 0),
651 immediate.X_add_symbol,
652 immediate.X_add_number,
653 0);
654 p[0] = (opcode->nibbles[0] << 4) | (opcode->nibbles[1]);
655 }
656 else if (opcode->arg[0] == A_BDISP12)
657 {
658 p = frag_var (rs_machine_dependent,
659 md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length,
660 len = md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length,
661 C (UNCOND_JUMP, 0),
662 immediate.X_add_symbol,
663 immediate.X_add_number,
664 0);
665 p[0] = (opcode->nibbles[0] << 4);
666 }
667
668 }
669
670 /* Now we know what sort of opcodes it is, lets build the bytes -
671 */
672 static void
673 build_Mytes (opcode, operand)
674 sh_opcode_info *opcode;
675 sh_operand_info *operand;
676
677 {
678 int index;
679 char nbuf[4];
680 char *output = frag_more (2);
681
682 nbuf[0] = 0;
683 nbuf[1] = 0;
684 nbuf[2] = 0;
685 nbuf[3] = 0;
686
687 for (index = 0; index < 4; index++)
688 {
689 sh_nibble_type i = opcode->nibbles[index];
690 if (i < 16)
691 {
692 nbuf[index] = i;
693 }
694 else
695 {
696 switch (i)
697 {
698 case REG_N:
699 nbuf[index] = reg_n;
700 break;
701 case REG_M:
702 nbuf[index] = reg_m;
703 break;
704 case DISP_4:
705 insert (output + 1, R_SH_IMM4, 0);
706 break;
707 case IMM_4BY4:
708 insert (output + 1, R_SH_IMM4BY4, 0);
709 break;
710 case IMM_4BY2:
711 insert (output + 1, R_SH_IMM4BY2, 0);
712 break;
713 case IMM_4:
714 insert (output + 1, R_SH_IMM4, 0);
715 break;
716 case IMM_8BY4:
717 insert (output + 1, R_SH_IMM8BY4, 0);
718 break;
719 case IMM_8BY2:
720 insert (output + 1, R_SH_IMM8BY2, 0);
721 break;
722 case IMM_8:
723 insert (output + 1, R_SH_IMM8, 0);
724 break;
725 case PCRELIMM_8BY4:
726 insert (output + 1, R_SH_PCRELIMM8BY4, 0);
727 break;
728 case PCRELIMM_8BY2:
729 insert (output + 1, R_SH_PCRELIMM8BY2, 0);
730 break;
731 default:
732 printf ("failed for %d\n", i);
733 }
734 }
735 }
736 output[0] = (nbuf[0] << 4) | (nbuf[1]);
737 output[1] = (nbuf[2] << 4) | (nbuf[3]);
738 }
739
740 /* This is the guts of the machine-dependent assembler. STR points to a
741 machine dependent instruction. This function is supposed to emit
742 the frags/bytes it assembles to.
743 */
744
745 void
746 md_assemble (str)
747 char *str;
748 {
749 unsigned char *op_start;
750 unsigned char *op_end;
751 sh_operand_info operand[2];
752 sh_opcode_info *opcode;
753 unsigned char *name;
754
755 int nlen = 0;
756
757 /* Drop leading whitespace */
758 while (*str == ' ')
759 str++;
760
761 /* find the op code end */
762 for (name = op_start = op_end = (unsigned char *) (str);
763 *op_end &&
764 !is_end_of_line[*op_end] && *op_end != ' ';
765 op_end++)
766 {
767 nlen++;
768 }
769 name[nlen] = 0;
770
771 if (op_end == op_start)
772 {
773 as_bad ("can't find opcode ");
774 }
775
776 opcode = (sh_opcode_info *) hash_find (opcode_hash_control, name);
777
778 if (opcode == NULL)
779 {
780 as_bad ("unknown opcode");
781 return;
782 }
783
784 if (opcode->arg[0] == A_BDISP12
785 || opcode->arg[0] == A_BDISP8)
786 {
787 input_line_pointer = parse_exp (op_end + 1);
788 build_relax (opcode);
789 }
790 else
791 {
792 input_line_pointer = get_operands (opcode, op_end, operand);
793
794 opcode = get_specific (opcode, operand);
795
796 if (opcode == 0)
797 {
798 /* Couldn't find an opcode which matched the operands */
799 char *where = frag_more (2);
800
801 where[0] = 0x0;
802 where[1] = 0x0;
803 as_bad ("invalid operands for opcode");
804 return;
805 }
806
807 build_Mytes (opcode, operand);
808 }
809
810 }
811
812 void
813 DEFUN (tc_crawl_symbol_chain, (headers),
814 object_headers * headers)
815 {
816 printf ("call to tc_crawl_symbol_chain \n");
817 }
818
819 symbolS *
820 DEFUN (md_undefined_symbol, (name),
821 char *name)
822 {
823 return 0;
824 }
825
826 void
827 DEFUN (tc_headers_hook, (headers),
828 object_headers * headers)
829 {
830 printf ("call to tc_headers_hook \n");
831 }
832
833 void
834 DEFUN_VOID (md_end)
835 {
836 }
837
838 /* Various routines to kill one day */
839 /* Equal to MAX_PRECISION in atof-ieee.c */
840 #define MAX_LITTLENUMS 6
841
842 /* Turn a string in input_line_pointer into a floating point constant of type
843 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
844 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
845 */
846 char *
847 md_atof (type, litP, sizeP)
848 char type;
849 char *litP;
850 int *sizeP;
851 {
852 int prec;
853 LITTLENUM_TYPE words[MAX_LITTLENUMS];
854 LITTLENUM_TYPE *wordP;
855 char *t;
856 char *atof_ieee ();
857
858 switch (type)
859 {
860 case 'f':
861 case 'F':
862 case 's':
863 case 'S':
864 prec = 2;
865 break;
866
867 case 'd':
868 case 'D':
869 case 'r':
870 case 'R':
871 prec = 4;
872 break;
873
874 case 'x':
875 case 'X':
876 prec = 6;
877 break;
878
879 case 'p':
880 case 'P':
881 prec = 6;
882 break;
883
884 default:
885 *sizeP = 0;
886 return "Bad call to MD_NTOF()";
887 }
888 t = atof_ieee (input_line_pointer, type, words);
889 if (t)
890 input_line_pointer = t;
891
892 *sizeP = prec * sizeof (LITTLENUM_TYPE);
893 for (wordP = words; prec--;)
894 {
895 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
896 litP += sizeof (LITTLENUM_TYPE);
897 }
898 return ""; /* Someone should teach Dean about null pointers */
899 }
900
901 int
902 md_parse_option (argP, cntP, vecP)
903 char **argP;
904 int *cntP;
905 char ***vecP;
906
907 {
908 if (!strcmp (*argP, "relax"))
909 {
910 relax = 1;
911 **argP = 0;
912 }
913 return 1;
914 }
915
916 int md_short_jump_size;
917
918 void
919 tc_Nout_fix_to_chars ()
920 {
921 printf ("call to tc_Nout_fix_to_chars \n");
922 abort ();
923 }
924
925 void
926 md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
927 char *ptr;
928 addressT from_Nddr;
929 addressT to_Nddr;
930 fragS *frag;
931 symbolS *to_symbol;
932 {
933 as_fatal ("failed sanity check.");
934 }
935
936 void
937 md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
938 char *ptr;
939 addressT from_Nddr, to_Nddr;
940 fragS *frag;
941 symbolS *to_symbol;
942 {
943 as_fatal ("failed sanity check.");
944 }
945
946 /*
947 called after relaxing, change the frags so they know how big they are
948 */
949 void
950 md_convert_frag (headers, fragP)
951 object_headers *headers;
952 fragS *fragP;
953
954 {
955 unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
956 int donerelax = 0;
957 int targ_addr = ((fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0) + fragP->fr_offset);
958 switch (fragP->fr_subtype)
959 {
960 case C (COND_JUMP, COND8):
961 {
962 /* Get the address of the end of the instruction */
963 int next_inst = fragP->fr_fix + fragP->fr_address + 2;
964
965 int disp = targ_addr - next_inst - 2;
966 disp /= 2;
967 md_number_to_chars (buffer + 1, disp, 1);
968 fragP->fr_fix += 2;
969 fragP->fr_var = 0;
970 }
971 break;
972
973 case C (UNCOND_JUMP, UNCOND12):
974 {
975 /* Get the address of the end of the instruction */
976 int next_inst = fragP->fr_fix + fragP->fr_address + 2;
977
978 int t;
979 int disp = targ_addr - next_inst - 2;
980
981 disp /= 2;
982 t = buffer[0] & 0xf0;
983 md_number_to_chars (buffer, disp, 2);
984 buffer[0] = (buffer[0] & 0xf) | t;
985 fragP->fr_fix += 2;
986 fragP->fr_var = 0;
987 }
988 break;
989
990 case C (UNCOND_JUMP, UNCOND32):
991 case C (UNCOND_JUMP, UNDEF_WORD_DISP):
992 {
993 /* A jump wont fit in 12 bits, make code which looks like
994 bra foo
995 mov.w @(0, PC), r14
996 .long disp
997 foo: bra @r14
998 */
999
1000 int next_inst =
1001 fragP->fr_fix + fragP->fr_address + UNCOND32_LENGTH;
1002
1003 int disp = targ_addr - next_inst;
1004 int t = buffer[0] & 0x10;
1005
1006 disp /= 2;
1007
1008 buffer[0] = 0xa0; /* branch over move and disp */
1009 buffer[1] = 3;
1010 buffer[2] = 0xd0 | JREG;/* Build mov insn */
1011 buffer[3] = 0x00;
1012
1013 buffer[4] = 0; /* space for 32 bit jump disp */
1014 buffer[5] = 0;
1015 buffer[6] = 0;
1016 buffer[7] = 0;
1017
1018 buffer[10] = 0x40 | JREG; /* Build jmp @JREG */
1019 buffer[11] = t ? 0xb : 0x2b;
1020
1021 buffer[12] = 0x20; /* build nop */
1022 buffer[13] = 0x0b;
1023
1024 /* Make reloc for the long disp */
1025 fix_new (fragP,
1026 fragP->fr_fix + 4,
1027 4,
1028 fragP->fr_symbol,
1029 0,
1030 fragP->fr_offset,
1031 0,
1032 R_SH_IMM32);
1033 fragP->fr_fix += UNCOND32_LENGTH;
1034 fragP->fr_var = 0;
1035 donerelax = 1;
1036
1037 }
1038 break;
1039
1040 case C (COND_JUMP, COND12):
1041 {
1042 /* A bcond won't fit, so turn it into a b!cond; bra disp; nop */
1043 int next_inst =
1044 fragP->fr_fix + fragP->fr_address + 6;
1045
1046 int disp = targ_addr - next_inst;
1047 disp /= 2;
1048 md_number_to_chars (buffer + 2, disp, 2);
1049 buffer[0] ^= 0x2; /* Toggle T/F bit */
1050 buffer[1] = 1; /* branch over jump and nop */
1051 buffer[2] = (buffer[2] & 0xf) | 0xa0; /* Build jump insn */
1052 buffer[4] = 0x20; /* Build nop */
1053 buffer[5] = 0x0b;
1054 fragP->fr_fix += 6;
1055 fragP->fr_var = 0;
1056 donerelax = 1;
1057 }
1058 break;
1059
1060 case C (COND_JUMP, COND32):
1061 case C (COND_JUMP, UNDEF_WORD_DISP):
1062 {
1063 /* A bcond won't fit and it won't go into a 12 bit
1064 displacement either, the code sequence looks like:
1065 b!cond foop
1066 mov.w @(n, PC), r14
1067 jmp @r14
1068 nop
1069 .long where
1070 foop:
1071 */
1072
1073 int next_inst =
1074 fragP->fr_fix + fragP->fr_address + COND32_LENGTH;
1075
1076 int disp = targ_addr - next_inst;
1077 disp /= 2;
1078
1079 buffer[0] ^= 0x2; /* Toggle T/F bit */
1080 #define JREG 14
1081 buffer[1] = 5; /* branch over mov, jump, nop and ptr */
1082 buffer[2] = 0xd0 | JREG;/* Build mov insn */
1083 buffer[3] = 0x2;
1084 buffer[4] = 0x40 | JREG;/* Build jmp @JREG */
1085 buffer[5] = 0x0b;
1086 buffer[6] = 0x20; /* build nop */
1087 buffer[7] = 0x0b;
1088 buffer[8] = 0; /* space for 32 bit jump disp */
1089 buffer[9] = 0;
1090 buffer[10] = 0;
1091 buffer[11] = 0;
1092 buffer[12] = 0;
1093 buffer[13] = 0;
1094 /* Make reloc for the long disp */
1095 fix_new (fragP,
1096 fragP->fr_fix + 8,
1097 4,
1098 fragP->fr_symbol,
1099 0,
1100 fragP->fr_offset,
1101 0,
1102 R_SH_IMM32);
1103 fragP->fr_fix += COND32_LENGTH;
1104 fragP->fr_var = 0;
1105 donerelax = 1;
1106 }
1107 break;
1108
1109 default:
1110 abort ();
1111 }
1112
1113 if (donerelax && !relax)
1114 {
1115 as_bad ("Offset doesn't fit at 0x%x, trying to get to 0x%x",
1116 fragP->fr_address,
1117 targ_addr);
1118 }
1119
1120 }
1121
1122 valueT
1123 DEFUN (md_section_align, (seg, size),
1124 segT seg AND
1125 valueT size)
1126 {
1127 return ((size + (1 << section_alignment[(int) seg]) - 1)
1128 & (-1 << section_alignment[(int) seg]));
1129
1130 }
1131
1132 void
1133 md_apply_fix (fixP, val)
1134 fixS *fixP;
1135 long val;
1136 {
1137 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1138 int addr = fixP->fx_frag->fr_address + fixP->fx_where;
1139 if (fixP->fx_r_type == 0)
1140 {
1141 fixP->fx_r_type = R_SH_IMM32;
1142 }
1143
1144 switch (fixP->fx_r_type)
1145 {
1146
1147 case R_SH_IMM4:
1148 *buf = (*buf & 0xf0) | (val & 0xf);
1149 break;
1150
1151 case R_SH_IMM4BY2:
1152 *buf = (*buf & 0xf0) | ((val >> 1) & 0xf);
1153 break;
1154
1155 case R_SH_IMM4BY4:
1156 *buf = (*buf & 0xf0) | ((val >> 2) & 0xf);
1157 break;
1158
1159 case R_SH_IMM8BY2:
1160 *buf = val >> 1;
1161 break;
1162
1163 case R_SH_IMM8BY4:
1164 *buf = val >> 2;
1165 break;
1166
1167 case R_SH_IMM8:
1168 *buf++ = val;
1169 break;
1170
1171 case R_SH_PCRELIMM8BY4:
1172 addr &= ~1;
1173
1174 if (val & 0x3)
1175 as_warn ("non aligned displacement at %x\n", addr);
1176 val -= (addr + 4);
1177 val += 3;
1178 val /= 4;
1179 if (val & ~0xff)
1180 as_warn ("pcrel too far at %x\n", addr);
1181
1182 *buf = val;
1183 break;
1184
1185 case R_SH_PCRELIMM8BY2:
1186 addr &= ~1;
1187 if (val & 0x1)
1188 as_bad ("odd displacement at %x\n", addr);
1189 val -= (addr + 4);
1190 val++;
1191 val /= 2;
1192 if (val & ~0xff)
1193 as_warn ("pcrel too far at %x\n", addr);
1194 *buf = val;
1195 break;
1196
1197 case R_SH_IMM32:
1198 *buf++ = val >> 24;
1199 *buf++ = val >> 16;
1200 *buf++ = val >> 8;
1201 *buf++ = val >> 0;
1202 break;
1203
1204 default:
1205 abort ();
1206 }
1207 }
1208
1209 void
1210 DEFUN (md_operand, (expressionP), expressionS * expressionP)
1211 {
1212 }
1213
1214 int md_long_jump_size;
1215
1216 /*
1217 called just before address relaxation, return the length
1218 by which a fragment must grow to reach it's destination
1219 */
1220 int
1221 md_estimate_size_before_relax (fragP, segment_type)
1222 register fragS *fragP;
1223 register segT segment_type;
1224 {
1225 switch (fragP->fr_subtype)
1226 {
1227 case C (UNCOND_JUMP, UNDEF_DISP):
1228 /* used to be a branch to somewhere which was unknown */
1229 if (!fragP->fr_symbol)
1230 {
1231 fragP->fr_subtype = C (UNCOND_JUMP, UNCOND12);
1232 fragP->fr_var = md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length;
1233 }
1234 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1235 {
1236 fragP->fr_subtype = C (UNCOND_JUMP, UNCOND12);
1237 fragP->fr_var = md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length;
1238 }
1239 else
1240 {
1241 fragP->fr_subtype = C (UNCOND_JUMP, UNDEF_WORD_DISP);
1242 fragP->fr_var = md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length;
1243 return md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length;
1244 }
1245 break;
1246
1247 default:
1248 abort ();
1249 case C (COND_JUMP, UNDEF_DISP):
1250 /* used to be a branch to somewhere which was unknown */
1251 if (fragP->fr_symbol
1252 && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1253 {
1254 /* Got a symbol and it's defined in this segment, become byte
1255 sized - maybe it will fix up */
1256 fragP->fr_subtype = C (COND_JUMP, COND8);
1257 fragP->fr_var = md_relax_table[C (COND_JUMP, COND8)].rlx_length;
1258 }
1259 else if (fragP->fr_symbol)
1260 {
1261 /* Its got a segment, but its not ours, so it will always be long */
1262 fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
1263 fragP->fr_var = md_relax_table[C (COND_JUMP, COND32)].rlx_length;
1264 return md_relax_table[C (COND_JUMP, COND32)].rlx_length;
1265 }
1266 else
1267 {
1268 /* We know the abs value */
1269 fragP->fr_subtype = C (COND_JUMP, COND8);
1270 fragP->fr_var = md_relax_table[C (COND_JUMP, COND8)].rlx_length;
1271 }
1272
1273 break;
1274 }
1275 return fragP->fr_var;
1276 }
1277
1278 /* Put number into target byte order */
1279
1280 void
1281 md_number_to_chars (ptr, use, nbytes)
1282 char *ptr;
1283 valueT use;
1284 int nbytes;
1285 {
1286 switch (nbytes)
1287 {
1288 case 4:
1289 *ptr++ = (use >> 24) & 0xff;
1290 case 3:
1291 *ptr++ = (use >> 16) & 0xff;
1292 case 2:
1293 *ptr++ = (use >> 8) & 0xff;
1294 case 1:
1295 *ptr++ = (use >> 0) & 0xff;
1296 break;
1297 default:
1298 abort ();
1299 }
1300 }
1301 long
1302 md_pcrel_from (fixP)
1303 fixS *fixP;
1304
1305 {
1306 int gap = fixP->fx_size + fixP->fx_where +
1307 fixP->fx_frag->fr_address;
1308 return gap;
1309 }
1310
1311 void
1312 tc_coff_symbol_emit_hook ()
1313 {
1314 }
1315
1316 short
1317 tc_coff_fix2rtype (fix_ptr)
1318 fixS *fix_ptr;
1319 {
1320 return fix_ptr->fx_r_type;
1321 }
1322
1323 void
1324 tc_reloc_mangle (fix_ptr, intr, base)
1325 fixS *fix_ptr;
1326 struct internal_reloc *intr;
1327 bfd_vma base;
1328
1329 {
1330 symbolS *symbol_ptr;
1331
1332 symbol_ptr = fix_ptr->fx_addsy;
1333
1334 /* If this relocation is attached to a symbol then it's ok
1335 to output it */
1336 if (fix_ptr->fx_r_type == RELOC_32)
1337 {
1338 /* cons likes to create reloc32's whatever the size of the reloc..
1339 */
1340 switch (fix_ptr->fx_size)
1341 {
1342 case 2:
1343 intr->r_type = R_IMM16;
1344 break;
1345 case 1:
1346 intr->r_type = R_IMM8;
1347 break;
1348 default:
1349 abort ();
1350 }
1351 }
1352 else
1353 {
1354 intr->r_type = fix_ptr->fx_r_type;
1355 }
1356
1357 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1358 intr->r_offset = fix_ptr->fx_offset;
1359
1360 /* Turn the segment of the symbol into an offset. */
1361 if (symbol_ptr)
1362 {
1363 symbolS *dot;
1364
1365 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
1366 if (dot)
1367 {
1368 intr->r_offset += S_GET_VALUE (symbol_ptr);
1369 intr->r_symndx = dot->sy_number;
1370 }
1371 else
1372 {
1373 intr->r_symndx = symbol_ptr->sy_number;
1374 }
1375 }
1376 else
1377 {
1378 intr->r_symndx = -1;
1379 }
1380 }
1381
1382 int
1383 tc_coff_sizemachdep (frag)
1384 fragS *frag;
1385 {
1386 return md_relax_table[frag->fr_subtype].rlx_length;
1387 }
1388
1389
1390 /* end of tc-sh.c */
This page took 0.061375 seconds and 4 git commands to generate.