0dc7a9f4cb1e8c7d3f0fc9a37566c3cd40739502
[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 void
687 DEFUN_VOID (md_end)
688 {
689 }
690
691 /* Various routines to kill one day */
692 /* Equal to MAX_PRECISION in atof-ieee.c */
693 #define MAX_LITTLENUMS 6
694
695 /* Turn a string in input_line_pointer into a floating point constant of type
696 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
697 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
698 */
699 char *
700 md_atof (type, litP, sizeP)
701 char type;
702 char *litP;
703 int *sizeP;
704 {
705 int prec;
706 LITTLENUM_TYPE words[MAX_LITTLENUMS];
707 LITTLENUM_TYPE *wordP;
708 char *t;
709 char *atof_ieee ();
710
711 switch (type)
712 {
713 case 'f':
714 case 'F':
715 case 's':
716 case 'S':
717 prec = 2;
718 break;
719
720 case 'd':
721 case 'D':
722 case 'r':
723 case 'R':
724 prec = 4;
725 break;
726
727 case 'x':
728 case 'X':
729 prec = 6;
730 break;
731
732 case 'p':
733 case 'P':
734 prec = 6;
735 break;
736
737 default:
738 *sizeP = 0;
739 return "Bad call to MD_NTOF()";
740 }
741 t = atof_ieee (input_line_pointer, type, words);
742 if (t)
743 input_line_pointer = t;
744
745 *sizeP = prec * sizeof (LITTLENUM_TYPE);
746 for (wordP = words; prec--;)
747 {
748 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
749 litP += sizeof (LITTLENUM_TYPE);
750 }
751 return 0;
752 }
753 \f
754 CONST char *md_shortopts = "";
755 struct option md_longopts[] = {
756
757 #define OPTION_RELAX (OPTION_MD_BASE)
758 #define OPTION_LITTLE (OPTION_MD_BASE+1)
759
760 {"relax", no_argument, NULL, OPTION_RELAX},
761 {"little", no_argument, NULL, OPTION_LITTLE},
762 {NULL, no_argument, NULL, 0}
763 };
764 size_t md_longopts_size = sizeof(md_longopts);
765
766 int
767 md_parse_option (c, arg)
768 int c;
769 char *arg;
770 {
771 switch (c)
772 {
773 case OPTION_RELAX:
774 relax = 1;
775 break;
776 case OPTION_LITTLE:
777 abort ();
778 break;
779
780 default:
781 return 0;
782 }
783
784 return 1;
785 }
786
787 void
788 md_show_usage (stream)
789 FILE *stream;
790 {
791 fprintf(stream, "\
792 RCE options:\n\
793 -relax alter jump instructions for long displacements\n");
794 }
795 \f
796 int md_short_jump_size;
797
798 void
799 tc_Nout_fix_to_chars ()
800 {
801 as_fatal ("call to tc_Nout_fix_to_chars");
802 }
803
804 void
805 md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
806 char *ptr;
807 addressT from_Nddr;
808 addressT to_Nddr;
809 fragS *frag;
810 symbolS *to_symbol;
811 {
812 as_fatal ("failed sanity check: short_jump");
813 }
814
815 void
816 md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
817 char *ptr;
818 addressT from_Nddr, to_Nddr;
819 fragS *frag;
820 symbolS *to_symbol;
821 {
822 as_fatal ("failed sanity check: long_jump");
823 }
824
825 /*
826 called after relaxing, change the frags so they know how big they are
827 */
828 #ifndef BFD_ASSEMBLER
829 void
830 md_convert_frag (headers, seg, fragP)
831 object_headers *headers;
832 segT seg;
833 register fragS *fragP;
834 #else
835 void
836 md_convert_frag (abfd, sec, fragP)
837 bfd *abfd;
838 segT sec;
839 register fragS *fragP;
840 #endif
841 {
842 unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
843 int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
844 #ifdef BFD_ASSEMBLER /* not needed otherwise? */
845 targ_addr += fragP->fr_symbol->sy_frag->fr_address;
846 #endif
847 switch (fragP->fr_subtype)
848 {
849 case C (COND_JUMP, COND12):
850 case C (UNCD_JUMP, UNCD12):
851 {
852 /* Get the address of the end of the instruction */
853 int next_inst = fragP->fr_fix + fragP->fr_address + 2;
854 unsigned char t0;
855 int disp = targ_addr - next_inst;
856 if (disp&1)
857 as_bad("odd displacement at %x", next_inst-2);
858 if (disp < 0) /* move sign to low order bit */
859 disp |= 1;
860 t0 = buffer[0] & 0xF8;
861 md_number_to_chars (buffer, disp, 2);
862 buffer[0] = (buffer[0] & 0x07) | t0;
863 fragP->fr_fix += 2;
864 fragP->fr_var = 0;
865 }
866 break;
867
868 case C (COND_JUMP, COND32):
869 case C (COND_JUMP, UNDEF_WORD_DISP):
870 {
871 /* A conditional branch wont fit into 12 bits so:
872 * b!cond 1f
873 * jmpi 0f
874 * .align 2
875 * 0: .long disp
876 * 1:
877 */
878 int next_inst = fragP->fr_fix + fragP->fr_address + C32_LEN;
879 int align = next_inst&02;
880 buffer[0] ^= 0x08; /* Toggle T/F bit */
881 buffer[2] = 0x73; /* Build jmpi */
882 buffer[3] = 0x00;
883 if (align)
884 {
885 buffer[1] = 3; /* branch over jmpi, and ptr */
886 buffer[4] = 0; /* space for 32 bit address */
887 buffer[5] = 0;
888 buffer[6] = 0;
889 buffer[7] = 0;
890 /* Make reloc for the long disp */
891 fix_new(fragP, fragP->fr_fix + 4, 4,
892 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
893 #if 0
894 /**** frag has shrunk but gas can't deal with that */
895 fragP->fr_fix += C32_LEN - 2;
896 #else
897 fragP->fr_fix += C32_LEN;
898 #endif
899 }
900 else
901 {
902 buffer[1] = 4; /* branch over jmpi, and ptr */
903 buffer[4] = 0; /* alignment */
904 buffer[5] = 0;
905 buffer[6] = 0; /* space for 32 bit address */
906 buffer[7] = 0;
907 buffer[8] = 0;
908 buffer[9] = 0;
909 /* Make reloc for the long disp */
910 fix_new(fragP, fragP->fr_fix + 6, 4,
911 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
912 fragP->fr_fix += C32_LEN;
913 }
914 fragP->fr_var = 0;
915 }
916 break;
917
918 case C (UNCD_JUMP, UNCD32):
919 case C (UNCD_JUMP, UNDEF_WORD_DISP):
920 {
921 /* An unconditional branch wont fit in 12 bits, make code which looks like
922 * jmpi 0f
923 * .align 2
924 * 0: .long disp
925 */
926 int next_inst = fragP->fr_fix + fragP->fr_address + U32_LEN;
927 int align = next_inst&02;
928 buffer[0] = 0x73; /* build jmpi */
929 buffer[1] = 0x00;
930 if (align)
931 {
932 buffer[2] = 0; /* space for 32 bit address */
933 buffer[3] = 0;
934 buffer[4] = 0;
935 buffer[5] = 0;
936 /* Make reloc for the long disp */
937 fix_new (fragP, fragP->fr_fix + 2, 4,
938 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
939 #if 0
940 /**** frag has shrunk but gas can't deal with that */
941 fragP->fr_fix += U32_LEN - 2;
942 #else
943 fragP->fr_fix += U32_LEN;
944 #endif
945 }
946 else
947 {
948 buffer[2] = 0; /* alignment */
949 buffer[3] = 0;
950 buffer[4] = 0; /* space for 32 bit address */
951 buffer[5] = 0;
952 buffer[6] = 0;
953 buffer[7] = 0;
954 /* Make reloc for the long disp */
955 fix_new (fragP, fragP->fr_fix + 4, 4,
956 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
957 fragP->fr_fix += U32_LEN;
958 }
959 fragP->fr_var = 0;
960 }
961 break;
962
963 default:
964 abort ();
965 }
966 }
967
968 void
969 md_apply_fix1 (fixP, val)
970 fixS *fixP;
971 long val;
972 {
973 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
974 int addr = fixP->fx_frag->fr_address + fixP->fx_where;
975
976 switch (fixP->fx_r_type)
977 {
978 case R_PCRELIMM11BY2: /* second byte of 2 byte opcode */
979 val /= 2;
980 if (((val & ~0x3ff) != 0) && ((val | 0x3ff) != -1))
981 as_warn ("pcrel for branch too far (0x%x) at 0x%x", val, addr);
982 /*****
983 BR no longer puts the sign-bit in bit0, leaves it in bit10
984 buf[0] |= ((val >> 7) & 0x7);
985 buf[1] |= ((val & 0x7f) << 1);
986 buf[1] |= ((val >> 10) & 0x1);
987 *****/
988 buf[0] |= ((val >> 8) & 0x7);
989 buf[1] |= (val & 0xff);
990 break;
991 case R_PCRELIMM8BY4: /* lower 8 bits of 2 byte opcode */
992 val += 3;
993 val /= 4;
994 if (val & ~0xff)
995 as_warn ("pcrel for lrw too far (0x%x) at 0x%x", val, addr);
996 buf[1] |= (val & 0xff);
997 break;
998 default:
999 if (fixP->fx_size != 4)
1000 abort ();
1001 *buf++ = val >> 24;
1002 *buf++ = val >> 16;
1003 *buf++ = val >> 8;
1004 *buf = val >> 0;
1005 break;
1006 }
1007 }
1008
1009 #ifdef BFD_ASSEMBLER
1010 int
1011 md_apply_fix (fixP, valp)
1012 fixS *fixP;
1013 valueT *valp;
1014 {
1015 md_apply_fix1 (fixP, *valp);
1016 return 1;
1017 }
1018 #else
1019 void
1020 md_apply_fix (fixP, val)
1021 fixS *fixP;
1022 long val;
1023 {
1024 md_apply_fix1 (fixP, val);
1025 }
1026 #endif
1027
1028 int md_long_jump_size;
1029
1030 /*
1031 called just before address relaxation, return the length
1032 by which a fragment must grow to reach it's destination
1033 */
1034 int
1035 md_estimate_size_before_relax (fragP, segment_type)
1036 register fragS *fragP;
1037 register segT segment_type;
1038 {
1039 switch (fragP->fr_subtype)
1040 {
1041 case C (UNCD_JUMP, UNDEF_DISP):
1042 /* used to be a branch to somewhere which was unknown */
1043 if (!fragP->fr_symbol)
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 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1049 {
1050 fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
1051 fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
1052 }
1053 else
1054 {
1055 fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);
1056 fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
1057 return md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
1058 }
1059 break;
1060
1061 default:
1062 abort ();
1063 case C (COND_JUMP, UNDEF_DISP):
1064 /* used to be a branch to somewhere which was unknown */
1065 if (fragP->fr_symbol
1066 && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1067 {
1068 /* Got a symbol and it's defined in this segment, become byte
1069 sized - maybe it will fix up */
1070 fragP->fr_subtype = C (COND_JUMP, COND12);
1071 fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
1072 }
1073 else if (fragP->fr_symbol)
1074 {
1075 /* Its got a segment, but its not ours, so it will always be long */
1076 fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
1077 fragP->fr_var = md_relax_table[C (COND_JUMP, COND32)].rlx_length;
1078 return md_relax_table[C (COND_JUMP, COND32)].rlx_length;
1079 }
1080 else
1081 {
1082 /* We know the abs value */
1083 fragP->fr_subtype = C (COND_JUMP, COND12);
1084 fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
1085 }
1086
1087 break;
1088 }
1089 return fragP->fr_var;
1090 }
1091
1092 /* Put number into target byte order */
1093
1094 void
1095 md_number_to_chars (ptr, use, nbytes)
1096 char *ptr;
1097 valueT use;
1098 int nbytes;
1099 {
1100 switch (nbytes)
1101 {
1102 case 4:
1103 *ptr++ = (use >> 24) & 0xff;
1104 case 3:
1105 *ptr++ = (use >> 16) & 0xff;
1106 case 2:
1107 *ptr++ = (use >> 8) & 0xff;
1108 case 1:
1109 *ptr++ = (use >> 0) & 0xff;
1110 break;
1111 default:
1112 abort ();
1113 }
1114 }
1115
1116
1117 /* Round up a section size to the appropriate boundary. */
1118 valueT
1119 md_section_align (segment, size)
1120 segT segment;
1121 valueT size;
1122 {
1123 return size; /* Byte alignment is fine */
1124 }
1125
1126
1127 long
1128 md_pcrel_from (fixP)
1129 fixS *fixP;
1130
1131 {
1132 int gap = fixP->fx_size + fixP->fx_where +
1133 fixP->fx_frag->fr_address;
1134 return gap;
1135 }
1136
1137 void
1138 dump_literals (i)
1139 int i;
1140 {
1141 /* does nothing for now. */
1142 }
1143
1144 #ifdef BFD_ASSEMBLER
1145
1146 arelent *
1147 tc_gen_reloc (section, fixp)
1148 asection *section;
1149 fixS *fixp;
1150 {
1151 arelent *rel;
1152 bfd_reloc_code_real_type code;
1153
1154 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1155 switch (F (fixp->fx_size, fixp->fx_pcrel))
1156 {
1157 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1158 MAP (1, 0, BFD_RELOC_8);
1159 MAP (2, 0, BFD_RELOC_16);
1160 MAP (4, 0, BFD_RELOC_32);
1161 MAP (1, 1, BFD_RELOC_8_PCREL);
1162 MAP (2, 1, BFD_RELOC_16_PCREL);
1163 MAP (4, 1, BFD_RELOC_32_PCREL);
1164 default:
1165 as_bad ("Can not do %d byte %srelocation", fixp->fx_size,
1166 fixp->fx_pcrel ? "pc-relative" : "");
1167 }
1168
1169 rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
1170 assert (rel != 0);
1171 rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1172 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
1173 if (fixp->fx_pcrel)
1174 rel->addend = fixp->fx_addnumber;
1175 else
1176 rel->addend = 0;
1177
1178 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1179 if (!rel->howto)
1180 {
1181 const char *name;
1182
1183 name = S_GET_NAME (fixp->fx_addsy);
1184 if (name == NULL)
1185 name = "<unknown>";
1186 as_fatal ("Cannot find relocation type for symbol %s, code %d",
1187 name, (int) code);
1188 }
1189
1190 return rel;
1191 }
1192
1193 #else /* !BFD_ASSEMBLER */
1194
1195 #if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
1196 void
1197 tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
1198 char *where;
1199 fixS *fixP;
1200 relax_addressT segment_address_in_file;
1201 {
1202 /*
1203 * In: length of relocation (or of address) in chars: 1, 2 or 4.
1204 * Out: GNU LD relocation length code: 0, 1, or 2.
1205 */
1206
1207 static CONST unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
1208 long r_symbolnum;
1209
1210 know (fixP->fx_addsy != NULL);
1211
1212 md_number_to_chars (where,
1213 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
1214 4);
1215
1216 r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
1217 ? S_GET_TYPE (fixP->fx_addsy)
1218 : fixP->fx_addsy->sy_number);
1219
1220 where[4] = (r_symbolnum >> 16) & 0x0ff;
1221 where[5] = (r_symbolnum >> 8) & 0x0ff;
1222 where[6] = r_symbolnum & 0x0ff;
1223 where[7] = (((fixP->fx_pcrel << 7) & 0x80)
1224 | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60)
1225 | (((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10));
1226
1227 }
1228
1229 void
1230 tc_aout_pre_write_hook (headers)
1231 object_headers *headers;
1232 {
1233 }
1234 #endif
1235 #endif /* !BFD_ASSEMBLER */
This page took 0.070742 seconds and 3 git commands to generate.