* no more relocation_info structures. We now squirt directly from
fixS's. * i960-bout and i960-coff "tested" against their predecessors.
This commit is contained in:
parent
b6de2014a1
commit
a79c6033ed
@ -93,16 +93,6 @@ const pseudo_typeS obj_pseudo_table[] = {
|
||||
|
||||
/* Relocation. */
|
||||
|
||||
/*
|
||||
* In: length of relocation (or of address) in chars: 1, 2 or 4.
|
||||
* Out: GNU LD relocation length code: 0, 1, or 2.
|
||||
*/
|
||||
|
||||
static unsigned char
|
||||
nbytes_r_length [] = {
|
||||
42, 0, 1, 42, 2
|
||||
};
|
||||
|
||||
/*
|
||||
* emit_relocations()
|
||||
*
|
||||
@ -113,40 +103,13 @@ char **where;
|
||||
fixS *fixP; /* Fixup chain for this segment. */
|
||||
relax_addressT segment_address_in_file;
|
||||
{
|
||||
struct relocation_info ri;
|
||||
register symbolS * symbolP;
|
||||
|
||||
/* If a machine dependent emitter is needed, call it instead. */
|
||||
if (md_emit_relocations) {
|
||||
(*md_emit_relocations) (fixP, segment_address_in_file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* JF this is for paranoia */
|
||||
bzero((char *)&ri,sizeof(ri));
|
||||
for (; fixP; fixP = fixP->fx_next) {
|
||||
if ((symbolP = fixP->fx_addsy) != 0) {
|
||||
ri . r_bsr = fixP->fx_bsr;
|
||||
ri . r_disp = fixP->fx_im_disp;
|
||||
ri . r_callj = fixP->fx_callj;
|
||||
ri . r_length = nbytes_r_length [fixP->fx_size];
|
||||
ri . r_pcrel = fixP->fx_pcrel;
|
||||
ri . r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file;
|
||||
|
||||
if (S_GET_TYPE(symbolP) == N_UNDF) {
|
||||
ri . r_extern = 1;
|
||||
ri . r_symbolnum = symbolP->sy_number;
|
||||
} else {
|
||||
ri . r_extern = 0;
|
||||
ri . r_symbolnum = S_GET_TYPE(symbolP);
|
||||
}
|
||||
|
||||
/* Output the relocation information in machine-dependent form. */
|
||||
md_ri_to_chars(*where, &ri);
|
||||
*where += md_reloc_size;
|
||||
}
|
||||
}
|
||||
for (; fixP; fixP = fixP->fx_next) {
|
||||
if (fixP->fx_addsy != NULL) {
|
||||
tc_bout_fix_to_chars(*where, fixP, segment_address_in_file);
|
||||
where += sizeof(struct relocation_info);
|
||||
} /* if there's a symbol */
|
||||
} /* for each fixup */
|
||||
|
||||
} /* emit_relocations() */
|
||||
|
||||
/* Aout file generation & utilities */
|
||||
@ -168,7 +131,7 @@ object_headers *headers;
|
||||
headers->header.a_balign = section_alignment[SEG_BSS];
|
||||
|
||||
headers->header.a_tload = 0;
|
||||
headers->header.a_dload = md_section_align(SEG_DATA, headers->header.a_text);
|
||||
headers->header.a_dload = md_section_align(SEG_DATA, H_GET_TEXT_SIZE(headers));
|
||||
|
||||
append(where, (char *) &headers->header, sizeof(headers->header));
|
||||
} /* a_header_append() */
|
||||
|
@ -247,6 +247,7 @@ struct relocation_info {
|
||||
H_GET_DATA_RELOCATION_SIZE(h) + \
|
||||
(h)->string_table_size)
|
||||
|
||||
#define H_GET_HEADER_SIZE(h) (sizeof(struct exec))
|
||||
#define H_GET_TEXT_SIZE(h) ((h)->header.a_text)
|
||||
#define H_GET_DATA_SIZE(h) ((h)->header.a_data)
|
||||
#define H_GET_BSS_SIZE(h) ((h)->header.a_bss)
|
||||
@ -256,6 +257,8 @@ struct relocation_info {
|
||||
#define H_GET_MAGIC_NUMBER(h) ((h)->header.a_info)
|
||||
#define H_GET_ENTRY_POINT(h) ((h)->header.a_entry)
|
||||
#define H_GET_STRING_SIZE(h) ((h)->string_table_size)
|
||||
#define H_GET_LINENO_SIZE(h) (0)
|
||||
|
||||
#ifdef EXEC_MACHINE_TYPE
|
||||
#define H_GET_MACHINE_TYPE(h) ((h)->header.a_machtype)
|
||||
#endif /* EXEC_MACHINE_TYPE */
|
||||
@ -263,9 +266,9 @@ struct relocation_info {
|
||||
#define H_GET_VERSION(h) ((h)->header.a_version)
|
||||
#endif /* EXEC_VERSION */
|
||||
|
||||
#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = md_section_align(SEG_TEXT, (v)))
|
||||
#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = md_section_align(SEG_DATA, (v)))
|
||||
#define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = md_section_align(SEG_BSS, (v)))
|
||||
#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = (v))
|
||||
#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = (v))
|
||||
#define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = (v))
|
||||
|
||||
#define H_SET_RELOCATION_SIZE(h,t,d) (H_SET_TEXT_RELOCATION_SIZE((h),(t)),\
|
||||
H_SET_DATA_RELOCATION_SIZE((h),(d)))
|
||||
@ -302,6 +305,13 @@ typedef struct {
|
||||
#define OBJ_EMIT_LINENO(a, b, c) ;
|
||||
#define obj_pre_write_hook(a) ;
|
||||
|
||||
#ifdef __STDC__
|
||||
struct fix;
|
||||
void tc_aout_fix_to_chars(char *where, struct fix *fixP, relax_addressT segment_address);
|
||||
#else
|
||||
void tc_aout_fix_to_chars();
|
||||
#endif /* __STDC__ */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* comment-column: 0
|
||||
|
@ -903,29 +903,6 @@ symbolS *to_symbol;
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Translate internal representation of relocation info to target format.
|
||||
|
||||
On sparc/29k: first 4 bytes are normal unsigned long address, next three
|
||||
bytes are index, most sig. byte first. Byte 7 is broken up with
|
||||
bit 7 as external, bits 6 & 5 unused, and the lower
|
||||
five bits as relocation type. Next 4 bytes are long addend. */
|
||||
/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
|
||||
void
|
||||
md_ri_to_chars(the_bytes, ri)
|
||||
char *the_bytes;
|
||||
struct reloc_info_generic *ri;
|
||||
{
|
||||
/* this is easy */
|
||||
md_number_to_chars(the_bytes, ri->r_address, 4);
|
||||
/* now the fun stuff */
|
||||
the_bytes[4] = (ri->r_index >> 16) & 0x0ff;
|
||||
the_bytes[5] = (ri->r_index >> 8) & 0x0ff;
|
||||
the_bytes[6] = ri->r_index & 0x0ff;
|
||||
the_bytes[7] = ((ri->r_extern << 7) & 0x80) | (0 & 0x60) | (ri->r_type & 0x1F);
|
||||
/* Also easy */
|
||||
md_number_to_chars(&the_bytes[8], ri->r_addend, 4);
|
||||
}
|
||||
|
||||
/* should never be called for 29k */
|
||||
void md_convert_frag(headers, fragP)
|
||||
object_headers *headers;
|
||||
@ -1012,48 +989,45 @@ print_insn(insn)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Sparc/A29K relocations are completely different, so it needs
|
||||
* this machine dependent routine to emit them.
|
||||
*/
|
||||
/* Translate internal representation of relocation info to target format.
|
||||
|
||||
On sparc/29k: first 4 bytes are normal unsigned long address, next three
|
||||
bytes are index, most sig. byte first. Byte 7 is broken up with
|
||||
bit 7 as external, bits 6 & 5 unused, and the lower
|
||||
five bits as relocation type. Next 4 bytes are long addend. */
|
||||
/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
|
||||
|
||||
#ifdef OBJ_AOUT
|
||||
static void emit_machine_reloc(fixP, segment_address_in_file)
|
||||
register fixS *fixP;
|
||||
|
||||
void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
|
||||
char *where;
|
||||
fixS *fixP;
|
||||
relax_addressT segment_address_in_file;
|
||||
{
|
||||
struct reloc_info_generic ri;
|
||||
register symbolS *symbolP;
|
||||
extern char *next_object_file_charP;
|
||||
/* !!!! long add_number; */
|
||||
long r_index;
|
||||
|
||||
know(fixP->fx_r_type < NO_RELOC);
|
||||
know(fixP->fx_addsy != NULL);
|
||||
|
||||
r_index = (S_IS_DEFINED(fixP->fx_addsy)
|
||||
? S_GET_TYPE(fixP->fx_addsy)
|
||||
: fixP->fx_addsy->sy_number);
|
||||
|
||||
/* this is easy */
|
||||
md_number_to_chars(where,
|
||||
fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
|
||||
4);
|
||||
|
||||
/* now the fun stuff */
|
||||
where[4] = (r_index >> 16) & 0x0ff;
|
||||
where[5] = (r_index >> 8) & 0x0ff;
|
||||
where[6] = r_index & 0x0ff;
|
||||
where[7] = (((!S_IS_DEFINED(fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
|
||||
/* Also easy */
|
||||
md_number_to_chars(&where[8], fixP->fx_addnumber, 4);
|
||||
|
||||
bzero((char *) &ri, sizeof(ri));
|
||||
for (; fixP; fixP = fixP->fx_next) {
|
||||
|
||||
if (fixP->fx_r_type >= NO_RELOC) {
|
||||
fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
|
||||
abort();
|
||||
}
|
||||
|
||||
if ((symbolP = fixP->fx_addsy) != NULL) {
|
||||
ri.r_address = fixP->fx_frag->fr_address +
|
||||
fixP->fx_where - segment_address_in_file;
|
||||
ri.r_addend = fixP->fx_addnumber;
|
||||
if (!S_IS_DEFINED(symbolP)) {
|
||||
ri.r_extern = 1;
|
||||
ri.r_index = symbolP->sy_number;
|
||||
} else {
|
||||
ri.r_extern = 0;
|
||||
ri.r_index = S_GET_TYPE(symbolP);
|
||||
}
|
||||
ri.r_type = fixP->fx_r_type;
|
||||
|
||||
md_ri_to_chars (next_object_file_charP, &ri);
|
||||
next_object_file_charP += md_reloc_size;
|
||||
}
|
||||
}
|
||||
} /* emit_machine_reloc() */
|
||||
|
||||
void (*md_emit_relocations)() = emit_machine_reloc;
|
||||
return;
|
||||
} /* tc_aout_fix_to_chars() */
|
||||
|
||||
#endif /* OBJ_AOUT */
|
||||
|
||||
|
@ -5,7 +5,7 @@ This file is part of GAS.
|
||||
|
||||
GAS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GAS is distributed in the hope that it will be useful,
|
||||
@ -86,7 +86,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
extern char *input_line_pointer;
|
||||
extern struct hash_control *po_hash;
|
||||
extern unsigned char nbytes_r_length[];
|
||||
extern char *next_object_file_charP;
|
||||
|
||||
#ifdef OBJ_COFF
|
||||
@ -95,20 +94,6 @@ int md_reloc_size = sizeof(struct reloc);
|
||||
int md_reloc_size = sizeof(struct relocation_info);
|
||||
#endif /* OBJ_COFF */
|
||||
|
||||
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
|
||||
#ifdef __STDC__
|
||||
|
||||
static void emit_machine_reloc(fixS *fixP, relax_addressT segment_address_in_file);
|
||||
|
||||
#else /* __STDC__ */
|
||||
|
||||
static void emit_machine_reloc();
|
||||
|
||||
#endif /* __STDC__ */
|
||||
|
||||
void (*md_emit_relocations)() = emit_machine_reloc;
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
|
||||
/***************************
|
||||
* Local i80960 routines *
|
||||
************************** */
|
||||
@ -621,6 +606,8 @@ md_number_to_chars(buf, value, n)
|
||||
if (value != 0 && value != -1){
|
||||
as_bad("Displacement too long for instruction field length.");
|
||||
}
|
||||
|
||||
return;
|
||||
} /* md_number_to_chars() */
|
||||
|
||||
/*****************************************************************************
|
||||
@ -892,7 +879,8 @@ md_parse_option(argP, cntP, vecP)
|
||||
*
|
||||
**************************************************************************** */
|
||||
void
|
||||
md_convert_frag(fragP)
|
||||
md_convert_frag(headers, fragP)
|
||||
object_headers *headers;
|
||||
fragS * fragP;
|
||||
{
|
||||
fixS *fixP; /* Structure describing needed address fix */
|
||||
@ -959,27 +947,13 @@ md_estimate_size_before_relax(fragP, segment_type)
|
||||
* we leave it in host byte order.
|
||||
*
|
||||
**************************************************************************** */
|
||||
void md_ri_to_chars(the_bytes, ri)
|
||||
char *the_bytes;
|
||||
struct reloc_info_generic *ri;
|
||||
void md_ri_to_chars(where, ri)
|
||||
char *where;
|
||||
struct relocation_info *ri;
|
||||
{
|
||||
struct relocation_info br;
|
||||
|
||||
(void) bzero(&br, sizeof(br));
|
||||
|
||||
br.r_address = ri->r_address;
|
||||
br.r_index = ri->r_index;
|
||||
br.r_pcrel = ri->r_pcrel;
|
||||
br.r_length = ri->r_length;
|
||||
br.r_extern = ri->r_extern;
|
||||
br.r_bsr = ri->r_bsr;
|
||||
br.r_disp = ri->r_disp;
|
||||
br.r_callj = ri->r_callj;
|
||||
|
||||
*((struct relocation_info *) the_bytes) = br;
|
||||
*((struct relocation_info *) where) = *ri; /* structure assignment */
|
||||
} /* md_ri_to_chars() */
|
||||
|
||||
|
||||
#ifndef WORKING_DOT_WORD
|
||||
|
||||
int md_short_jump_size = 0;
|
||||
@ -1393,14 +1367,14 @@ get_ispec(textP)
|
||||
|
||||
/* Find opening square bracket, if any
|
||||
*/
|
||||
start = index(textP, '[');
|
||||
start = strchr(textP, '[');
|
||||
|
||||
if (start != NULL){
|
||||
|
||||
/* Eliminate '[', detach from rest of operand */
|
||||
*start++ = '\0';
|
||||
|
||||
end = index(start, ']');
|
||||
end = strchr(start, ']');
|
||||
|
||||
if (end == NULL){
|
||||
as_bad("unmatched '['");
|
||||
@ -2569,54 +2543,41 @@ md_apply_fix(fixP, val)
|
||||
} /* md_apply_fix() */
|
||||
|
||||
#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
|
||||
/*
|
||||
* emit_relocations()
|
||||
*
|
||||
* Crawl along a fixS chain. Emit the segment's relocations.
|
||||
*/
|
||||
static void
|
||||
emit_machine_reloc (fixP, segment_address_in_file)
|
||||
register fixS * fixP; /* Fixup chain for this segment. */
|
||||
relax_addressT segment_address_in_file;
|
||||
void tc_bout_fix_to_chars(where, fixP, segment_address_in_file)
|
||||
char *where;
|
||||
fixS *fixP;
|
||||
relax_addressT segment_address_in_file;
|
||||
{
|
||||
struct reloc_info_generic ri;
|
||||
register symbolS * symbolP;
|
||||
|
||||
static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
|
||||
struct relocation_info ri;
|
||||
symbolS *symbolP;
|
||||
|
||||
/* JF this is for paranoia */
|
||||
bzero((char *)&ri,sizeof(ri));
|
||||
for (; fixP; fixP = fixP->fx_next)
|
||||
{
|
||||
if ((symbolP = fixP->fx_addsy) != 0)
|
||||
{
|
||||
/* These two 'cuz of NS32K */
|
||||
ri . r_bsr = fixP->fx_bsr;
|
||||
ri . r_disp = fixP->fx_im_disp;
|
||||
|
||||
ri . r_callj = fixP->fx_callj;
|
||||
|
||||
ri . r_length = nbytes_r_length [fixP->fx_size];
|
||||
ri . r_pcrel = fixP->fx_pcrel;
|
||||
ri . r_address = fixP->fx_frag->fr_address
|
||||
+ fixP->fx_where
|
||||
- segment_address_in_file;
|
||||
if (!S_IS_DEFINED(symbolP))
|
||||
{
|
||||
ri . r_extern = 1;
|
||||
ri . r_symbolnum = symbolP->sy_number;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri . r_extern = 0;
|
||||
ri . r_symbolnum = S_GET_TYPE(symbolP);
|
||||
}
|
||||
|
||||
/* Output the relocation information in machine-dependent form. */
|
||||
md_ri_to_chars(next_object_file_charP, &ri);
|
||||
next_object_file_charP += sizeof(struct relocation_info);
|
||||
bzero((char *)&ri, sizeof(ri));
|
||||
|
||||
know((symbolP = fixP->fx_addsy) != 0);
|
||||
|
||||
/* These two 'cuz of NS32K */
|
||||
ri.r_callj = fixP->fx_callj;
|
||||
|
||||
ri.r_length = nbytes_r_length[fixP->fx_size];
|
||||
ri.r_pcrel = fixP->fx_pcrel;
|
||||
ri.r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file;
|
||||
|
||||
if (!S_IS_DEFINED(symbolP)) {
|
||||
ri.r_extern = 1;
|
||||
ri.r_index = symbolP->sy_number;
|
||||
} else {
|
||||
ri.r_extern = 0;
|
||||
ri.r_index = S_GET_TYPE(symbolP);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the relocation information in machine-dependent form. */
|
||||
md_ri_to_chars(where, &ri);
|
||||
|
||||
return;
|
||||
} /* tc_bout_fix_to_chars() */
|
||||
|
||||
} /* emit_machine_reloc() */
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
|
||||
/* Align an address by rounding it up to the specified boundary.
|
||||
|
@ -1009,7 +1009,7 @@ static struct hash_control* op_hash = NULL; /* handle of the OPCODE hash table
|
||||
* No argument string should generate such an error string:
|
||||
* it means a bug in our code, not in the user's text.
|
||||
*
|
||||
* You MUST have called m86_ip_begin() once and m86_ip_end() never before using
|
||||
* You MUST have called m68_ip_begin() once and m86_ip_end() never before using
|
||||
* this function.
|
||||
*/
|
||||
|
||||
@ -1068,9 +1068,13 @@ char *instring;
|
||||
}
|
||||
|
||||
/* found a legitimate opcode, start matching operands */
|
||||
for(opP= &the_ins.operands[0];*p;opP++) {
|
||||
p = crack_operand (p, opP);
|
||||
if(opP->error) {
|
||||
while (*p == ' ') ++p;
|
||||
|
||||
for(opP = &the_ins.operands[0]; *p; opP++) {
|
||||
|
||||
p = crack_operand(p, opP);
|
||||
|
||||
if (opP->error) {
|
||||
the_ins.error=opP->error;
|
||||
return;
|
||||
}
|
||||
@ -3089,6 +3093,7 @@ bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower
|
||||
nibble as nuthin. (on Sun 3 at least) */
|
||||
/* Translate the internal relocation information into target-specific
|
||||
format. */
|
||||
#ifdef comment
|
||||
void
|
||||
md_ri_to_chars(the_bytes, ri)
|
||||
char *the_bytes;
|
||||
@ -3103,6 +3108,46 @@ md_ri_to_chars(the_bytes, ri)
|
||||
the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) |
|
||||
((ri->r_extern << 4) & 0x10));
|
||||
}
|
||||
#endif /* comment */
|
||||
|
||||
void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
|
||||
char *where;
|
||||
fixS *fixP;
|
||||
relax_addressT segment_address_in_file;
|
||||
{
|
||||
/*
|
||||
* In: length of relocation (or of address) in chars: 1, 2 or 4.
|
||||
* Out: GNU LD relocation length code: 0, 1, or 2.
|
||||
*/
|
||||
|
||||
static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
|
||||
|
||||
long r_extern;
|
||||
long r_symbolnum;
|
||||
|
||||
/* this is easy */
|
||||
md_number_to_chars(where,
|
||||
fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
|
||||
4);
|
||||
|
||||
/* now the fun stuff */
|
||||
if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) {
|
||||
r_extern = 1;
|
||||
r_symbolnum = fixP->fx_addsy->sy_number;
|
||||
} else {
|
||||
r_extern = 0;
|
||||
r_symbolnum = S_GET_TYPE(fixP->fx_addsy);
|
||||
}
|
||||
|
||||
where[4] = (r_symbolnum >> 16) & 0x0ff;
|
||||
where[5] = (r_symbolnum >> 8) & 0x0ff;
|
||||
where[6] = r_symbolnum & 0x0ff;
|
||||
where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) |
|
||||
((r_extern << 4) & 0x10));
|
||||
|
||||
return;
|
||||
} /* tc_aout_fix_to_chars() */
|
||||
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
|
||||
#ifndef WORKING_DOT_WORD
|
||||
|
@ -42,7 +42,7 @@ static void sparc_ip();
|
||||
|
||||
static enum sparc_architecture current_architecture = v6;
|
||||
static int architecture_requested = 0;
|
||||
static int warn_on_bump = 1;
|
||||
static int warn_on_bump = 0;
|
||||
|
||||
const relax_typeS md_relax_table[] = {
|
||||
0 };
|
||||
@ -428,7 +428,7 @@ char *str;
|
||||
struct sparc_opcode *insn;
|
||||
char *argsStart;
|
||||
unsigned long opcode;
|
||||
unsigned int mask;
|
||||
unsigned int mask = 0;
|
||||
int match = 0;
|
||||
int comma = 0;
|
||||
|
||||
@ -787,44 +787,134 @@ char *str;
|
||||
/* start-sanitize-v9 */
|
||||
#ifndef NO_V9
|
||||
case 'j':
|
||||
case 'u':
|
||||
case 'U':
|
||||
#endif /* NO_V9 */
|
||||
/* end-sanitize-v9 */
|
||||
case 'e': /* next operand is a floating point register */
|
||||
case 'v':
|
||||
case 'V':
|
||||
|
||||
case 'f':
|
||||
case 'B':
|
||||
case 'R':
|
||||
|
||||
case 'g':
|
||||
if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) {
|
||||
mask = *s++;
|
||||
if (isdigit(*s)) {
|
||||
mask = 10 * (mask - '0') + (*s++ - '0');
|
||||
if (mask >= 32) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mask -= '0';
|
||||
}
|
||||
switch (*args) {
|
||||
|
||||
case 'e':
|
||||
opcode |= RS1(mask);
|
||||
continue;
|
||||
|
||||
case 'f':
|
||||
opcode |= RS2(mask);
|
||||
continue;
|
||||
|
||||
case 'g':
|
||||
opcode |= RD(mask);
|
||||
continue;
|
||||
case 'H':
|
||||
case 'J': {
|
||||
char format;
|
||||
|
||||
if (*s++ == '%'
|
||||
|
||||
/* start-sanitize-v9 */
|
||||
#ifndef NO_V9
|
||||
case 'j':
|
||||
opcode |= (mask & 0x1f) << 9;
|
||||
continue;
|
||||
&& ((format = *s) == 'f'
|
||||
|| *s == 'd'
|
||||
|| *s == 'q')
|
||||
#else
|
||||
/* end-sanitize-v9 */
|
||||
&& ((format = *s) == 'f')
|
||||
|
||||
/* start-sanitize-v9 */
|
||||
#endif /* NO_V9 */
|
||||
/* end-sanitize-v9 */
|
||||
}
|
||||
}
|
||||
&& isdigit(*++s)) {
|
||||
|
||||
|
||||
|
||||
for (mask = 0; isdigit(*s); ++s) {
|
||||
mask = 10 * mask + (*s - '0');
|
||||
} /* read the number */
|
||||
|
||||
if ((*args == 'u'
|
||||
|| *args == 'v'
|
||||
|| *args == 'B'
|
||||
|| *args == 'H')
|
||||
&& (mask & 1)) {
|
||||
break;
|
||||
} /* register must be even numbered */
|
||||
|
||||
if ((*args == 'U'
|
||||
|| *args == 'V'
|
||||
|| *args == 'R'
|
||||
|| *args == 'J')
|
||||
&& (mask & 3)) {
|
||||
break;
|
||||
} /* register must be multiple of 4 */
|
||||
|
||||
if (format == 'f') {
|
||||
if (mask >= 32) {
|
||||
error_message = ": There are only 32 f registers; [0-31]";
|
||||
goto error;
|
||||
} /* on error */
|
||||
/* start-sanitize-v9 */
|
||||
#ifndef NO_V9
|
||||
} else {
|
||||
if (format == 'd') {
|
||||
if (mask >= 64) {
|
||||
error_message = ": There are only 32 d registers [0, 2, ... 62].";
|
||||
goto error;
|
||||
} else if (mask & 1) {
|
||||
error_message = ": Only even numbered d registers exist.";
|
||||
goto error;
|
||||
} /* on error */
|
||||
|
||||
} else if (format == 'q') {
|
||||
if (mask >= 64) {
|
||||
error_message =
|
||||
": There are only 16 q registers [0, 4, ... 60].";
|
||||
goto error;
|
||||
} else if (mask & 3) {
|
||||
error_message =
|
||||
": Only q registers evenly divisible by four exist.";
|
||||
goto error;
|
||||
} /* on error */
|
||||
} else {
|
||||
know(0);
|
||||
} /* depending on format */
|
||||
|
||||
if (mask >= 32) {
|
||||
mask -= 31;
|
||||
} /* wrap high bit */
|
||||
} /* if not an 'f' register. */
|
||||
#endif /* NO_V9 */
|
||||
/* end-sanitize-v9 */
|
||||
} /* on error */
|
||||
|
||||
switch (*args) {
|
||||
/* start-sanitize-v9 */
|
||||
#ifndef NO_V9
|
||||
case 'j':
|
||||
case 'u':
|
||||
case 'U':
|
||||
opcode |= (mask & 0x1f) << 9;
|
||||
continue;
|
||||
#endif /* NO_V9 */
|
||||
/* end-sanitize-v9 */
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
case 'e':
|
||||
opcode |= RS1(mask);
|
||||
continue;
|
||||
|
||||
|
||||
case 'f':
|
||||
case 'B':
|
||||
case 'R':
|
||||
opcode |= RS2(mask);
|
||||
continue;
|
||||
|
||||
case 'g':
|
||||
case 'H':
|
||||
case 'J':
|
||||
opcode |= RD(mask);
|
||||
continue;
|
||||
} /* pack it in. */
|
||||
|
||||
know(0);
|
||||
break;
|
||||
} /* float arg */
|
||||
|
||||
case 'F':
|
||||
if (strncmp(s, "%fsr", 4) == 0) {
|
||||
@ -1208,28 +1298,20 @@ long val;
|
||||
/* start-sanitize-v9 */
|
||||
#ifndef NO_V9
|
||||
case RELOC_11:
|
||||
#if 0
|
||||
/* ??? Bogus overflow test. This is a signed value, so
|
||||
the upper bits can be set if the sign bit is set. */
|
||||
if (val & ~0x7ff) {
|
||||
if (((val > 0) && (val & ~0x7ff))
|
||||
|| ((val < 0) && (~val & ~0x7ff))) {
|
||||
as_bad("relocation overflow.");
|
||||
} /* on overflow */
|
||||
#endif
|
||||
|
||||
buf[2] = (val >> 8) & 0x7;
|
||||
buf[3] = val & 0xff;
|
||||
break;
|
||||
|
||||
case RELOC_WDISP2_14:
|
||||
#if 0
|
||||
/* ??? Bogus overflow test. This is a signed value, so
|
||||
the upper bits can be set if the sign bit is set. */
|
||||
/* ??? This tests the wrong 16 bits also, should test
|
||||
~0x3fffc0. */
|
||||
if (val & ~0xffff) {
|
||||
if (((val > 0) && (val & ~0x3fffc))
|
||||
|| ((val < 0) && (~val & ~0x3fffc))) {
|
||||
as_bad("relocation overflow.");
|
||||
} /* on overflow */
|
||||
#endif
|
||||
|
||||
val = (val >>= 2) + 1;
|
||||
buf[1] |= ((val >> 14) & 0x3) << 3;
|
||||
@ -1238,15 +1320,10 @@ long val;
|
||||
break;
|
||||
|
||||
case RELOC_WDISP19:
|
||||
#if 0
|
||||
/* ??? Bogus overflow test. This is a signed value, so
|
||||
the upper bits can be set if the sign bit is set. */
|
||||
/* ??? This tests the wrong 19 bits also, should test
|
||||
~0x1ffffc0. */
|
||||
if (val & ~0x7ffff) {
|
||||
if (((val > 0) && (val & ~0x1ffffc))
|
||||
|| ((val < 0) && (~val & ~0x1ffffc))) {
|
||||
as_bad("relocation overflow.");
|
||||
} /* on overflow */
|
||||
#endif
|
||||
|
||||
val = (val >>= 2) + 1;
|
||||
buf[1] |= (val >> 16) & 0x7;
|
||||
@ -1255,7 +1332,7 @@ long val;
|
||||
break;
|
||||
|
||||
case RELOC_HHI22:
|
||||
val >> 32;
|
||||
val >>= 32;
|
||||
/* intentional fallthrough */
|
||||
#endif /* NO_V9 */
|
||||
/* end-sanitize-v9 */
|
||||
@ -1345,23 +1422,56 @@ symbolS *to_symbol;
|
||||
bit 7 as external, bits 6 & 5 unused, and the lower
|
||||
five bits as relocation type. Next 4 bytes are long addend. */
|
||||
/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
|
||||
void md_ri_to_chars(the_bytes, ri)
|
||||
char *the_bytes;
|
||||
struct reloc_info_generic *ri;
|
||||
void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
|
||||
char *where;
|
||||
fixS *fixP;
|
||||
relax_addressT segment_address_in_file;
|
||||
{
|
||||
long r_index;
|
||||
long r_extern;
|
||||
long r_addend;
|
||||
long r_address;
|
||||
|
||||
know(fixP->fx_addsy);
|
||||
|
||||
if ((S_GET_TYPE(fixP->fx_addsy)) == N_UNDF) {
|
||||
r_extern = 1;
|
||||
r_index = fixP->fx_addsy->sy_number;
|
||||
} else {
|
||||
r_extern = 0;
|
||||
r_index = S_GET_TYPE(fixP->fx_addsy);
|
||||
}
|
||||
|
||||
/* this is easy */
|
||||
md_number_to_chars(the_bytes, ri->r_address, 4);
|
||||
md_number_to_chars(where,
|
||||
r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
|
||||
4);
|
||||
|
||||
/* now the fun stuff */
|
||||
the_bytes[4] = (ri->r_index >> 16) & 0x0ff;
|
||||
the_bytes[5] = (ri->r_index >> 8) & 0x0ff;
|
||||
the_bytes[6] = ri->r_index & 0x0ff;
|
||||
the_bytes[7] = ((ri->r_extern << 7) & 0x80) | (0 & 0x60) | (ri->r_type & 0x1F);
|
||||
where[4] = (r_index >> 16) & 0x0ff;
|
||||
where[5] = (r_index >> 8) & 0x0ff;
|
||||
where[6] = r_index & 0x0ff;
|
||||
where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
|
||||
|
||||
/* Also easy */
|
||||
md_number_to_chars(&the_bytes[8], ri->r_addend, 4);
|
||||
} /* md_ri_to_chars() */
|
||||
if (fixP->fx_addsy->sy_frag) {
|
||||
r_addend = fixP->fx_addsy->sy_frag->fr_address;
|
||||
}
|
||||
|
||||
if (fixP->fx_pcrel) {
|
||||
r_addend -= r_address;
|
||||
} else {
|
||||
r_addend = fixP->fx_addnumber;
|
||||
}
|
||||
|
||||
md_number_to_chars(&where[8], r_addend, 4);
|
||||
|
||||
return;
|
||||
} /* tc_aout_fix_to_chars() */
|
||||
|
||||
/* should never be called for sparc */
|
||||
void md_convert_frag(fragP)
|
||||
void md_convert_frag(headers, fragP)
|
||||
object_headers *headers;
|
||||
register fragS *fragP;
|
||||
{
|
||||
fprintf(stderr, "sparc_convert_frag\n");
|
||||
@ -1450,8 +1560,10 @@ struct sparc_it *insn;
|
||||
|
||||
/* Set the hook... */
|
||||
|
||||
void emit_sparc_reloc();
|
||||
void (*md_emit_relocations)() = emit_sparc_reloc;
|
||||
/* void emit_sparc_reloc();
|
||||
void (*md_emit_relocations)() = emit_sparc_reloc; */
|
||||
|
||||
#ifdef comment
|
||||
|
||||
/*
|
||||
* Sparc/AM29K relocations are completely different, so it needs
|
||||
@ -1503,6 +1615,7 @@ relax_addressT segment_address_in_file;
|
||||
return;
|
||||
} /* emit_sparc_reloc() */
|
||||
#endif /* aout or bout */
|
||||
#endif /* comment */
|
||||
|
||||
/*
|
||||
* md_parse_option
|
||||
|
Loading…
Reference in New Issue
Block a user