2002-06-08 Matt Thomas <matt@3am-software.com>

* configure.in (vax-*-netbsdelf*, vax-*-netbsdaout*)
(vax-*-netbsd*): New targets.
* configure: Regenerate.
* config/aout_gnu.h (enum machine_type): Add M_VAX4K_NETBSD.
* config/tc-vax.c: Add support for ELF and PIC.
(flag_want_pic): New flag.
(float_cons): Fix prototype.
(md_apply_fix3): Adjust for BFD_ASSEMBLER.
(md_assemble): Introduce a new is_absolute local, and use it
rather than repeating the test.  Make fatal errors actually
fatal by using as_fatal as appropriate.  Adjust for BFD_ASSEMBLER.
Add support for ELF.  Add support for PIC.
(md_convert_frag): Adjust for BFD_ASSEMBLER.
(tc_aout_fix_to_chars): Only include if OBJ_AOUT and not
BFD_ASSEMBLER.
(vax_reg_parse): Make the % register prefix mandatory for ELF,
optional for a.out, and not allowed for VMS.  Adjust all callers.
(md_create_short_jump): Add ATTRIBUTE_UNUSED to unused arguments.
(md_create_long_jump): Likewise.
(md_undefined_symbol): Likewise.
(md_section_align): Likewise.
(md_shortopts): Allow -k and -K for ELF.
(md_parse_option): Set flag_want_pic if -k or -K.
(tc_headers_hook): New function if OBJ_AOUT and not BFD_ASSEMBLER.
(tc_gen_reloc): New function if BFD_ASSEMBLER.
* config/tc-vax.h (tc_headers_hook): Remove.
(TARGET_FORMAT): Set according to object format and target
environment.
(BFD_ARCH, TARGET_ARCH): Define.
(NO_RELOC): Adjust for BFD_ASSEMBLER.
(TC_RELOC_RTSYM_LOC_FIXUP, TC_FIX_ADJUSTABLE)
(tc_fix_adjustable): Define if BFD_ASSEMBLER.
* config/vax-inst.h (VAX_JSB, VAX_CALLS, VAX_CALLG): Define.
This commit is contained in:
Jason Thorpe 2002-06-09 00:45:42 +00:00
parent 05b65acb41
commit 7542c0f275
7 changed files with 602 additions and 244 deletions

View File

@ -1,3 +1,39 @@
2002-06-08 Matt Thomas <matt@3am-software.com>
* configure.in (vax-*-netbsdelf*, vax-*-netbsdaout*)
(vax-*-netbsd*): New targets.
* configure: Regenerate.
* config/aout_gnu.h (enum machine_type): Add M_VAX4K_NETBSD.
* config/tc-vax.c: Add support for ELF and PIC.
(flag_want_pic): New flag.
(float_cons): Fix prototype.
(md_apply_fix3): Adjust for BFD_ASSEMBLER.
(md_assemble): Introduce a new is_absolute local, and use it
rather than repeating the test. Make fatal errors actually
fatal by using as_fatal as appropriate. Adjust for BFD_ASSEMBLER.
Add support for ELF. Add support for PIC.
(md_convert_frag): Adjust for BFD_ASSEMBLER.
(tc_aout_fix_to_chars): Only include if OBJ_AOUT and not
BFD_ASSEMBLER.
(vax_reg_parse): Make the % register prefix mandatory for ELF,
optional for a.out, and not allowed for VMS. Adjust all callers.
(md_create_short_jump): Add ATTRIBUTE_UNUSED to unused arguments.
(md_create_long_jump): Likewise.
(md_undefined_symbol): Likewise.
(md_section_align): Likewise.
(md_shortopts): Allow -k and -K for ELF.
(md_parse_option): Set flag_want_pic if -k or -K.
(tc_headers_hook): New function if OBJ_AOUT and not BFD_ASSEMBLER.
(tc_gen_reloc): New function if BFD_ASSEMBLER.
* config/tc-vax.h (tc_headers_hook): Remove.
(TARGET_FORMAT): Set according to object format and target
environment.
(BFD_ARCH, TARGET_ARCH): Define.
(NO_RELOC): Adjust for BFD_ASSEMBLER.
(TC_RELOC_RTSYM_LOC_FIXUP, TC_FIX_ADJUSTABLE)
(tc_fix_adjustable): Define if BFD_ASSEMBLER.
* config/vax-inst.h (VAX_JSB, VAX_CALLS, VAX_CALLG): Define.
2002-06-08 Alan Modra <amodra@bigpond.net.au>
* Makefile.am: Run "make dep-am".

View File

@ -119,6 +119,7 @@ enum machine_type
M_386 = 100,
M_29K = 101,
M_RS6000 = 102, /* IBM RS/6000 */
M_VAX4K_NETBSD = 150,
/* HP/BSD formats */
M_HP200 = 200, /* hp200 (68010) BSD binary */
M_HP300 = 300, /* hp300 (68020+68881) BSD binary */

View File

@ -23,6 +23,11 @@
#include "vax-inst.h"
#include "obstack.h" /* For FRAG_APPEND_1_CHAR macro in "frags.h" */
#include "subsegs.h"
#ifdef OBJ_ELF
#include "elf/vax.h"
#endif
/* These chars start a comment anywhere in a source file (except inside
another comment */
@ -58,10 +63,20 @@ LITTLENUM_TYPE big_operand_bits[VIT_MAX_OPERANDS][SIZE_OF_LARGE_NUMBER];
FLONUM_TYPE float_operand[VIT_MAX_OPERANDS];
/* Above is made to point into big_operand_bits by md_begin(). */
#ifdef OBJ_ELF
#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
#define PROCEDURE_LINKAGE_TABLE_NAME "_PROCEDURE_LINKAGE_TABLE_"
symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
symbolS *PLT_symbol; /* Pre-defined "_PROCEDURE_LINKAGE_TABLE_" */
#endif
int flag_hash_long_names; /* -+ */
int flag_one; /* -1 */
int flag_show_after_trunc; /* -H */
int flag_no_hash_mixed_case; /* -h NUM */
#ifdef OBJ_ELF
int flag_want_pic; /* -k */
#endif
/*
* For VAX, relative addresses of "just the right length" are easy.
@ -223,7 +238,7 @@ const relax_typeS md_relax_table[] =
#undef WF
#undef WB
void float_cons ();
void float_cons PARAMS ((int));
const pseudo_typeS md_pseudo_table[] =
{
@ -231,7 +246,7 @@ const pseudo_typeS md_pseudo_table[] =
{"ffloat", float_cons, 'f'},
{"gfloat", float_cons, 'g'},
{"hfloat", float_cons, 'h'},
{0},
{NULL, NULL, 0},
};
#define STATE_PC_RELATIVE (1)
@ -251,10 +266,13 @@ int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f,
LITTLENUM_TYPE * words));
static const char *vip_begin PARAMS ((int, const char *, const char *,
const char *));
static void vip_op_1 PARAMS ((int, const char *));
static void vip_op_defaults PARAMS ((const char *, const char *, const char *));
static void vip_op PARAMS ((char *, struct vop *));
static void vip PARAMS ((struct vit *, char *));
static int vax_reg_parse PARAMS ((char, char, char, char));
void
md_begin ()
{
@ -290,14 +308,19 @@ md_number_to_chars (con, value, nbytes)
void /* Knows about order of bytes in address. */
md_apply_fix3 (fixP, valueP, seg)
fixS * fixP;
valueT * valueP;
fixS *fixP;
valueT *valueP;
segT seg ATTRIBUTE_UNUSED;
{
valueT value = * valueP;
number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
value, fixP->fx_size);
#ifdef BFD_ASSEMBLER
if (((fixP->fx_addsy == NULL && fixP->fx_subsy == NULL)
&& fixP->fx_r_type != BFD_RELOC_32_PLT_PCREL
&& fixP->fx_r_type != BFD_RELOC_32_GOT_PCREL)
|| fixP->fx_r_type == NO_RELOC)
#endif
number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
value, fixP->fx_size);
if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
fixP->fx_done = 1;
@ -325,6 +348,8 @@ md_assemble (instruction_string)
{
/* Non-zero if operand expression's segment is not known yet. */
int is_undefined;
/* Non-zero if operand expression's segment is absolute. */
int is_absolute;
int length_code;
char *p;
@ -375,7 +400,7 @@ md_assemble (instruction_string)
*/
if ((goofed = (*v.vit_error)) != 0)
{
as_warn (_("Ignoring statement due to \"%s\""), v.vit_error);
as_fatal (_("Ignoring statement due to \"%s\""), v.vit_error);
}
/*
* We need to use expression() and friends, which require us to diddle
@ -394,7 +419,7 @@ md_assemble (instruction_string)
{ /* for each operand */
if (operandP->vop_error)
{
as_warn (_("Ignoring statement because \"%s\""), operandP->vop_error);
as_fatal (_("Aborting because statement has \"%s\""), operandP->vop_error);
goofed = 1;
}
else
@ -441,7 +466,7 @@ md_assemble (instruction_string)
* instruction operands.
*/
need_pass_2 = 1;
as_warn (_("Can't relocate expression"));
as_fatal (_("Can't relocate expression"));
break;
case O_big:
@ -619,7 +644,7 @@ md_assemble (instruction_string)
}
if (input_line_pointer != operandP->vop_expr_end + 1)
{
as_warn ("Junk at end of expression \"%s\"", input_line_pointer);
as_fatal ("Junk at end of expression \"%s\"", input_line_pointer);
goofed = 1;
}
operandP->vop_expr_end[1] = c_save;
@ -662,7 +687,13 @@ md_assemble (instruction_string)
this_add_number = expP->X_add_number;
this_add_symbol = expP->X_add_symbol;
to_seg = *segP;
#ifdef BFD_ASSEMBLER
is_undefined = (to_seg == undefined_section);
is_absolute = (to_seg == absolute_section);
#else
is_undefined = (to_seg == SEG_UNKNOWN);
is_absolute = (to_seg == SEG_ABSOLUTE);
#endif
at = operandP->vop_mode & 1;
length = (operandP->vop_short == 'b'
? 1 : (operandP->vop_short == 'w'
@ -731,16 +762,20 @@ md_assemble (instruction_string)
/*
* --- SEG FLOAT MAY APPEAR HERE ----
*/
if (to_seg == SEG_ABSOLUTE)
if (is_absolute)
{
if (nbytes)
{
know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
p = frag_more (nbytes);
/* Conventional relocation. */
fix_new (frag_now, p - frag_now->fr_literal,
nbytes, &abs_symbol, this_add_number,
1, NO_RELOC);
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
#ifdef BFD_ASSEMBLER
section_symbol (absolute_section),
#else
&abs_symbol,
#endif
this_add_number, 1, NO_RELOC);
}
else
{
@ -816,15 +851,19 @@ md_assemble (instruction_string)
}
else
{
/* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */
/* to_seg != now_seg && !is_undefinfed && !is_absolute */
if (nbytes > 0)
{
/* Pc-relative. Conventional relocation. */
know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
p = frag_more (nbytes);
fix_new (frag_now, p - frag_now->fr_literal,
nbytes, &abs_symbol, this_add_number,
1, NO_RELOC);
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
#ifdef BFD_ASSEMBLER
section_symbol (absolute_section),
#else
&abs_symbol,
#endif
this_add_number, 1, NO_RELOC);
}
else
{
@ -915,7 +954,7 @@ md_assemble (instruction_string)
|| operandP->vop_access == 'w');
if (operandP->vop_short == 's')
{
if (to_seg == SEG_ABSOLUTE)
if (is_absolute)
{
if (this_add_number >= 64)
{
@ -954,8 +993,14 @@ md_assemble (instruction_string)
if (length == 0)
{
know (operandP->vop_short == ' ');
length_code = STATE_BYTE;
#ifdef OBJ_ELF
if (S_IS_EXTERNAL (this_add_symbol)
|| S_IS_WEAK (this_add_symbol))
length_code = STATE_UNDF;
#endif
p = frag_var (rs_machine_dependent, 10, 2,
ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE),
ENCODE_RELAX (STATE_PC_RELATIVE, length_code),
this_add_symbol, this_add_number,
opcode_low_byteP);
know (operandP->vop_mode == 10 + at);
@ -980,7 +1025,7 @@ md_assemble (instruction_string)
{ /* to_seg != now_seg */
if (this_add_symbol == NULL)
{
know (to_seg == SEG_ABSOLUTE);
know (is_absolute);
/* Do @#foo: simpler relocation than foo-.(pc) anyway. */
p = frag_more (5);
p[0] = VAX_ABSOLUTE_MODE; /* @#... */
@ -995,17 +1040,29 @@ md_assemble (instruction_string)
/* {@}{q^}other_seg */
know ((length == 0 && operandP->vop_short == ' ')
|| (length > 0 && operandP->vop_short != ' '));
if (is_undefined)
if (is_undefined
#ifdef OBJ_ELF
|| S_IS_WEAK(this_add_symbol)
|| S_IS_EXTERNAL(this_add_symbol)
#endif
)
{
switch (length)
{
default: length_code = STATE_UNDF; break;
case 1: length_code = STATE_BYTE; break;
case 2: length_code = STATE_WORD; break;
case 4: length_code = STATE_LONG; break;
}
/*
* We have a SEG_UNKNOWN symbol. It might
* turn out to be in the same segment as
* the instruction, permitting relaxation.
*/
p = frag_var (rs_machine_dependent, 5, 2,
ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
ENCODE_RELAX (STATE_PC_RELATIVE, length_code),
this_add_symbol, this_add_number,
0);
opcode_low_byteP);
p[0] = at << 4;
}
else
@ -1043,7 +1100,7 @@ md_assemble (instruction_string)
one case. */
}
if (length == 0
&& to_seg == SEG_ABSOLUTE && (expP->X_op != O_big)
&& is_absolute && (expP->X_op != O_big)
&& operandP->vop_mode == 8 /* No '@'. */
&& this_add_number < 64)
{
@ -1059,8 +1116,15 @@ md_assemble (instruction_string)
know (nbytes);
p = frag_more (nbytes + 1);
know (operandP->vop_reg == 0xF);
#ifdef OBJ_ELF
if (flag_want_pic && operandP->vop_mode == 8
&& this_add_symbol != NULL)
{
as_warn (_("Symbol used as immediate operand in PIC mode."));
}
#endif
p[0] = (operandP->vop_mode << 4) | 0xF;
if ((to_seg == SEG_ABSOLUTE) && (expP->X_op != O_big))
if ((is_absolute) && (expP->X_op != O_big))
{
/*
* If nbytes > 4, then we are scrod. We
@ -1115,7 +1179,7 @@ md_assemble (instruction_string)
|| (length > 0 && operandP->vop_short != ' '));
if (length == 0)
{
if (to_seg == SEG_ABSOLUTE)
if (is_absolute)
{
long test;
@ -1137,7 +1201,7 @@ md_assemble (instruction_string)
know (operandP->vop_reg >= 0);
p[0] = operandP->vop_reg
| ((at | "?\12\14?\16"[length]) << 4);
if (to_seg == SEG_ABSOLUTE)
if (is_absolute)
{
md_number_to_chars (p + 1, this_add_number, length);
}
@ -1165,21 +1229,65 @@ md_estimate_size_before_relax (fragP, segment)
{
if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
{
if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
if (S_GET_SEGMENT (fragP->fr_symbol) != segment
#ifdef OBJ_ELF
|| S_IS_WEAK (fragP->fr_symbol)
|| S_IS_EXTERNAL (fragP->fr_symbol)
#endif
)
{
/* Non-relaxable cases. */
int reloc_type = NO_RELOC;
char *p;
int old_fr_fix;
old_fr_fix = fragP->fr_fix;
p = fragP->fr_literal + old_fr_fix;
#ifdef OBJ_ELF
/*
* If this is to undefined symbol, then if it's an indirect
* reference indicate that is can mutated into a GLOB_DAT
* by the loader. We restrict ourselves to no offset due to
* a limitation in the NetBSD linker.
*/
if (GOT_symbol == NULL)
GOT_symbol = symbol_find (GLOBAL_OFFSET_TABLE_NAME);
if (PLT_symbol == NULL)
PLT_symbol = symbol_find (PROCEDURE_LINKAGE_TABLE_NAME);
if ((GOT_symbol == NULL || fragP->fr_symbol != GOT_symbol)
&& (PLT_symbol == NULL || fragP->fr_symbol != PLT_symbol)
&& fragP->fr_symbol != NULL
&& (!S_IS_DEFINED (fragP->fr_symbol)
|| S_IS_WEAK (fragP->fr_symbol)
|| S_IS_EXTERNAL (fragP->fr_symbol)))
{
if (p[0] & 0x10)
{
if (flag_want_pic)
as_fatal ("PIC reference to %s is indirect.\n",
S_GET_NAME (fragP->fr_symbol));
}
else
{
if (((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLS
|| ((unsigned char *) fragP->fr_opcode)[0] == VAX_CALLG
|| ((unsigned char *) fragP->fr_opcode)[0] == VAX_JSB
|| ((unsigned char *) fragP->fr_opcode)[0] == VAX_JMP
|| S_IS_FUNCTION (fragP->fr_symbol))
reloc_type = BFD_RELOC_32_PLT_PCREL;
else
reloc_type = BFD_RELOC_32_GOT_PCREL;
}
}
#endif
switch (RELAX_STATE (fragP->fr_subtype))
{
case STATE_PC_RELATIVE:
p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */
fragP->fr_fix += 1 + 4;
fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
fragP->fr_offset, 1, reloc_type);
break;
case STATE_CONDITIONAL_BRANCH:
@ -1272,11 +1380,19 @@ md_estimate_size_before_relax (fragP, segment)
* Out: Any fixSs and constants are set up.
* Caller will turn frag into a ".space 0".
*/
#ifdef BFD_ASSEMBLER
void
md_convert_frag (headers, seg, fragP)
object_headers *headers;
segT seg;
bfd *headers ATTRIBUTE_UNUSED;
segT seg ATTRIBUTE_UNUSED;
fragS *fragP;
#else
void
md_convert_frag (headers, seg, fragP)
object_headers *headers ATTRIBUTE_UNUSED;
segT seg ATTRIBUTE_UNUSED;
fragS *fragP;
#endif
{
char *addressP; /* -> _var to change. */
char *opcodeP; /* -> opcode char(s) to change. */
@ -1284,10 +1400,6 @@ md_convert_frag (headers, seg, fragP)
/* Added to fr_fix: incl. ALL var chars. */
symbolS *symbolP;
long where;
long address_of_var;
/* Where, in file space, is _var of *fragP? */
long target_address = 0;
/* Where, in file space, does addr point? */
know (fragP->fr_type == rs_machine_dependent);
where = fragP->fr_fix;
@ -1295,43 +1407,46 @@ md_convert_frag (headers, seg, fragP)
opcodeP = fragP->fr_opcode;
symbolP = fragP->fr_symbol;
know (symbolP);
target_address = S_GET_VALUE (symbolP) + fragP->fr_offset;
address_of_var = fragP->fr_address + where;
switch (fragP->fr_subtype)
{
case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
addressP[0] |= 0xAF; /* Byte displacement. */
addressP[1] = target_address - (address_of_var + 2);
addressP[0] |= 0xAF; /* Byte displacement. */
fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 2;
break;
case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
addressP[0] |= 0xCF; /* Word displacement. */
md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2);
addressP[0] |= 0xCF; /* Word displacement. */
fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 3;
break;
case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):
know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
addressP[0] |= 0xEF; /* Long word displacement. */
md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
addressP[0] |= 0xEF; /* Long word displacement. */
fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 5;
break;
case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
addressP[0] = target_address - (address_of_var + 1);
fix_new (fragP, fragP->fr_fix, 1, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 1;
break;
case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
opcodeP[0] ^= 1; /* Reverse sense of test. */
addressP[0] = 3;
addressP[1] = VAX_BRB + VAX_WIDEN_WORD;
md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2);
addressP[1] = VAX_BRW;
fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 4;
break;
@ -1340,30 +1455,35 @@ md_convert_frag (headers, seg, fragP)
addressP[0] = 6;
addressP[1] = VAX_JMP;
addressP[2] = VAX_PC_RELATIVE_MODE;
md_number_to_chars (addressP + 3, target_address - (address_of_var + 7), 4);
fix_new (fragP, fragP->fr_fix + 3, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 7;
break;
case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):
addressP[0] = target_address - (address_of_var + 1);
fix_new (fragP, fragP->fr_fix, 1, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 1;
break;
case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):
opcodeP[0] += VAX_WIDEN_WORD; /* brb -> brw, bsbb -> bsbw */
md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
1, NO_RELOC);
extension = 2;
break;
case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):
opcodeP[0] += VAX_WIDEN_LONG; /* brb -> jmp, bsbb -> jsb */
addressP[0] = VAX_PC_RELATIVE_MODE;
md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 5;
break;
case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD):
md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 2;
break;
@ -1374,12 +1494,14 @@ md_convert_frag (headers, seg, fragP)
addressP[3] = 6;
addressP[4] = VAX_JMP;
addressP[5] = VAX_PC_RELATIVE_MODE;
md_number_to_chars (addressP + 6, target_address - (address_of_var + 10), 4);
fix_new (fragP, fragP->fr_fix + 6, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 10;
break;
case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE):
addressP[0] = target_address - (address_of_var + 1);
fix_new (fragP, fragP->fr_fix, 1, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 1;
break;
@ -1388,7 +1510,8 @@ md_convert_frag (headers, seg, fragP)
addressP[1] = VAX_BRB;
addressP[2] = 3;
addressP[3] = VAX_BRW;
md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2);
fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 6;
break;
@ -1398,7 +1521,8 @@ md_convert_frag (headers, seg, fragP)
addressP[2] = 6;
addressP[3] = VAX_JMP;
addressP[4] = VAX_PC_RELATIVE_MODE;
md_number_to_chars (addressP + 5, target_address - (address_of_var + 9), 4);
fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
fragP->fr_offset, 1, NO_RELOC);
extension = 9;
break;
@ -1433,6 +1557,8 @@ md_ri_to_chars (the_bytes, ri)
#endif /* comment */
#ifdef OBJ_AOUT
#ifndef BFD_ASSEMBLER
void
tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
char *where;
@ -1464,6 +1590,8 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
| ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
| (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
}
#endif /* !BFD_ASSEMBLER */
#endif /* OBJ_AOUT */
/*
* BUGS, GRIPES, APOLOGIA, etc.
@ -1978,13 +2106,35 @@ main ()
#define PC (15)
int /* return -1 or 0:15 */
vax_reg_parse (c1, c2, c3) /* 3 chars of register name */
char c1, c2, c3; /* c3 == 0 if 2-character reg name */
vax_reg_parse (c1, c2, c3, c4) /* 3 chars of register name */
char c1, c2, c3, c4; /* c3 == 0 if 2-character reg name */
{
int retval; /* return -1:15 */
retval = -1;
#ifdef OBJ_ELF
if (c1 != '%') /* register prefixes are mandatory for ELF */
return retval;
c1 = c2;
c2 = c3;
c3 = c4;
#endif
#ifdef OBJ_VMS
if (c4 != 0) /* register prefixes are not allowed under VMS */
return retval;
#endif
#ifdef OBJ_AOUT
if (c1 == '%') /* register prefixes are optional under a.out */
{
c1 = c2;
c2 = c3;
c3 = c4;
}
else if (c3 && c4) /* can't be 4 characters long. */
return retval;
#endif
c1 = TOLOWER (c1);
c2 = TOLOWER (c2);
if (ISDIGIT (c2) && c1 == 'r')
@ -2388,9 +2538,11 @@ vip_op (optext, vopP)
* name error. So again we don't need to check for early '\0'.
*/
if (q[3] == ']')
ndx = vax_reg_parse (q[1], q[2], 0);
ndx = vax_reg_parse (q[1], q[2], 0, 0);
else if (q[4] == ']')
ndx = vax_reg_parse (q[1], q[2], q[3]);
ndx = vax_reg_parse (q[1], q[2], q[3], 0);
else if (q[5] == ']')
ndx = vax_reg_parse (q[1], q[2], q[3], q[4]);
else
ndx = -1;
/*
@ -2443,9 +2595,11 @@ vip_op (optext, vopP)
* name error. So again we don't need to check for early '\0'.
*/
if (q[3] == ')')
reg = vax_reg_parse (q[1], q[2], 0);
reg = vax_reg_parse (q[1], q[2], 0, 0);
else if (q[4] == ')')
reg = vax_reg_parse (q[1], q[2], q[3]);
reg = vax_reg_parse (q[1], q[2], q[3], 0);
else if (q[5] == ')')
reg = vax_reg_parse (q[1], q[2], q[3], q[4]);
else
reg = -1;
/*
@ -2515,8 +2669,11 @@ vip_op (optext, vopP)
q--;
/* reverse over whitespace, but don't */
/* run back over *p */
if (q > p && q < p + 3) /* room for Rn or Rnn exactly? */
reg = vax_reg_parse (p[0], p[1], q < p + 2 ? 0 : p[2]);
/* room for Rn or Rnn (include prefix) exactly? */
if (q > p && q < p + 4)
reg = vax_reg_parse (p[0], p[1],
q < p + 2 ? 0 : p[2],
q < p + 3 ? 0 : p[3]);
else
reg = -1; /* always comes here if no register at all */
/*
@ -3065,9 +3222,10 @@ const int md_reloc_size = 8; /* Size of relocation record */
void
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
addressT from_addr, to_addr;
fragS *frag;
symbolS *to_symbol;
addressT from_addr;
addressT to_addr ATTRIBUTE_UNUSED;
fragS *frag ATTRIBUTE_UNUSED;
symbolS *to_symbol ATTRIBUTE_UNUSED;
{
valueT offset;
@ -3083,7 +3241,8 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
void
md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
addressT from_addr, to_addr;
addressT from_addr ATTRIBUTE_UNUSED;
addressT to_addr;
fragS *frag;
symbolS *to_symbol;
{
@ -3098,6 +3257,8 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
#ifdef OBJ_VMS
const char *md_shortopts = "d:STt:V+1h:Hv::";
#elif defined(OBJ_ELC)
const char *md_shortopts = "d:STt:VkK";
#else
const char *md_shortopts = "d:STt:V";
#endif
@ -3164,6 +3325,13 @@ md_parse_option (c, arg)
break;
#endif
#ifdef OBJ_ELF
case 'K':
case 'k':
flag_want_pic = 1;
break; /* -pic, Position Independent Code */
#endif
default:
return 0;
}
@ -3199,7 +3367,7 @@ VMS options:\n\
symbolS *
md_undefined_symbol (name)
char *name;
char *name ATTRIBUTE_UNUSED;
{
return 0;
}
@ -3207,7 +3375,7 @@ md_undefined_symbol (name)
/* Round up a section size to the appropriate boundary. */
valueT
md_section_align (segment, size)
segT segment;
segT segment ATTRIBUTE_UNUSED;
valueT size;
{
return size; /* Byte alignment is fine */
@ -3215,7 +3383,7 @@ md_section_align (segment, size)
/* Exactly what point is a PC-relative offset relative TO?
On the vax, they're relative to the address of the offset, plus
its size. (??? Is this right? FIXME-SOON) */
its size. */
long
md_pcrel_from (fixP)
fixS *fixP;
@ -3223,4 +3391,96 @@ md_pcrel_from (fixP)
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}
#ifdef OBJ_AOUT
#ifndef BFD_ASSEMBLER
void
tc_headers_hook(headers)
object_headers *headers;
{
#ifdef TE_NetBSD
N_SET_INFO(headers->header, OMAGIC, M_VAX4K_NETBSD, 0);
headers->header.a_info = htonl(headers->header.a_info);
#endif
}
#endif /* !BFD_ASSEMBLER */
#endif /* OBJ_AOUT */
#ifdef BFD_ASSEMBLER
arelent *
tc_gen_reloc (section, fixp)
asection *section ATTRIBUTE_UNUSED;
fixS *fixp;
{
arelent *reloc;
bfd_reloc_code_real_type code;
if (fixp->fx_tcbit)
abort();
if (fixp->fx_r_type != BFD_RELOC_NONE)
{
code = fixp->fx_r_type;
if (fixp->fx_pcrel)
{
switch (code)
{
case BFD_RELOC_8_PCREL:
case BFD_RELOC_16_PCREL:
case BFD_RELOC_32_PCREL:
#ifdef OBJ_ELF
case BFD_RELOC_8_GOT_PCREL:
case BFD_RELOC_16_GOT_PCREL:
case BFD_RELOC_32_GOT_PCREL:
case BFD_RELOC_8_PLT_PCREL:
case BFD_RELOC_16_PLT_PCREL:
case BFD_RELOC_32_PLT_PCREL:
#endif
break;
default:
as_bad_where (fixp->fx_file, fixp->fx_line,
_("Cannot make %s relocation PC relative"),
bfd_get_reloc_code_name (code));
}
}
}
else
{
#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
switch (F (fixp->fx_size, fixp->fx_pcrel))
{
#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
MAP (1, 0, BFD_RELOC_8);
MAP (2, 0, BFD_RELOC_16);
MAP (4, 0, BFD_RELOC_32);
MAP (1, 1, BFD_RELOC_8_PCREL);
MAP (2, 1, BFD_RELOC_16_PCREL);
MAP (4, 1, BFD_RELOC_32_PCREL);
default:
abort ();
}
}
#undef F
#undef MAP
reloc = (arelent *) xmalloc (sizeof (arelent));
reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
#ifndef OBJ_ELF
if (fixp->fx_pcrel)
reloc->addend = fixp->fx_addnumber;
else
reloc->addend = 0;
#else
reloc->addend = fixp->fx_offset;
#endif
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
assert (reloc->howto != 0);
return reloc;
}
#endif /* BFD_ASSEMBLER */
/* end of tc-vax.c */

View File

@ -23,12 +23,35 @@
#define TARGET_BYTES_BIG_ENDIAN 0
#define NO_RELOC 0
#define NOP_OPCODE 0x01
#ifdef OBJ_AOUT
#ifdef TE_NetBSD
#define TARGET_FORMAT "a.out-vax-netbsd"
#endif
#ifndef TARGET_FORMAT
#define TARGET_FORMAT "a.out-vax-bsd"
#endif
#endif
#ifdef OBJ_VMS
#define TARGET_FORMAT "vms-vax"
#endif
#ifdef OBJ_ELF
#define TARGET_FORMAT "elf32-vax"
#endif
#define BFD_ARCH bfd_arch_vax /* for non-BFD_ASSEMBLER */
#define TARGET_ARCH bfd_arch_vax /* BFD_ASSEMBLER */
#ifdef BFD_ASSEMBLER
#define NO_RELOC BFD_RELOC_NONE
#else
#define NO_RELOC 0
#endif
#define NOP_OPCODE 0x01
#define tc_aout_pre_write_hook(x) {;} /* not used */
#define tc_crawl_symbol_chain(a) {;} /* not used */
#define tc_headers_hook(a) {;} /* not used */
#define md_operand(x)
long md_chars_to_number PARAMS ((unsigned char *, int));
@ -36,6 +59,35 @@ long md_chars_to_number PARAMS ((unsigned char *, int));
extern const struct relax_type md_relax_table[];
#define TC_GENERIC_RELAX_TABLE md_relax_table
/* This expression evaluates to false if the relocation is for a local object
for which we still want to do the relocation at runtime. True if we
are willing to perform this relocation while building the .o file. If
the reloc is against an externally visible symbol, then the assembler
should never do the relocation. */
#ifdef BFD_ASSEMBLER
#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
((FIX)->fx_addsy == NULL \
|| (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
&& ! S_IS_WEAK ((FIX)->fx_addsy) \
&& S_IS_DEFINED ((FIX)->fx_addsy) \
&& ! S_IS_COMMON ((FIX)->fx_addsy)))
#define TC_FIX_ADJUSTABLE(FIX) \
(!symbol_used_in_reloc_p ((FIX)) && tc_fix_adjustable ((FIX)))
#define tc_fix_adjustable(FIX) \
((FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \
&& (FIX)->fx_r_type != BFD_RELOC_32_PLT_PCREL \
&& (FIX)->fx_r_type != BFD_RELOC_32_GOT_PCREL \
&& (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \
&& ! S_IS_EXTERNAL ((FIX)->fx_addsy) \
&& ! S_IS_WEAK ((FIX)->fx_addsy) \
&& ((FIX)->fx_pcrel \
|| ((FIX)->fx_subsy != NULL \
&& (S_GET_SEGMENT ((FIX)->fx_subsy) \
== S_GET_SEGMENT ((FIX)->fx_addsy))) \
|| S_IS_LOCAL ((FIX)->fx_addsy)))
#endif
/*
* Local Variables:
* comment-column: 0

View File

@ -54,11 +54,14 @@ typedef long vax_opcodeT; /* For initialising array of opcodes */
#define VAX_WIDTH_WORD_JUMP '!' /* and VIT_OPCODE_SYNTHETIC set. */
#define VAX_WIDTH_BYTE_JUMP ':' /* */
#define VAX_JSB (0x16) /* Jump to subroutine */
#define VAX_JMP (0x17) /* Useful for branch optimising. Jump instr*/
#define VAX_PC_RELATIVE_MODE (0xef) /* Use it after VAX_JMP */
#define VAX_ABSOLUTE_MODE (0x9F)/* Use as @#... */
#define VAX_BRB (0x11) /* Canonical branch. */
#define VAX_BRW (0x31) /* Another canonical branch */
#define VAX_CALLS (0xFB) /* Call with arg list on stack */
#define VAX_CALLG (0xFA) /* Call with arg list in memory */
#define VAX_WIDEN_WORD (0x20) /* Add this to byte branch to get word br. */
#define VAX_WIDEN_LONG (0x6) /* Add this to byte branch to get long jmp.*/
/* Needs VAX_PC_RELATIVE_MODE byte after it*/

341
gas/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -480,6 +480,9 @@ changequote([,])dnl
v850e-*-*) fmt=elf bfd_gas=yes ;;
v850ea-*-*) fmt=elf bfd_gas=yes ;;
vax-*-netbsdelf*) fmt=elf em=nbsd bfd_gas=yes ;;
vax-*-netbsdaout* | vax-*-netbsd*)
fmt=aout em=nbsd ;;
vax-*-bsd* | vax-*-ultrix*)
fmt=aout ;;
vax-*-vms) fmt=vms ;;