1 /* tc-rce.c -- Assemble code for the Experimental RCE
3 Copyright (C) 1993,1994 Free Software Foundation.
5 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
22 Adapted from the SH assember
23 Relocation doesnt work yet.
31 #include "opcodes/rce-opc.h"
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 ****/
40 const char comment_chars
[] = "!";
41 const char line_separator_chars
[] = ";";
42 const char line_comment_chars
[] = "!";
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
52 void s_align_bytes ();
54 const pseudo_typeS md_pseudo_table
[] =
56 {"page", listing_eject
, 0},
60 const int md_reloc_size
= 8;
62 static int relax
; /* set if -relax seen */
64 const char EXP_CHARS
[] = "eE";
66 /* Chars that mean this number is a floating point constant */
69 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
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))
75 /* These are the two types of relaxable instruction */
84 #define UNDEF_WORD_DISP 4
88 #define C32_LEN 10 /* allow for align */
90 #define U32_LEN 8 /* allow for align */
93 /* Initialize the relax table */
94 const relax_typeS md_relax_table
[] =
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 */
110 static struct hash_control
*opcode_hash_control
; /* Opcode mnemonics */
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
120 rce_opcode_info
*opcode
;
121 char *prev_name
= "";
123 opcode_hash_control
= hash_new ();
125 /* Insert unique names into hash table */
126 for (opcode
= rce_table
; opcode
->name
; opcode
++)
128 if (strcmp (prev_name
, opcode
->name
))
130 prev_name
= opcode
->name
;
131 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
135 /* Make all the opcodes with the same name point to the same
137 opcode
->name
= prev_name
;
144 static expressionS immediate
; /* absolute expression */
146 /* try and parse a reg name */
152 if ( tolower(s
[0]) == 'r')
154 if (s
[1] == '1' && s
[2] >= '0' && s
[2] <= '5')
156 *reg
= 10 + s
[2] - '0';
159 if (s
[1] >= '0' && s
[1] <= '9')
165 as_bad("register expected");
169 static struct Cregs
{
196 if ( (tolower(s
[0]) == 'c' && tolower(s
[1]) == 'r') )
198 if (s
[2] == '3' && s
[3] >= '0' && s
[3] <= '1')
200 *reg
= 30 + s
[3] - '0';
203 if (s
[2] == '2' && s
[3] >= '0' && s
[3] <= '9')
205 *reg
= 20 + s
[3] - '0';
208 if (s
[2] == '1' && s
[3] >= '0' && s
[3] <= '9')
210 *reg
= 10 + s
[3] - '0';
213 if (s
[2] >= '0' && s
[2] <= '9')
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 ) {
228 as_bad("register expected");
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
;
249 parse_imm(s
, val
, min
, max
)
256 if (immediate
.X_op
!= O_constant
257 || immediate
.X_add_number
< min
258 || immediate
.X_add_number
> max
)
260 as_bad ("operand must be absolute in range %d..%d", min
, max
);
262 *val
= immediate
.X_add_number
;
266 /* look for immediate notation '#' */
268 parse_imm_notation(s
)
273 if( s
== (char *)(NULL
) ) return( (char *)(isa_imm
) );
285 parse_mem(s
, reg
, off
, siz
)
291 char *parse_imm_notation();
294 { s
= parse_reg(s
+1, reg
);
297 s
= parse_imm_notation(s
+1);
298 if( parse_imm_notation(NULL
) ) siz
=1;
299 s
= parse_imm(s
, off
, 0, 63);
304 as_bad ("operand must be a multiple of 4");
310 as_bad ("operand must be a multiple of 2");
321 as_bad("base register expected");
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.
337 rce_opcode_info
*opcode
;
344 /* Drop leading whitespace */
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
!= ' ';
353 name
[nlen
] = op_start
[nlen
];
359 as_bad ("can't find opcode ");
363 opcode
= (rce_opcode_info
*) hash_find (opcode_hash_control
, name
);
366 as_bad ("unknown opcode \"%s\"", name
);
370 switch (opcode
->opclass
)
372 output
= frag_more (2);
375 op_end
= parse_imm_notation(op_end
+ 1);
376 op_end
= parse_imm(op_end
, ®
, 0, 7);
378 output
= frag_more (2);
381 op_end
= parse_reg (op_end
+ 1, ®
);
383 output
= frag_more (2);
386 op_end
= parse_reg (op_end
+ 1, ®
);
388 as_bad("invalid register specified -> r15");
390 output
= frag_more (2);
393 op_end
= parse_reg (op_end
+ 1, ®
);
396 { op_end
= parse_creg(op_end
+ 1, ®
);
399 output
= frag_more (2);
402 op_end
= parse_reg (op_end
+ 1, ®
);
405 { op_end
= parse_reg(op_end
+ 1, ®
);
409 as_bad("second operand missing");
410 output
= frag_more (2);
412 case X1
: /** handle both syntax-> xtrb- r1,rx OR xtrb- rx **/
413 op_end
= parse_reg (op_end
+ 1, ®
);
414 if (*op_end
== ',') { /** xtrb- r1,rx **/
416 as_bad("destination register must be r1");
417 op_end
= parse_reg(op_end
+ 1, ®
);
419 else { /** xtrb- rx **/
422 output
= frag_more (2);
425 op_end
= parse_reg (op_end
+ 1, ®
);
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
) ) {
435 op_end
= parse_imm(op_end
, ®
, minval
, maxval
);
436 inst
|= (reg
-minval
)<<4;
439 as_bad("second operand missing");
440 output
= frag_more (2);
443 op_end
= parse_reg (op_end
+ 1, ®
);
446 { unsigned upper
= 31;
447 op_end
= parse_imm_notation(op_end
+ 1);
448 op_end
= parse_imm(op_end
, ®
, 0, upper
);
452 as_bad("second operand missing");
453 output
= frag_more (2);
456 op_end
= parse_reg (op_end
+ 1, ®
);
459 { unsigned upper
= 31;
460 op_end
= parse_imm_notation(op_end
+ 1);
461 op_end
= parse_imm(op_end
, ®
, 1, upper
);
465 as_bad("second operand missing");
466 output
= frag_more (2);
469 op_end
= parse_reg (op_end
+ 1, ®
);
472 { unsigned upper
= 0x7f;
473 op_end
= parse_imm_notation(op_end
+ 1);
474 op_end
= parse_imm(op_end
, ®
, 0, upper
);
478 as_bad("second operand missing");
479 output
= frag_more (2);
482 op_end
= parse_reg(op_end
+ 1, ®
);
487 if ((inst
& 0x6000) == 0)
489 else if ((inst
& 0x6000) == 0x4000)
491 else if ((inst
& 0x6000) == 0x2000)
493 op_end
= parse_mem(op_end
+ 1, ®
, &off
, size
);
494 inst
|= (reg
) | (off
<<4);
497 as_bad("second operand missing");
498 output
= frag_more (2);
501 op_end
= parse_reg (op_end
+ 1, ®
);
504 op_end
= parse_imm_notation(op_end
+ 1);
505 op_end
= parse_imm(op_end
, &val
, 0, 0x7FF);
509 as_bad("second operand missing");
511 as_bad("register must be r1");
512 output
= frag_more (2);
515 op_end
= parse_reg(op_end
+ 1, ®
);
516 if( reg
==0 || reg
==15 )
517 as_bad ("invalid register 'r0' and 'r15' illegal");
519 if (*op_end
++ == ',')
521 /** look for # notation **/
522 op_end
= parse_imm_notation(op_end
);
523 if( parse_imm_notation(NULL
) )
525 op_end
= parse_imm(op_end
, &val
, 0, 0x0FF);
527 output
= frag_more (2);
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
,
542 as_bad("second operand missing");
545 /** look for # notation **/
546 op_end
= parse_imm_notation(op_end
+ 1) -1;
547 if( parse_imm_notation(NULL
) )
549 op_end
= parse_imm(op_end
+1, &val
, 0, 0x0FF);
551 output
= frag_more (2);
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
);
565 op_end
= parse_reg(op_end
+ 1, ®
);
568 op_end
= parse_reg(op_end
+ 1, &endreg
);
573 { op_end
= parse_reg(op_end
+ 1, &basereg
);
576 if (endreg
== 15 && basereg
== 0)
578 if(reg
==0 || reg
==15)
579 as_bad("bad register list, 'r0' and 'r15' invalid as starting registers");
580 inst
|= 0x0080; /* list form */
583 else if (endreg
- reg
== 3)
584 { inst
|= basereg
; /* quadrant form */
587 case 4: inst
|= (1<<5); break;
588 case 8: inst
|= (2<<5); break;
589 case 12: inst
|= (3<<5); break;
591 as_bad("first register must be r0, r4, r8, or r12");
595 as_bad("bad register list or base register");
598 as_bad("base register expected");
601 as_bad("second operand missing");
604 as_bad("reg-reg expected");
605 output
= frag_more (2);
608 op_end
= parse_reg(op_end
+ 1, ®
);
611 op_end
= parse_reg(op_end
+ 1, &endreg
);
616 { op_end
= parse_reg(op_end
+ 1, &basereg
);
619 if (endreg
- reg
== 3)
620 { inst
|= basereg
; /* quadrant form */
623 case 4: inst
|= (1<<5); break;
624 case 8: inst
|= (2<<5); break;
625 case 12: inst
|= (3<<5); break;
627 as_bad("first register must be r0, r4, r8, or r12");
631 as_bad("bad register list or base register");
634 as_bad("base register expected");
637 as_bad("second operand missing");
640 as_bad("reg-reg expected");
641 output
= frag_more (2);
644 op_end
= parse_imm_notation(op_end
+ 1);
645 if( parse_imm_notation(NULL
) )
647 op_end
= parse_imm(op_end
, &val
, 0, 0x7FF);
649 output
= frag_more (2);
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
);
659 as_bad("cant deal with opcode \"%s\"", name
);
661 output
[0] = (inst
>>8);
665 #ifndef BFD_ASSEMBLER
667 DEFUN (tc_crawl_symbol_chain
, (headers
),
668 object_headers
* headers
)
673 DEFUN (tc_headers_hook
, (headers
),
674 object_headers
* headers
)
680 DEFUN (md_undefined_symbol
, (name
),
691 /* Various routines to kill one day */
692 /* Equal to MAX_PRECISION in atof-ieee.c */
693 #define MAX_LITTLENUMS 6
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.
700 md_atof (type
, litP
, sizeP
)
706 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
707 LITTLENUM_TYPE
*wordP
;
739 return "Bad call to MD_NTOF()";
741 t
= atof_ieee (input_line_pointer
, type
, words
);
743 input_line_pointer
= t
;
745 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
746 for (wordP
= words
; prec
--;)
748 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
749 litP
+= sizeof (LITTLENUM_TYPE
);
754 CONST
char *md_shortopts
= "";
755 struct option md_longopts
[] = {
757 #define OPTION_RELAX (OPTION_MD_BASE)
758 #define OPTION_LITTLE (OPTION_MD_BASE+1)
760 {"relax", no_argument
, NULL
, OPTION_RELAX
},
761 {"little", no_argument
, NULL
, OPTION_LITTLE
},
762 {NULL
, no_argument
, NULL
, 0}
764 size_t md_longopts_size
= sizeof(md_longopts
);
767 md_parse_option (c
, arg
)
788 md_show_usage (stream
)
793 -relax alter jump instructions for long displacements\n");
796 int md_short_jump_size
;
799 tc_Nout_fix_to_chars ()
801 as_fatal ("call to tc_Nout_fix_to_chars");
805 md_create_short_jump (ptr
, from_Nddr
, to_Nddr
, frag
, to_symbol
)
812 as_fatal ("failed sanity check: short_jump");
816 md_create_long_jump (ptr
, from_Nddr
, to_Nddr
, frag
, to_symbol
)
818 addressT from_Nddr
, to_Nddr
;
822 as_fatal ("failed sanity check: long_jump");
826 called after relaxing, change the frags so they know how big they are
828 #ifndef BFD_ASSEMBLER
830 md_convert_frag (headers
, fragP
)
831 object_headers
*headers
;
832 register fragS
*fragP
;
835 md_convert_frag (abfd
, sec
, fragP
)
838 register fragS
*fragP
;
841 unsigned char *buffer
= (unsigned char *) (fragP
->fr_fix
+ fragP
->fr_literal
);
842 int targ_addr
= S_GET_VALUE (fragP
->fr_symbol
) + fragP
->fr_offset
;
843 #ifdef BFD_ASSEMBLER /* not needed otherwise? */
844 targ_addr
+= fragP
->fr_symbol
->sy_frag
->fr_address
;
846 switch (fragP
->fr_subtype
)
848 case C (COND_JUMP
, COND12
):
849 case C (UNCD_JUMP
, UNCD12
):
851 /* Get the address of the end of the instruction */
852 int next_inst
= fragP
->fr_fix
+ fragP
->fr_address
+ 2;
854 int disp
= targ_addr
- next_inst
;
856 as_bad("odd displacement at %x", next_inst
-2);
857 if (disp
< 0) /* move sign to low order bit */
859 t0
= buffer
[0] & 0xF8;
860 md_number_to_chars (buffer
, disp
, 2);
861 buffer
[0] = (buffer
[0] & 0x07) | t0
;
867 case C (COND_JUMP
, COND32
):
868 case C (COND_JUMP
, UNDEF_WORD_DISP
):
870 /* A conditional branch wont fit into 12 bits so:
877 int next_inst
= fragP
->fr_fix
+ fragP
->fr_address
+ C32_LEN
;
878 int align
= next_inst
&02;
879 buffer
[0] ^= 0x08; /* Toggle T/F bit */
880 buffer
[2] = 0x73; /* Build jmpi */
884 buffer
[1] = 3; /* branch over jmpi, and ptr */
885 buffer
[4] = 0; /* space for 32 bit address */
889 /* Make reloc for the long disp */
890 fix_new(fragP
, fragP
->fr_fix
+ 4, 4,
891 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_32
);
893 /**** frag has shrunk but gas can't deal with that */
894 fragP
->fr_fix
+= C32_LEN
- 2;
896 fragP
->fr_fix
+= C32_LEN
;
901 buffer
[1] = 4; /* branch over jmpi, and ptr */
902 buffer
[4] = 0; /* alignment */
904 buffer
[6] = 0; /* space for 32 bit address */
908 /* Make reloc for the long disp */
909 fix_new(fragP
, fragP
->fr_fix
+ 6, 4,
910 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_32
);
911 fragP
->fr_fix
+= C32_LEN
;
917 case C (UNCD_JUMP
, UNCD32
):
918 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
920 /* An unconditional branch wont fit in 12 bits, make code which looks like
925 int next_inst
= fragP
->fr_fix
+ fragP
->fr_address
+ U32_LEN
;
926 int align
= next_inst
&02;
927 buffer
[0] = 0x73; /* build jmpi */
931 buffer
[2] = 0; /* space for 32 bit address */
935 /* Make reloc for the long disp */
936 fix_new (fragP
, fragP
->fr_fix
+ 2, 4,
937 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_32
);
939 /**** frag has shrunk but gas can't deal with that */
940 fragP
->fr_fix
+= U32_LEN
- 2;
942 fragP
->fr_fix
+= U32_LEN
;
947 buffer
[2] = 0; /* alignment */
949 buffer
[4] = 0; /* space for 32 bit address */
953 /* Make reloc for the long disp */
954 fix_new (fragP
, fragP
->fr_fix
+ 4, 4,
955 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_32
);
956 fragP
->fr_fix
+= U32_LEN
;
968 md_apply_fix1 (fixP
, val
)
972 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
973 int addr
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
975 switch (fixP
->fx_r_type
)
977 case R_PCRELIMM11BY2
: /* second byte of 2 byte opcode */
979 if (((val
& ~0x3ff) != 0) && ((val
| 0x3ff) != -1))
980 as_warn ("pcrel for branch too far (0x%x) at 0x%x", val
, addr
);
982 BR no longer puts the sign-bit in bit0, leaves it in bit10
983 buf[0] |= ((val >> 7) & 0x7);
984 buf[1] |= ((val & 0x7f) << 1);
985 buf[1] |= ((val >> 10) & 0x1);
987 buf
[0] |= ((val
>> 8) & 0x7);
988 buf
[1] |= (val
& 0xff);
990 case R_PCRELIMM8BY4
: /* lower 8 bits of 2 byte opcode */
994 as_warn ("pcrel for lrw too far (0x%x) at 0x%x", val
, addr
);
995 buf
[1] |= (val
& 0xff);
998 if (fixP
->fx_size
!= 4)
1008 #ifdef BFD_ASSEMBLER
1010 md_apply_fix (fixP
, valp
)
1014 md_apply_fix1 (fixP
, *valp
);
1019 md_apply_fix (fixP
, val
)
1023 md_apply_fix1 (fixP
, val
);
1027 int md_long_jump_size
;
1030 called just before address relaxation, return the length
1031 by which a fragment must grow to reach it's destination
1034 md_estimate_size_before_relax (fragP
, segment_type
)
1035 register fragS
*fragP
;
1036 register segT segment_type
;
1038 switch (fragP
->fr_subtype
)
1040 case C (UNCD_JUMP
, UNDEF_DISP
):
1041 /* used to be a branch to somewhere which was unknown */
1042 if (!fragP
->fr_symbol
)
1044 fragP
->fr_subtype
= C (UNCD_JUMP
, UNCD12
);
1045 fragP
->fr_var
= md_relax_table
[C (UNCD_JUMP
, UNCD12
)].rlx_length
;
1047 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
1049 fragP
->fr_subtype
= C (UNCD_JUMP
, UNCD12
);
1050 fragP
->fr_var
= md_relax_table
[C (UNCD_JUMP
, UNCD12
)].rlx_length
;
1054 fragP
->fr_subtype
= C (UNCD_JUMP
, UNDEF_WORD_DISP
);
1055 fragP
->fr_var
= md_relax_table
[C (UNCD_JUMP
, UNCD32
)].rlx_length
;
1056 return md_relax_table
[C (UNCD_JUMP
, UNCD32
)].rlx_length
;
1062 case C (COND_JUMP
, UNDEF_DISP
):
1063 /* used to be a branch to somewhere which was unknown */
1064 if (fragP
->fr_symbol
1065 && S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
1067 /* Got a symbol and it's defined in this segment, become byte
1068 sized - maybe it will fix up */
1069 fragP
->fr_subtype
= C (COND_JUMP
, COND12
);
1070 fragP
->fr_var
= md_relax_table
[C (COND_JUMP
, COND12
)].rlx_length
;
1072 else if (fragP
->fr_symbol
)
1074 /* Its got a segment, but its not ours, so it will always be long */
1075 fragP
->fr_subtype
= C (COND_JUMP
, UNDEF_WORD_DISP
);
1076 fragP
->fr_var
= md_relax_table
[C (COND_JUMP
, COND32
)].rlx_length
;
1077 return md_relax_table
[C (COND_JUMP
, COND32
)].rlx_length
;
1081 /* We know the abs value */
1082 fragP
->fr_subtype
= C (COND_JUMP
, COND12
);
1083 fragP
->fr_var
= md_relax_table
[C (COND_JUMP
, COND12
)].rlx_length
;
1088 return fragP
->fr_var
;
1091 /* Put number into target byte order */
1094 md_number_to_chars (ptr
, use
, nbytes
)
1102 *ptr
++ = (use
>> 24) & 0xff;
1104 *ptr
++ = (use
>> 16) & 0xff;
1106 *ptr
++ = (use
>> 8) & 0xff;
1108 *ptr
++ = (use
>> 0) & 0xff;
1116 /* Round up a section size to the appropriate boundary. */
1118 md_section_align (segment
, size
)
1122 return size
; /* Byte alignment is fine */
1127 md_pcrel_from (fixP
)
1131 int gap
= fixP
->fx_size
+ fixP
->fx_where
+
1132 fixP
->fx_frag
->fr_address
;
1140 /* does nothing for now. */
1143 #ifdef BFD_ASSEMBLER
1146 tc_gen_reloc (section
, fixp
)
1151 bfd_reloc_code_real_type code
;
1153 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1154 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
1156 #define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1157 MAP (1, 0, BFD_RELOC_8
);
1158 MAP (2, 0, BFD_RELOC_16
);
1159 MAP (4, 0, BFD_RELOC_32
);
1160 MAP (1, 1, BFD_RELOC_8_PCREL
);
1161 MAP (2, 1, BFD_RELOC_16_PCREL
);
1162 MAP (4, 1, BFD_RELOC_32_PCREL
);
1164 as_bad ("Can not do %d byte %srelocation", fixp
->fx_size
,
1165 fixp
->fx_pcrel
? "pc-relative" : "");
1168 rel
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
1170 rel
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1171 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1173 rel
->addend
= fixp
->fx_addnumber
;
1177 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1182 name
= S_GET_NAME (fixp
->fx_addsy
);
1185 as_fatal ("Cannot find relocation type for symbol %s, code %d",
1192 #else /* !BFD_ASSEMBLER */
1194 #if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
1196 tc_aout_fix_to_chars(where
, fixP
, segment_address_in_file
)
1199 relax_addressT segment_address_in_file
;
1202 * In: length of relocation (or of address) in chars: 1, 2 or 4.
1203 * Out: GNU LD relocation length code: 0, 1, or 2.
1206 static CONST
unsigned char nbytes_r_length
[] = {42, 0, 1, 42, 2};
1209 know (fixP
->fx_addsy
!= NULL
);
1211 md_number_to_chars (where
,
1212 fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
1215 r_symbolnum
= (S_IS_DEFINED (fixP
->fx_addsy
)
1216 ? S_GET_TYPE (fixP
->fx_addsy
)
1217 : fixP
->fx_addsy
->sy_number
);
1219 where
[4] = (r_symbolnum
>> 16) & 0x0ff;
1220 where
[5] = (r_symbolnum
>> 8) & 0x0ff;
1221 where
[6] = r_symbolnum
& 0x0ff;
1222 where
[7] = (((fixP
->fx_pcrel
<< 7) & 0x80)
1223 | ((nbytes_r_length
[fixP
->fx_size
] << 5) & 0x60)
1224 | (((!S_IS_DEFINED (fixP
->fx_addsy
)) << 4) & 0x10));
1229 tc_aout_pre_write_hook (headers
)
1230 object_headers
*headers
;
1234 #endif /* !BFD_ASSEMBLER */