* config/tc-sh.h (struct sh_segment_info_type): Define.
[deliverable/binutils-gdb.git] / gas / config / tc-rce.c
1 /* tc-rce.c -- Assemble code for the Experimental RCE
2
3 Copyright (C) 1993,1994 Free Software Foundation.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 /*
22 Adapted from the SH assember
23 Relocation doesnt work yet.
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/rce-opc.h"
32 #include <ctype.h>
33 #include <string.h>
34
35 #if 1 /**** TEMP ****/
36 #define R_PCRELIMM8BY4 23 /* 8 bit pc relative to long boundary shifted 4 */
37 #define R_PCRELIMM11BY2 24 /* 11 bit pc relative to long boundary shifted 2 */
38 #endif /**** TEMP ****/
39
40 const char comment_chars[] = "!";
41 const char line_separator_chars[] = ";";
42 const char line_comment_chars[] = "!";
43
44 /* This table describes all the machine specific pseudo-ops the assembler
45 has to support. The fields are:
46 pseudo-op name without dot
47 function to call to execute this pseudo-op
48 Integer arg to pass to the function
49 */
50
51 void cons ();
52 void s_align_bytes ();
53
54 const pseudo_typeS md_pseudo_table[] =
55 {
56 {"page", listing_eject, 0},
57 {0, 0, 0}
58 };
59
60 const int md_reloc_size = 8;
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 JREG 0 /* Register used as a temp when relaxing */
72 #define C(what,length) (((what) << 2) + (length))
73 #define GET_WHAT(x) ((x>>2))
74
75 /* These are the two types of relaxable instruction */
76 #define COND_JUMP 1
77 #define UNCD_JUMP 2
78
79 #define UNDEF_DISP 0
80 #define COND12 1
81 #define COND32 2
82 #define UNCD12 1
83 #define UNCD32 2
84 #define UNDEF_WORD_DISP 4
85 #define END 5
86
87 #define C12_LEN 2
88 #define C32_LEN 10 /* allow for align */
89 #define U12_LEN 2
90 #define U32_LEN 8 /* allow for align */
91
92
93 /* Initialize the relax table */
94 const relax_typeS md_relax_table[] =
95 {
96 { 1, 1, 0, 0 }, /* 0: unused */
97 { 1, 1, 0, 0 }, /* 1: unused */
98 { 1, 1, 0, 0 }, /* 2: unused */
99 { 1, 1, 0, 0 }, /* 3: unused */
100 { 1, 1, 0, 0 }, /* 4: unused */
101 { 2048, -2046, C12_LEN, C(COND_JUMP, COND32) }, /* 5: C(COND_JUMP, COND12) */
102 { 0, 0, C32_LEN, 0 }, /* 6: C(COND_JUMP, COND32) */
103 { 1, 1, 0, 0 }, /* 7: unused */
104 { 1, 1, 0, 0 }, /* 8: unused */
105 { 2048, -2046, U12_LEN, C(UNCD_JUMP, UNCD32) }, /* 9: C(UNCD_JUMP, UNCD12) */
106 { 0, 0, U32_LEN, 0 }, /*10: C(UNCD_JUMP, UNCD32) */
107 { 1, 1, 0, 0 }, /*11: unused */
108 };
109
110 static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
111
112 /*
113 This function is called once, at assembler startup time. This should
114 set up all the tables, etc that the MD part of the assembler needs
115 */
116
117 void
118 md_begin ()
119 {
120 rce_opcode_info *opcode;
121 char *prev_name = "";
122
123 opcode_hash_control = hash_new ();
124
125 /* Insert unique names into hash table */
126 for (opcode = rce_table; opcode->name; opcode++)
127 {
128 if (strcmp (prev_name, opcode->name))
129 {
130 prev_name = opcode->name;
131 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
132 }
133 else
134 {
135 /* Make all the opcodes with the same name point to the same
136 string */
137 opcode->name = prev_name;
138 }
139 }
140 }
141
142 static int reg_m;
143 static int reg_n;
144 static expressionS immediate; /* absolute expression */
145
146 /* try and parse a reg name */
147 static char *
148 parse_reg (s, reg)
149 char *s;
150 unsigned *reg;
151 {
152 if ( tolower(s[0]) == 'r')
153 {
154 if (s[1] == '1' && s[2] >= '0' && s[2] <= '5')
155 {
156 *reg = 10 + s[2] - '0';
157 return s+3;
158 }
159 if (s[1] >= '0' && s[1] <= '9')
160 {
161 *reg = (s[1] - '0');
162 return s+2;
163 }
164 }
165 as_bad("register expected");
166 return s;
167 }
168
169 static struct Cregs {
170 char *name;
171 unsigned int crnum;
172 } cregs[] = {
173 {"psr", 0},
174 {"epsr", 1},
175 {"fpsr", 2},
176 {"epc", 3},
177 {"fpc", 4},
178 {"ss0", 5},
179 {"ss1", 6},
180 {"ss2", 7},
181 {"ss3", 8},
182 {"aar", 9},
183 {"gcr", 10},
184 {"gsr", 11},
185 {"", 0}
186 };
187
188 static char *
189 parse_creg (s, reg)
190 char *s;
191 unsigned *reg;
192 {
193 char buf[10];
194 int i,j,length;
195
196 if ( (tolower(s[0]) == 'c' && tolower(s[1]) == 'r') )
197 {
198 if (s[2] == '3' && s[3] >= '0' && s[3] <= '1')
199 {
200 *reg = 30 + s[3] - '0';
201 return s+4;
202 }
203 if (s[2] == '2' && s[3] >= '0' && s[3] <= '9')
204 {
205 *reg = 20 + s[3] - '0';
206 return s+4;
207 }
208 if (s[2] == '1' && s[3] >= '0' && s[3] <= '9')
209 {
210 *reg = 10 + s[3] - '0';
211 return s+4;
212 }
213 if (s[2] >= '0' && s[2] <= '9')
214 {
215 *reg = (s[2] - '0');
216 return s+3;
217 }
218 }
219 /** look at alternate creg names before giving error **/
220 for(i=0; *(cregs[i].name)!='\0'; i++) {
221 length=strlen(cregs[i].name);
222 for(j=0; j<length; j++) buf[j]=tolower(s[j]);
223 if ( strncmp(cregs[i].name,buf,length)==0 ) {
224 *reg=cregs[i].crnum;
225 return( s+length );
226 }
227 }
228 as_bad("register expected");
229 return s;
230 }
231
232 static char *
233 parse_exp(s)
234 char *s;
235 { char *save;
236 char *new;
237
238 save = input_line_pointer;
239 input_line_pointer = s;
240 expression(&immediate);
241 if (immediate.X_op == O_absent)
242 as_bad("missing operand");
243 new = input_line_pointer;
244 input_line_pointer = save;
245 return new;
246 }
247
248 static char *
249 parse_imm(s, val, min, max)
250 char *s;
251 unsigned *val;
252 unsigned min, max;
253 { char *new;
254
255 new = parse_exp(s);
256 if (immediate.X_op != O_constant
257 || immediate.X_add_number < min
258 || immediate.X_add_number > max)
259 {
260 as_bad ("operand must be absolute in range %d..%d", min, max);
261 }
262 *val = immediate.X_add_number;
263 return new;
264 }
265
266 /* look for immediate notation '#' */
267 static char *
268 parse_imm_notation(s)
269 char *s;
270 {
271 static int isa_imm;
272
273 if( s == (char *)(NULL) ) return( (char *)(isa_imm) );
274 isa_imm=0;
275 while( isspace(*s) )
276 s++;
277 if( *s=='#' ) {
278 isa_imm=1;
279 s++;
280 }
281 return(s);
282 }
283
284 static char *
285 parse_mem(s, reg, off, siz)
286 char *s;
287 unsigned *reg;
288 unsigned *off;
289 unsigned siz;
290 { char *new;
291 char *parse_imm_notation();
292
293 if (*s == '(')
294 { s = parse_reg(s+1, reg);
295 if (*s == ',')
296 {
297 s = parse_imm_notation(s+1);
298 if( parse_imm_notation(NULL) ) siz=1;
299 s = parse_imm(s, off, 0, 63);
300 if (siz > 1)
301 { if (siz > 2)
302 {
303 if (*off & 0x3)
304 as_bad ("operand must be a multiple of 4");
305 *off >>= 2;
306 }
307 else
308 {
309 if (*off & 0x1)
310 as_bad ("operand must be a multiple of 2");
311 *off >>= 1;
312 }
313 }
314 }
315 else
316 *off = 0;
317 if (*s == ')')
318 s++;
319 }
320 else
321 as_bad("base register expected");
322 return s;
323 }
324
325
326 /* This is the guts of the machine-dependent assembler. STR points to a
327 machine dependent instruction. This function is supposed to emit
328 the frags/bytes it assembles to.
329 */
330
331 void
332 md_assemble (str)
333 char *str;
334 {
335 char *op_start;
336 char *op_end;
337 rce_opcode_info *opcode;
338 char *output;
339 int nlen = 0;
340 unsigned short inst;
341 unsigned reg, off;
342 char name[20];
343
344 /* Drop leading whitespace */
345 while (*str == ' ')
346 str++;
347
348 /* find the op code end */
349 for (op_start = op_end = str;
350 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
351 op_end++)
352 {
353 name[nlen] = op_start[nlen];
354 nlen++;
355 }
356 name[nlen] = 0;
357 if (nlen == 0)
358 {
359 as_bad ("can't find opcode ");
360 return;
361 }
362
363 opcode = (rce_opcode_info *) hash_find (opcode_hash_control, name);
364 if (opcode == NULL)
365 {
366 as_bad ("unknown opcode \"%s\"", name);
367 return;
368 }
369 inst = opcode->inst;
370 switch (opcode->opclass)
371 { case O0:
372 output = frag_more (2);
373 break;
374 case OT:
375 op_end = parse_imm_notation(op_end + 1);
376 op_end = parse_imm(op_end, &reg, 0, 7);
377 inst |= reg;
378 output = frag_more (2);
379 break;
380 case O1:
381 op_end = parse_reg (op_end + 1, &reg);
382 inst |= reg;
383 output = frag_more (2);
384 break;
385 case JSR:
386 op_end = parse_reg (op_end + 1, &reg);
387 if(reg==15)
388 as_bad("invalid register specified -> r15");
389 inst |= reg;
390 output = frag_more (2);
391 break;
392 case OC:
393 op_end = parse_reg (op_end + 1, &reg);
394 inst |= reg;
395 if (*op_end == ',')
396 { op_end = parse_creg(op_end + 1, &reg);
397 inst |= reg<<4;
398 }
399 output = frag_more (2);
400 break;
401 case O2:
402 op_end = parse_reg (op_end + 1, &reg);
403 inst |= reg;
404 if (*op_end == ',')
405 { op_end = parse_reg(op_end + 1, &reg);
406 inst |= reg<<4;
407 }
408 else
409 as_bad("second operand missing");
410 output = frag_more (2);
411 break;
412 case X1: /** handle both syntax-> xtrb- r1,rx OR xtrb- rx **/
413 op_end = parse_reg (op_end + 1, &reg);
414 if (*op_end == ',') { /** xtrb- r1,rx **/
415 if (reg != 1)
416 as_bad("destination register must be r1");
417 op_end = parse_reg(op_end + 1, &reg);
418 }
419 else { /** xtrb- rx **/
420 }
421 inst |= reg;
422 output = frag_more (2);
423 break;
424 case OI:
425 op_end = parse_reg (op_end + 1, &reg);
426 inst |= reg;
427 if (*op_end == ',')
428 { unsigned int maxval = 32;
429 unsigned int minval = 1;
430 op_end = parse_imm_notation(op_end + 1);
431 if( parse_imm_notation(NULL) ) {
432 maxval=31;
433 minval=0;
434 }
435 op_end = parse_imm(op_end, &reg, minval, maxval);
436 inst |= (reg-minval)<<4;
437 }
438 else
439 as_bad("second operand missing");
440 output = frag_more (2);
441 break;
442 case OB:
443 op_end = parse_reg (op_end + 1, &reg);
444 inst |= reg;
445 if (*op_end == ',')
446 { unsigned upper = 31;
447 op_end = parse_imm_notation(op_end + 1);
448 op_end = parse_imm(op_end, &reg, 0, upper);
449 inst |= reg<<4;
450 }
451 else
452 as_bad("second operand missing");
453 output = frag_more (2);
454 break;
455 case SI:
456 op_end = parse_reg (op_end + 1, &reg);
457 inst |= reg;
458 if (*op_end == ',')
459 { unsigned upper = 31;
460 op_end = parse_imm_notation(op_end + 1);
461 op_end = parse_imm(op_end, &reg, 1, upper);
462 inst |= reg<<4;
463 }
464 else
465 as_bad("second operand missing");
466 output = frag_more (2);
467 break;
468 case I7:
469 op_end = parse_reg (op_end + 1, &reg);
470 inst |= reg;
471 if (*op_end == ',')
472 { unsigned upper = 0x7f;
473 op_end = parse_imm_notation(op_end + 1);
474 op_end = parse_imm(op_end, &reg, 0, upper);
475 inst |= reg<<4;
476 }
477 else
478 as_bad("second operand missing");
479 output = frag_more (2);
480 break;
481 case LS:
482 op_end = parse_reg(op_end + 1, &reg);
483 inst |= reg<<8;
484 if (*op_end == ',')
485 {
486 int size;
487 if ((inst & 0x6000) == 0)
488 size = 4;
489 else if ((inst & 0x6000) == 0x4000)
490 size = 2;
491 else if ((inst & 0x6000) == 0x2000)
492 size = 1;
493 op_end = parse_mem(op_end + 1, &reg, &off, size);
494 inst |= (reg) | (off<<4);
495 }
496 else
497 as_bad("second operand missing");
498 output = frag_more (2);
499 break;
500 case LI:
501 op_end = parse_reg (op_end + 1, &reg);
502 if (*op_end == ',')
503 { unsigned val;
504 op_end = parse_imm_notation(op_end + 1);
505 op_end = parse_imm(op_end, &val, 0, 0x7FF);
506 inst |= val&0x7FF;
507 }
508 else
509 as_bad("second operand missing");
510 if (reg != 1)
511 as_bad("register must be r1");
512 output = frag_more (2);
513 break;
514 case LR:
515 op_end = parse_reg(op_end + 1, &reg);
516 if( reg==0 || reg==15 )
517 as_bad ("invalid register 'r0' and 'r15' illegal");
518 inst |= (reg<<8);
519 if (*op_end++ == ',')
520 {
521 /** look for # notation **/
522 op_end = parse_imm_notation(op_end);
523 if( parse_imm_notation(NULL) )
524 { unsigned val;
525 op_end = parse_imm(op_end, &val, 0, 0x0FF);
526 inst |= val&0x0FF;
527 output = frag_more (2);
528 }
529 else
530 {
531 output = frag_more (2);
532 if (*op_end++ != '[' )
533 as_bad ("second operand missing '['");
534 input_line_pointer = parse_exp(op_end);
535 if (*input_line_pointer++ != ']' )
536 as_bad ("second operand missing ']'");
537 fix_new_exp(frag_now, output-frag_now->fr_literal, 2, &immediate,
538 1, R_PCRELIMM8BY4);
539 }
540 }
541 else
542 as_bad("second operand missing");
543 break;
544 case LJ:
545 /** look for # notation **/
546 op_end = parse_imm_notation(op_end + 1) -1;
547 if( parse_imm_notation(NULL) )
548 { unsigned val;
549 op_end = parse_imm(op_end+1, &val, 0, 0x0FF);
550 inst |= val&0x0FF;
551 output = frag_more (2);
552 }
553 else
554 { output = frag_more (2);
555 if (*++op_end != '[')
556 as_bad ("operand missing '['");
557 input_line_pointer = parse_exp(op_end+1);
558 if (*input_line_pointer++ != ']')
559 as_bad ("operand missing ']'");
560 fix_new_exp(frag_now, output-frag_now->fr_literal,
561 2, &immediate, 1, R_PCRELIMM8BY4);
562 }
563 break;
564 case OM:
565 op_end = parse_reg(op_end + 1, &reg);
566 if (*op_end == '-')
567 { int endreg;
568 op_end = parse_reg(op_end + 1, &endreg);
569 if (*op_end == ',')
570 { int basereg;
571 op_end++;
572 if (*op_end == '(')
573 { op_end = parse_reg(op_end + 1, &basereg);
574 if (*op_end == ')')
575 op_end++;
576 if (endreg == 15 && basereg == 0)
577 {
578 if(reg==0 || reg==15)
579 as_bad("bad register list, 'r0' and 'r15' invalid as starting registers");
580 inst |= 0x0080; /* list form */
581 inst |= reg;
582 }
583 else if (endreg - reg == 3)
584 { inst |= basereg; /* quadrant form */
585 switch (reg)
586 { case 0: break;
587 case 4: inst |= (1<<5); break;
588 case 8: inst |= (2<<5); break;
589 case 12: inst |= (3<<5); break;
590 default:
591 as_bad("first register must be r0, r4, r8, or r12");
592 }
593 }
594 else
595 as_bad("bad register list or base register");
596 }
597 else
598 as_bad("base register expected");
599 }
600 else
601 as_bad("second operand missing");
602 }
603 else
604 as_bad("reg-reg expected");
605 output = frag_more (2);
606 break;
607 case OQ:
608 op_end = parse_reg(op_end + 1, &reg);
609 if (*op_end == '-')
610 { int endreg;
611 op_end = parse_reg(op_end + 1, &endreg);
612 if (*op_end == ',')
613 { int basereg;
614 op_end++;
615 if (*op_end == '(')
616 { op_end = parse_reg(op_end + 1, &basereg);
617 if (*op_end == ')')
618 op_end++;
619 if (endreg - reg == 3)
620 { inst |= basereg; /* quadrant form */
621 switch (reg)
622 { case 0: break;
623 case 4: inst |= (1<<5); break;
624 case 8: inst |= (2<<5); break;
625 case 12: inst |= (3<<5); break;
626 default:
627 as_bad("first register must be r0, r4, r8, or r12");
628 }
629 }
630 else
631 as_bad("bad register list or base register");
632 }
633 else
634 as_bad("base register expected");
635 }
636 else
637 as_bad("second operand missing");
638 }
639 else
640 as_bad("reg-reg expected");
641 output = frag_more (2);
642 break;
643 case BR:
644 op_end = parse_imm_notation(op_end + 1);
645 if( parse_imm_notation(NULL) )
646 { unsigned val;
647 op_end = parse_imm(op_end, &val, 0, 0x7FF);
648 inst |= val&0x7FF;
649 output = frag_more (2);
650 }
651 else
652 { output = frag_more (2);
653 input_line_pointer = parse_exp(op_end);
654 fix_new_exp (frag_now, output-frag_now->fr_literal,
655 2, &immediate, 1, R_PCRELIMM11BY2);
656 }
657 break;
658 default:
659 as_bad("cant deal with opcode \"%s\"", name);
660 }
661 output[0] = (inst>>8);
662 output[1] = (inst);
663 }
664
665 #ifndef BFD_ASSEMBLER
666 void
667 DEFUN (tc_crawl_symbol_chain, (headers),
668 object_headers * headers)
669 {
670 }
671
672 void
673 DEFUN (tc_headers_hook, (headers),
674 object_headers * headers)
675 {
676 }
677 #endif
678
679 symbolS *
680 DEFUN (md_undefined_symbol, (name),
681 char *name)
682 {
683 return 0;
684 }
685
686 /* Various routines to kill one day */
687 /* Equal to MAX_PRECISION in atof-ieee.c */
688 #define MAX_LITTLENUMS 6
689
690 /* Turn a string in input_line_pointer into a floating point constant of type
691 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
692 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
693 */
694 char *
695 md_atof (type, litP, sizeP)
696 char type;
697 char *litP;
698 int *sizeP;
699 {
700 int prec;
701 LITTLENUM_TYPE words[MAX_LITTLENUMS];
702 LITTLENUM_TYPE *wordP;
703 char *t;
704 char *atof_ieee ();
705
706 switch (type)
707 {
708 case 'f':
709 case 'F':
710 case 's':
711 case 'S':
712 prec = 2;
713 break;
714
715 case 'd':
716 case 'D':
717 case 'r':
718 case 'R':
719 prec = 4;
720 break;
721
722 case 'x':
723 case 'X':
724 prec = 6;
725 break;
726
727 case 'p':
728 case 'P':
729 prec = 6;
730 break;
731
732 default:
733 *sizeP = 0;
734 return "Bad call to MD_NTOF()";
735 }
736 t = atof_ieee (input_line_pointer, type, words);
737 if (t)
738 input_line_pointer = t;
739
740 *sizeP = prec * sizeof (LITTLENUM_TYPE);
741 for (wordP = words; prec--;)
742 {
743 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
744 litP += sizeof (LITTLENUM_TYPE);
745 }
746 return 0;
747 }
748 \f
749 CONST char *md_shortopts = "";
750 struct option md_longopts[] = {
751
752 #define OPTION_RELAX (OPTION_MD_BASE)
753 #define OPTION_LITTLE (OPTION_MD_BASE+1)
754
755 {"relax", no_argument, NULL, OPTION_RELAX},
756 {"little", no_argument, NULL, OPTION_LITTLE},
757 {NULL, no_argument, NULL, 0}
758 };
759 size_t md_longopts_size = sizeof(md_longopts);
760
761 int
762 md_parse_option (c, arg)
763 int c;
764 char *arg;
765 {
766 switch (c)
767 {
768 case OPTION_RELAX:
769 relax = 1;
770 break;
771 case OPTION_LITTLE:
772 abort ();
773 break;
774
775 default:
776 return 0;
777 }
778
779 return 1;
780 }
781
782 void
783 md_show_usage (stream)
784 FILE *stream;
785 {
786 fprintf(stream, "\
787 RCE options:\n\
788 -relax alter jump instructions for long displacements\n");
789 }
790 \f
791 int md_short_jump_size;
792
793 void
794 tc_Nout_fix_to_chars ()
795 {
796 as_fatal ("call to tc_Nout_fix_to_chars");
797 }
798
799 void
800 md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
801 char *ptr;
802 addressT from_Nddr;
803 addressT to_Nddr;
804 fragS *frag;
805 symbolS *to_symbol;
806 {
807 as_fatal ("failed sanity check: short_jump");
808 }
809
810 void
811 md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
812 char *ptr;
813 addressT from_Nddr, to_Nddr;
814 fragS *frag;
815 symbolS *to_symbol;
816 {
817 as_fatal ("failed sanity check: long_jump");
818 }
819
820 /*
821 called after relaxing, change the frags so they know how big they are
822 */
823 #ifndef BFD_ASSEMBLER
824 void
825 md_convert_frag (headers, seg, fragP)
826 object_headers *headers;
827 segT seg;
828 register fragS *fragP;
829 #else
830 void
831 md_convert_frag (abfd, sec, fragP)
832 bfd *abfd;
833 segT sec;
834 register fragS *fragP;
835 #endif
836 {
837 unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
838 int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
839 #ifdef BFD_ASSEMBLER /* not needed otherwise? */
840 targ_addr += fragP->fr_symbol->sy_frag->fr_address;
841 #endif
842 switch (fragP->fr_subtype)
843 {
844 case C (COND_JUMP, COND12):
845 case C (UNCD_JUMP, UNCD12):
846 {
847 /* Get the address of the end of the instruction */
848 int next_inst = fragP->fr_fix + fragP->fr_address + 2;
849 unsigned char t0;
850 int disp = targ_addr - next_inst;
851 if (disp&1)
852 as_bad("odd displacement at %x", next_inst-2);
853 if (disp < 0) /* move sign to low order bit */
854 disp |= 1;
855 t0 = buffer[0] & 0xF8;
856 md_number_to_chars (buffer, disp, 2);
857 buffer[0] = (buffer[0] & 0x07) | t0;
858 fragP->fr_fix += 2;
859 fragP->fr_var = 0;
860 }
861 break;
862
863 case C (COND_JUMP, COND32):
864 case C (COND_JUMP, UNDEF_WORD_DISP):
865 {
866 /* A conditional branch wont fit into 12 bits so:
867 * b!cond 1f
868 * jmpi 0f
869 * .align 2
870 * 0: .long disp
871 * 1:
872 */
873 int next_inst = fragP->fr_fix + fragP->fr_address + C32_LEN;
874 int align = next_inst&02;
875 buffer[0] ^= 0x08; /* Toggle T/F bit */
876 buffer[2] = 0x73; /* Build jmpi */
877 buffer[3] = 0x00;
878 if (align)
879 {
880 buffer[1] = 3; /* branch over jmpi, and ptr */
881 buffer[4] = 0; /* space for 32 bit address */
882 buffer[5] = 0;
883 buffer[6] = 0;
884 buffer[7] = 0;
885 /* Make reloc for the long disp */
886 fix_new(fragP, fragP->fr_fix + 4, 4,
887 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
888 #if 0
889 /**** frag has shrunk but gas can't deal with that */
890 fragP->fr_fix += C32_LEN - 2;
891 #else
892 fragP->fr_fix += C32_LEN;
893 #endif
894 }
895 else
896 {
897 buffer[1] = 4; /* branch over jmpi, and ptr */
898 buffer[4] = 0; /* alignment */
899 buffer[5] = 0;
900 buffer[6] = 0; /* space for 32 bit address */
901 buffer[7] = 0;
902 buffer[8] = 0;
903 buffer[9] = 0;
904 /* Make reloc for the long disp */
905 fix_new(fragP, fragP->fr_fix + 6, 4,
906 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
907 fragP->fr_fix += C32_LEN;
908 }
909 fragP->fr_var = 0;
910 }
911 break;
912
913 case C (UNCD_JUMP, UNCD32):
914 case C (UNCD_JUMP, UNDEF_WORD_DISP):
915 {
916 /* An unconditional branch wont fit in 12 bits, make code which looks like
917 * jmpi 0f
918 * .align 2
919 * 0: .long disp
920 */
921 int next_inst = fragP->fr_fix + fragP->fr_address + U32_LEN;
922 int align = next_inst&02;
923 buffer[0] = 0x73; /* build jmpi */
924 buffer[1] = 0x00;
925 if (align)
926 {
927 buffer[2] = 0; /* space for 32 bit address */
928 buffer[3] = 0;
929 buffer[4] = 0;
930 buffer[5] = 0;
931 /* Make reloc for the long disp */
932 fix_new (fragP, fragP->fr_fix + 2, 4,
933 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
934 #if 0
935 /**** frag has shrunk but gas can't deal with that */
936 fragP->fr_fix += U32_LEN - 2;
937 #else
938 fragP->fr_fix += U32_LEN;
939 #endif
940 }
941 else
942 {
943 buffer[2] = 0; /* alignment */
944 buffer[3] = 0;
945 buffer[4] = 0; /* space for 32 bit address */
946 buffer[5] = 0;
947 buffer[6] = 0;
948 buffer[7] = 0;
949 /* Make reloc for the long disp */
950 fix_new (fragP, fragP->fr_fix + 4, 4,
951 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
952 fragP->fr_fix += U32_LEN;
953 }
954 fragP->fr_var = 0;
955 }
956 break;
957
958 default:
959 abort ();
960 }
961 }
962
963 void
964 md_apply_fix1 (fixP, val)
965 fixS *fixP;
966 long val;
967 {
968 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
969 int addr = fixP->fx_frag->fr_address + fixP->fx_where;
970
971 switch (fixP->fx_r_type)
972 {
973 case R_PCRELIMM11BY2: /* second byte of 2 byte opcode */
974 val /= 2;
975 if (((val & ~0x3ff) != 0) && ((val | 0x3ff) != -1))
976 as_warn ("pcrel for branch too far (0x%x) at 0x%x", val, addr);
977 /*****
978 BR no longer puts the sign-bit in bit0, leaves it in bit10
979 buf[0] |= ((val >> 7) & 0x7);
980 buf[1] |= ((val & 0x7f) << 1);
981 buf[1] |= ((val >> 10) & 0x1);
982 *****/
983 buf[0] |= ((val >> 8) & 0x7);
984 buf[1] |= (val & 0xff);
985 break;
986 case R_PCRELIMM8BY4: /* lower 8 bits of 2 byte opcode */
987 val += 3;
988 val /= 4;
989 if (val & ~0xff)
990 as_warn ("pcrel for lrw too far (0x%x) at 0x%x", val, addr);
991 buf[1] |= (val & 0xff);
992 break;
993 default:
994 if (fixP->fx_size != 4)
995 abort ();
996 *buf++ = val >> 24;
997 *buf++ = val >> 16;
998 *buf++ = val >> 8;
999 *buf = val >> 0;
1000 break;
1001 }
1002 }
1003
1004 #ifdef BFD_ASSEMBLER
1005 int
1006 md_apply_fix (fixP, valp)
1007 fixS *fixP;
1008 valueT *valp;
1009 {
1010 md_apply_fix1 (fixP, *valp);
1011 return 1;
1012 }
1013 #else
1014 void
1015 md_apply_fix (fixP, val)
1016 fixS *fixP;
1017 long val;
1018 {
1019 md_apply_fix1 (fixP, val);
1020 }
1021 #endif
1022
1023 int md_long_jump_size;
1024
1025 /*
1026 called just before address relaxation, return the length
1027 by which a fragment must grow to reach it's destination
1028 */
1029 int
1030 md_estimate_size_before_relax (fragP, segment_type)
1031 register fragS *fragP;
1032 register segT segment_type;
1033 {
1034 switch (fragP->fr_subtype)
1035 {
1036 case C (UNCD_JUMP, UNDEF_DISP):
1037 /* used to be a branch to somewhere which was unknown */
1038 if (!fragP->fr_symbol)
1039 {
1040 fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
1041 fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
1042 }
1043 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1044 {
1045 fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
1046 fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
1047 }
1048 else
1049 {
1050 fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);
1051 fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
1052 return md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
1053 }
1054 break;
1055
1056 default:
1057 abort ();
1058 case C (COND_JUMP, UNDEF_DISP):
1059 /* used to be a branch to somewhere which was unknown */
1060 if (fragP->fr_symbol
1061 && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1062 {
1063 /* Got a symbol and it's defined in this segment, become byte
1064 sized - maybe it will fix up */
1065 fragP->fr_subtype = C (COND_JUMP, COND12);
1066 fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
1067 }
1068 else if (fragP->fr_symbol)
1069 {
1070 /* Its got a segment, but its not ours, so it will always be long */
1071 fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
1072 fragP->fr_var = md_relax_table[C (COND_JUMP, COND32)].rlx_length;
1073 return md_relax_table[C (COND_JUMP, COND32)].rlx_length;
1074 }
1075 else
1076 {
1077 /* We know the abs value */
1078 fragP->fr_subtype = C (COND_JUMP, COND12);
1079 fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
1080 }
1081
1082 break;
1083 }
1084 return fragP->fr_var;
1085 }
1086
1087 /* Put number into target byte order */
1088
1089 void
1090 md_number_to_chars (ptr, use, nbytes)
1091 char *ptr;
1092 valueT use;
1093 int nbytes;
1094 {
1095 switch (nbytes)
1096 {
1097 case 4:
1098 *ptr++ = (use >> 24) & 0xff;
1099 case 3:
1100 *ptr++ = (use >> 16) & 0xff;
1101 case 2:
1102 *ptr++ = (use >> 8) & 0xff;
1103 case 1:
1104 *ptr++ = (use >> 0) & 0xff;
1105 break;
1106 default:
1107 abort ();
1108 }
1109 }
1110
1111
1112 /* Round up a section size to the appropriate boundary. */
1113 valueT
1114 md_section_align (segment, size)
1115 segT segment;
1116 valueT size;
1117 {
1118 return size; /* Byte alignment is fine */
1119 }
1120
1121
1122 long
1123 md_pcrel_from (fixP)
1124 fixS *fixP;
1125
1126 {
1127 int gap = fixP->fx_size + fixP->fx_where +
1128 fixP->fx_frag->fr_address;
1129 return gap;
1130 }
1131
1132 void
1133 dump_literals (i)
1134 int i;
1135 {
1136 /* does nothing for now. */
1137 }
1138
1139 #ifdef BFD_ASSEMBLER
1140
1141 arelent *
1142 tc_gen_reloc (section, fixp)
1143 asection *section;
1144 fixS *fixp;
1145 {
1146 arelent *rel;
1147 bfd_reloc_code_real_type code;
1148
1149 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1150 switch (F (fixp->fx_size, fixp->fx_pcrel))
1151 {
1152 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1153 MAP (1, 0, BFD_RELOC_8);
1154 MAP (2, 0, BFD_RELOC_16);
1155 MAP (4, 0, BFD_RELOC_32);
1156 MAP (1, 1, BFD_RELOC_8_PCREL);
1157 MAP (2, 1, BFD_RELOC_16_PCREL);
1158 MAP (4, 1, BFD_RELOC_32_PCREL);
1159 default:
1160 as_bad ("Can not do %d byte %srelocation", fixp->fx_size,
1161 fixp->fx_pcrel ? "pc-relative" : "");
1162 }
1163
1164 rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
1165 assert (rel != 0);
1166 rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1167 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
1168 if (fixp->fx_pcrel)
1169 rel->addend = fixp->fx_addnumber;
1170 else
1171 rel->addend = 0;
1172
1173 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1174 if (!rel->howto)
1175 {
1176 const char *name;
1177
1178 name = S_GET_NAME (fixp->fx_addsy);
1179 if (name == NULL)
1180 name = "<unknown>";
1181 as_fatal ("Cannot find relocation type for symbol %s, code %d",
1182 name, (int) code);
1183 }
1184
1185 return rel;
1186 }
1187
1188 #else /* !BFD_ASSEMBLER */
1189
1190 #if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
1191 void
1192 tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
1193 char *where;
1194 fixS *fixP;
1195 relax_addressT segment_address_in_file;
1196 {
1197 /*
1198 * In: length of relocation (or of address) in chars: 1, 2 or 4.
1199 * Out: GNU LD relocation length code: 0, 1, or 2.
1200 */
1201
1202 static CONST unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
1203 long r_symbolnum;
1204
1205 know (fixP->fx_addsy != NULL);
1206
1207 md_number_to_chars (where,
1208 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
1209 4);
1210
1211 r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
1212 ? S_GET_TYPE (fixP->fx_addsy)
1213 : fixP->fx_addsy->sy_number);
1214
1215 where[4] = (r_symbolnum >> 16) & 0x0ff;
1216 where[5] = (r_symbolnum >> 8) & 0x0ff;
1217 where[6] = r_symbolnum & 0x0ff;
1218 where[7] = (((fixP->fx_pcrel << 7) & 0x80)
1219 | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60)
1220 | (((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10));
1221
1222 }
1223
1224 void
1225 tc_aout_pre_write_hook (headers)
1226 object_headers *headers;
1227 {
1228 }
1229 #endif
1230 #endif /* !BFD_ASSEMBLER */
This page took 0.054696 seconds and 4 git commands to generate.