* 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:
K. Richard Pixley 1991-08-14 00:26:06 +00:00
parent b6de2014a1
commit a79c6033ed
6 changed files with 323 additions and 257 deletions

View file

@ -93,16 +93,6 @@ const pseudo_typeS obj_pseudo_table[] = {
/* Relocation. */ /* 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() * emit_relocations()
* *
@ -113,40 +103,13 @@ char **where;
fixS *fixP; /* Fixup chain for this segment. */ fixS *fixP; /* Fixup chain for this segment. */
relax_addressT segment_address_in_file; relax_addressT segment_address_in_file;
{ {
struct relocation_info ri; for (; fixP; fixP = fixP->fx_next) {
register symbolS * symbolP; 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 */
/* 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;
}
}
} /* emit_relocations() */ } /* emit_relocations() */
/* Aout file generation & utilities */ /* Aout file generation & utilities */
@ -168,7 +131,7 @@ object_headers *headers;
headers->header.a_balign = section_alignment[SEG_BSS]; headers->header.a_balign = section_alignment[SEG_BSS];
headers->header.a_tload = 0; 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)); append(where, (char *) &headers->header, sizeof(headers->header));
} /* a_header_append() */ } /* a_header_append() */

View file

@ -247,6 +247,7 @@ struct relocation_info {
H_GET_DATA_RELOCATION_SIZE(h) + \ H_GET_DATA_RELOCATION_SIZE(h) + \
(h)->string_table_size) (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_TEXT_SIZE(h) ((h)->header.a_text)
#define H_GET_DATA_SIZE(h) ((h)->header.a_data) #define H_GET_DATA_SIZE(h) ((h)->header.a_data)
#define H_GET_BSS_SIZE(h) ((h)->header.a_bss) #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_MAGIC_NUMBER(h) ((h)->header.a_info)
#define H_GET_ENTRY_POINT(h) ((h)->header.a_entry) #define H_GET_ENTRY_POINT(h) ((h)->header.a_entry)
#define H_GET_STRING_SIZE(h) ((h)->string_table_size) #define H_GET_STRING_SIZE(h) ((h)->string_table_size)
#define H_GET_LINENO_SIZE(h) (0)
#ifdef EXEC_MACHINE_TYPE #ifdef EXEC_MACHINE_TYPE
#define H_GET_MACHINE_TYPE(h) ((h)->header.a_machtype) #define H_GET_MACHINE_TYPE(h) ((h)->header.a_machtype)
#endif /* EXEC_MACHINE_TYPE */ #endif /* EXEC_MACHINE_TYPE */
@ -263,9 +266,9 @@ struct relocation_info {
#define H_GET_VERSION(h) ((h)->header.a_version) #define H_GET_VERSION(h) ((h)->header.a_version)
#endif /* EXEC_VERSION */ #endif /* EXEC_VERSION */
#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = md_section_align(SEG_TEXT, (v))) #define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = (v))
#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = md_section_align(SEG_DATA, (v))) #define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = (v))
#define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = md_section_align(SEG_BSS, (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)),\ #define H_SET_RELOCATION_SIZE(h,t,d) (H_SET_TEXT_RELOCATION_SIZE((h),(t)),\
H_SET_DATA_RELOCATION_SIZE((h),(d))) H_SET_DATA_RELOCATION_SIZE((h),(d)))
@ -302,6 +305,13 @@ typedef struct {
#define OBJ_EMIT_LINENO(a, b, c) ; #define OBJ_EMIT_LINENO(a, b, c) ;
#define obj_pre_write_hook(a) ; #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: * Local Variables:
* comment-column: 0 * comment-column: 0

View file

@ -903,29 +903,6 @@ symbolS *to_symbol;
abort(); 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 */ /* should never be called for 29k */
void md_convert_frag(headers, fragP) void md_convert_frag(headers, fragP)
object_headers *headers; object_headers *headers;
@ -1012,48 +989,45 @@ print_insn(insn)
} }
#endif #endif
/* /* Translate internal representation of relocation info to target format.
* Sparc/A29K relocations are completely different, so it needs
* this machine dependent routine to emit them. 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 #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; relax_addressT segment_address_in_file;
{ {
struct reloc_info_generic ri; long r_index;
register symbolS *symbolP;
extern char *next_object_file_charP;
/* !!!! long add_number; */
bzero((char *) &ri, sizeof(ri)); know(fixP->fx_r_type < NO_RELOC);
for (; fixP; fixP = fixP->fx_next) { know(fixP->fx_addsy != NULL);
if (fixP->fx_r_type >= NO_RELOC) { r_index = (S_IS_DEFINED(fixP->fx_addsy)
fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type); ? S_GET_TYPE(fixP->fx_addsy)
abort(); : fixP->fx_addsy->sy_number);
}
if ((symbolP = fixP->fx_addsy) != NULL) { /* this is easy */
ri.r_address = fixP->fx_frag->fr_address + md_number_to_chars(where,
fixP->fx_where - segment_address_in_file; fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
ri.r_addend = fixP->fx_addnumber; 4);
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); /* now the fun stuff */
next_object_file_charP += md_reloc_size; where[4] = (r_index >> 16) & 0x0ff;
} where[5] = (r_index >> 8) & 0x0ff;
} where[6] = r_index & 0x0ff;
} /* emit_machine_reloc() */ 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);
void (*md_emit_relocations)() = emit_machine_reloc; return;
} /* tc_aout_fix_to_chars() */
#endif /* OBJ_AOUT */ #endif /* OBJ_AOUT */

View file

@ -5,7 +5,7 @@ This file is part of GAS.
GAS is free software; you can redistribute it and/or modify GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by 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. any later version.
GAS is distributed in the hope that it will be useful, 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 char *input_line_pointer;
extern struct hash_control *po_hash; extern struct hash_control *po_hash;
extern unsigned char nbytes_r_length[];
extern char *next_object_file_charP; extern char *next_object_file_charP;
#ifdef OBJ_COFF #ifdef OBJ_COFF
@ -95,20 +94,6 @@ int md_reloc_size = sizeof(struct reloc);
int md_reloc_size = sizeof(struct relocation_info); int md_reloc_size = sizeof(struct relocation_info);
#endif /* OBJ_COFF */ #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 * * Local i80960 routines *
************************** */ ************************** */
@ -621,6 +606,8 @@ md_number_to_chars(buf, value, n)
if (value != 0 && value != -1){ if (value != 0 && value != -1){
as_bad("Displacement too long for instruction field length."); as_bad("Displacement too long for instruction field length.");
} }
return;
} /* md_number_to_chars() */ } /* md_number_to_chars() */
/***************************************************************************** /*****************************************************************************
@ -892,7 +879,8 @@ md_parse_option(argP, cntP, vecP)
* *
**************************************************************************** */ **************************************************************************** */
void void
md_convert_frag(fragP) md_convert_frag(headers, fragP)
object_headers *headers;
fragS * fragP; fragS * fragP;
{ {
fixS *fixP; /* Structure describing needed address fix */ 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. * we leave it in host byte order.
* *
**************************************************************************** */ **************************************************************************** */
void md_ri_to_chars(the_bytes, ri) void md_ri_to_chars(where, ri)
char *the_bytes; char *where;
struct reloc_info_generic *ri; struct relocation_info *ri;
{ {
struct relocation_info br; *((struct relocation_info *) where) = *ri; /* structure assignment */
(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;
} /* md_ri_to_chars() */ } /* md_ri_to_chars() */
#ifndef WORKING_DOT_WORD #ifndef WORKING_DOT_WORD
int md_short_jump_size = 0; int md_short_jump_size = 0;
@ -1393,14 +1367,14 @@ get_ispec(textP)
/* Find opening square bracket, if any /* Find opening square bracket, if any
*/ */
start = index(textP, '['); start = strchr(textP, '[');
if (start != NULL){ if (start != NULL){
/* Eliminate '[', detach from rest of operand */ /* Eliminate '[', detach from rest of operand */
*start++ = '\0'; *start++ = '\0';
end = index(start, ']'); end = strchr(start, ']');
if (end == NULL){ if (end == NULL){
as_bad("unmatched '['"); as_bad("unmatched '['");
@ -2569,54 +2543,41 @@ md_apply_fix(fixP, val)
} /* md_apply_fix() */ } /* md_apply_fix() */
#if defined(OBJ_AOUT) | defined(OBJ_BOUT) #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
/* void tc_bout_fix_to_chars(where, fixP, segment_address_in_file)
* emit_relocations() char *where;
* fixS *fixP;
* Crawl along a fixS chain. Emit the segment's relocations. relax_addressT segment_address_in_file;
*/
static void
emit_machine_reloc (fixP, segment_address_in_file)
register fixS * fixP; /* Fixup chain for this segment. */
relax_addressT segment_address_in_file;
{ {
struct reloc_info_generic ri; static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
register symbolS * symbolP; struct relocation_info ri;
symbolS *symbolP;
/* JF this is for paranoia */ /* JF this is for paranoia */
bzero((char *)&ri,sizeof(ri)); 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; know((symbolP = fixP->fx_addsy) != 0);
ri . r_length = nbytes_r_length [fixP->fx_size]; /* These two 'cuz of NS32K */
ri . r_pcrel = fixP->fx_pcrel; ri.r_callj = fixP->fx_callj;
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. */ ri.r_length = nbytes_r_length[fixP->fx_size];
md_ri_to_chars(next_object_file_charP, &ri); ri.r_pcrel = fixP->fx_pcrel;
next_object_file_charP += sizeof(struct relocation_info); 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);
} }
}
} /* emit_machine_reloc() */ /* Output the relocation information in machine-dependent form. */
md_ri_to_chars(where, &ri);
return;
} /* tc_bout_fix_to_chars() */
#endif /* OBJ_AOUT or OBJ_BOUT */ #endif /* OBJ_AOUT or OBJ_BOUT */
/* Align an address by rounding it up to the specified boundary. /* Align an address by rounding it up to the specified boundary.

View file

@ -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: * No argument string should generate such an error string:
* it means a bug in our code, not in the user's text. * 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. * this function.
*/ */
@ -1068,9 +1068,13 @@ char *instring;
} }
/* found a legitimate opcode, start matching operands */ /* found a legitimate opcode, start matching operands */
for(opP= &the_ins.operands[0];*p;opP++) { while (*p == ' ') ++p;
p = crack_operand (p, opP);
if(opP->error) { for(opP = &the_ins.operands[0]; *p; opP++) {
p = crack_operand(p, opP);
if (opP->error) {
the_ins.error=opP->error; the_ins.error=opP->error;
return; 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) */ nibble as nuthin. (on Sun 3 at least) */
/* Translate the internal relocation information into target-specific /* Translate the internal relocation information into target-specific
format. */ format. */
#ifdef comment
void void
md_ri_to_chars(the_bytes, ri) md_ri_to_chars(the_bytes, ri)
char *the_bytes; 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) | the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) |
((ri->r_extern << 4) & 0x10)); ((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 */ #endif /* OBJ_AOUT or OBJ_BOUT */
#ifndef WORKING_DOT_WORD #ifndef WORKING_DOT_WORD

View file

@ -42,7 +42,7 @@ static void sparc_ip();
static enum sparc_architecture current_architecture = v6; static enum sparc_architecture current_architecture = v6;
static int architecture_requested = 0; static int architecture_requested = 0;
static int warn_on_bump = 1; static int warn_on_bump = 0;
const relax_typeS md_relax_table[] = { const relax_typeS md_relax_table[] = {
0 }; 0 };
@ -428,7 +428,7 @@ char *str;
struct sparc_opcode *insn; struct sparc_opcode *insn;
char *argsStart; char *argsStart;
unsigned long opcode; unsigned long opcode;
unsigned int mask; unsigned int mask = 0;
int match = 0; int match = 0;
int comma = 0; int comma = 0;
@ -787,44 +787,134 @@ char *str;
/* start-sanitize-v9 */ /* start-sanitize-v9 */
#ifndef NO_V9 #ifndef NO_V9
case 'j': case 'j':
case 'u':
case 'U':
#endif /* NO_V9 */ #endif /* NO_V9 */
/* end-sanitize-v9 */ /* end-sanitize-v9 */
case 'e': /* next operand is a floating point register */ case 'e': /* next operand is a floating point register */
case 'v':
case 'V':
case 'f': case 'f':
case 'B':
case 'R':
case 'g': case 'g':
if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) { case 'H':
mask = *s++; case 'J': {
if (isdigit(*s)) { char format;
mask = 10 * (mask - '0') + (*s++ - '0');
if (mask >= 32) {
break;
}
} else {
mask -= '0';
}
switch (*args) {
case 'e': if (*s++ == '%'
opcode |= RS1(mask);
continue;
case 'f':
opcode |= RS2(mask);
continue;
case 'g':
opcode |= RD(mask);
continue;
/* start-sanitize-v9 */ /* start-sanitize-v9 */
#ifndef NO_V9 #ifndef NO_V9
case 'j': && ((format = *s) == 'f'
opcode |= (mask & 0x1f) << 9; || *s == 'd'
continue; || *s == 'q')
#else
/* end-sanitize-v9 */
&& ((format = *s) == 'f')
/* start-sanitize-v9 */
#endif /* NO_V9 */ #endif /* NO_V9 */
/* end-sanitize-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; break;
} /* float arg */
case 'F': case 'F':
if (strncmp(s, "%fsr", 4) == 0) { if (strncmp(s, "%fsr", 4) == 0) {
@ -1208,28 +1298,20 @@ long val;
/* start-sanitize-v9 */ /* start-sanitize-v9 */
#ifndef NO_V9 #ifndef NO_V9
case RELOC_11: case RELOC_11:
#if 0 if (((val > 0) && (val & ~0x7ff))
/* ??? Bogus overflow test. This is a signed value, so || ((val < 0) && (~val & ~0x7ff))) {
the upper bits can be set if the sign bit is set. */
if (val & ~0x7ff) {
as_bad("relocation overflow."); as_bad("relocation overflow.");
} /* on overflow */ } /* on overflow */
#endif
buf[2] = (val >> 8) & 0x7; buf[2] = (val >> 8) & 0x7;
buf[3] = val & 0xff; buf[3] = val & 0xff;
break; break;
case RELOC_WDISP2_14: case RELOC_WDISP2_14:
#if 0 if (((val > 0) && (val & ~0x3fffc))
/* ??? Bogus overflow test. This is a signed value, so || ((val < 0) && (~val & ~0x3fffc))) {
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) {
as_bad("relocation overflow."); as_bad("relocation overflow.");
} /* on overflow */ } /* on overflow */
#endif
val = (val >>= 2) + 1; val = (val >>= 2) + 1;
buf[1] |= ((val >> 14) & 0x3) << 3; buf[1] |= ((val >> 14) & 0x3) << 3;
@ -1238,15 +1320,10 @@ long val;
break; break;
case RELOC_WDISP19: case RELOC_WDISP19:
#if 0 if (((val > 0) && (val & ~0x1ffffc))
/* ??? Bogus overflow test. This is a signed value, so || ((val < 0) && (~val & ~0x1ffffc))) {
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) {
as_bad("relocation overflow."); as_bad("relocation overflow.");
} /* on overflow */ } /* on overflow */
#endif
val = (val >>= 2) + 1; val = (val >>= 2) + 1;
buf[1] |= (val >> 16) & 0x7; buf[1] |= (val >> 16) & 0x7;
@ -1255,7 +1332,7 @@ long val;
break; break;
case RELOC_HHI22: case RELOC_HHI22:
val >> 32; val >>= 32;
/* intentional fallthrough */ /* intentional fallthrough */
#endif /* NO_V9 */ #endif /* NO_V9 */
/* end-sanitize-v9 */ /* end-sanitize-v9 */
@ -1345,23 +1422,56 @@ symbolS *to_symbol;
bit 7 as external, bits 6 & 5 unused, and the lower bit 7 as external, bits 6 & 5 unused, and the lower
five bits as relocation type. Next 4 bytes are long addend. */ 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 */ /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
void md_ri_to_chars(the_bytes, ri) void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
char *the_bytes; char *where;
struct reloc_info_generic *ri; 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 */ /* 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 */ /* now the fun stuff */
the_bytes[4] = (ri->r_index >> 16) & 0x0ff; where[4] = (r_index >> 16) & 0x0ff;
the_bytes[5] = (ri->r_index >> 8) & 0x0ff; where[5] = (r_index >> 8) & 0x0ff;
the_bytes[6] = ri->r_index & 0x0ff; where[6] = r_index & 0x0ff;
the_bytes[7] = ((ri->r_extern << 7) & 0x80) | (0 & 0x60) | (ri->r_type & 0x1F); where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
/* Also easy */ /* Also easy */
md_number_to_chars(&the_bytes[8], ri->r_addend, 4); if (fixP->fx_addsy->sy_frag) {
} /* md_ri_to_chars() */ 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 */ /* should never be called for sparc */
void md_convert_frag(fragP) void md_convert_frag(headers, fragP)
object_headers *headers;
register fragS *fragP; register fragS *fragP;
{ {
fprintf(stderr, "sparc_convert_frag\n"); fprintf(stderr, "sparc_convert_frag\n");
@ -1450,8 +1560,10 @@ struct sparc_it *insn;
/* Set the hook... */ /* Set the hook... */
void emit_sparc_reloc(); /* void emit_sparc_reloc();
void (*md_emit_relocations)() = emit_sparc_reloc; void (*md_emit_relocations)() = emit_sparc_reloc; */
#ifdef comment
/* /*
* Sparc/AM29K relocations are completely different, so it needs * Sparc/AM29K relocations are completely different, so it needs
@ -1503,6 +1615,7 @@ relax_addressT segment_address_in_file;
return; return;
} /* emit_sparc_reloc() */ } /* emit_sparc_reloc() */
#endif /* aout or bout */ #endif /* aout or bout */
#endif /* comment */
/* /*
* md_parse_option * md_parse_option