aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorK. Richard Pixley <rich@cygnus>1991-08-14 00:26:06 +0000
committerK. Richard Pixley <rich@cygnus>1991-08-14 00:26:06 +0000
commita79c6033ed4df262e86ac15a016e187e65d0674c (patch)
treef36c001a51022958c8160a43f4c043bdb17eea0a /gas
parentb6de2014a14fb75de126bff749efdc48529add90 (diff)
downloadgdb-a79c6033ed4df262e86ac15a016e187e65d0674c.zip
gdb-a79c6033ed4df262e86ac15a016e187e65d0674c.tar.gz
gdb-a79c6033ed4df262e86ac15a016e187e65d0674c.tar.bz2
* no more relocation_info structures. We now squirt directly from
fixS's. * i960-bout and i960-coff "tested" against their predecessors.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/obj-bout.c53
-rw-r--r--gas/config/obj-bout.h16
-rw-r--r--gas/config/tc-a29k.c96
-rw-r--r--gas/config/tc-i960.c123
-rw-r--r--gas/config/tc-m68k.c53
-rw-r--r--gas/config/tc-sparc.c233
6 files changed, 320 insertions, 254 deletions
diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c
index b759ff0..74cd5f7 100644
--- a/gas/config/obj-bout.c
+++ b/gas/config/obj-bout.c
@@ -94,16 +94,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()
*
* Crawl along a fixS chain. Emit the segment's 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() */
diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h
index 00ba2a4..1b0743e 100644
--- a/gas/config/obj-bout.h
+++ b/gas/config/obj-bout.h
@@ -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
diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c
index fecdc5d..80a6382 100644
--- a/gas/config/tc-a29k.c
+++ b/gas/config/tc-a29k.c
@@ -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.
- */
-#ifdef OBJ_AOUT
-static void emit_machine_reloc(fixP, segment_address_in_file)
-register 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; */
-
- bzero((char *) &ri, sizeof(ri));
- for (; fixP; fixP = fixP->fx_next) {
+/* Translate internal representation of relocation info to target format.
- if (fixP->fx_r_type >= NO_RELOC) {
- fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
- abort();
- }
+ 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 */
- 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;
+#ifdef OBJ_AOUT
- md_ri_to_chars (next_object_file_charP, &ri);
- next_object_file_charP += md_reloc_size;
- }
- }
-} /* emit_machine_reloc() */
+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;
+
+ 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);
-void (*md_emit_relocations)() = emit_machine_reloc;
+ return;
+} /* tc_aout_fix_to_chars() */
#endif /* OBJ_AOUT */
diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c
index a32325b..a551376 100644
--- a/gas/config/tc-i960.c
+++ b/gas/config/tc-i960.c
@@ -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.
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c
index 9c30a04..c6924db 100644
--- a/gas/config/tc-m68k.c
+++ b/gas/config/tc-m68k.c
@@ -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
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index 47fdbd2..1f41129 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -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');
+ case 'H':
+ case 'J': {
+ char format;
+
+ if (*s++ == '%'
+
+ /* start-sanitize-v9 */
+#ifndef NO_V9
+ && ((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) {
- break;
- }
+ error_message = ": There are only 32 f registers; [0-31]";
+ goto error;
+ } /* on error */
+ /* start-sanitize-v9 */
+#ifndef NO_V9
} else {
- mask -= '0';
- }
- switch (*args) {
-
- case 'e':
- opcode |= RS1(mask);
- continue;
-
- case 'f':
- opcode |= RS2(mask);
- continue;
+ 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 */
- case 'g':
- opcode |= RD(mask);
- continue;
+ 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':
- opcode |= (mask & 0x1f) << 9;
- continue;
+ 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