fix for pr1371: heed fx_offset in pcrel relocs

This commit is contained in:
Ken Raeburn
1992-08-01 23:20:55 +00:00
parent 3dfa6cfb66
commit 680227f309
2 changed files with 1607 additions and 1421 deletions

View File

@ -1,3 +1,8 @@
Sat Aug 1 19:10:13 1992 Ken Raeburn (raeburn@cygnus.com)
* config/tc-sparc.c (tc_aout_fix_to_chars): If pc-relative, take
fx_offset into account.
Fri Jul 31 21:53:28 1992 Ken Raeburn (raeburn@cygnus.com)
* configure.in (mips host): Accept "ultrix" with version number.

View File

@ -343,6 +343,39 @@ static void s_proc() {
return;
} /* s_proc() */
/* start-sanitize-v9 */
#ifndef NO_V9
struct priv_reg_entry { char *name; int regnum; };
struct priv_reg_entry priv_reg_table[] =
{
{ "tpc", 0 },
{ "tnpc", 1 },
{ "tstate", 2 },
{ "tt", 3 },
{ "tick", 4 },
{ "tba", 5 },
{ "pstate", 6 },
{ "tl", 7 },
{ "pil", 8 },
{ "cwp", 9 },
{ "cansave", 10 },
{ "canrestore", 11 },
{ "cleanwin", 12 },
{ "otherwin", 13 },
{ "wstate", 14},
{ "fpq", 15},
{ "ver", 31 },
{ "", -1 }, /* end marker */
};
static int cmp_reg_entry (p, q)
struct priv_reg_entry *p, *q;
{
return strcmp (q->name, p->name);
}
#endif
/* end-sanitize-v9 */
/* This function is called once, at assembler startup time. It should
set up all the tables, etc. that the MD part of the assembler will need. */
void md_begin() {
@ -385,6 +418,13 @@ void md_begin() {
toHex[i] = i + 10 - 'a';
for (i = 'A'; i <= 'F'; ++i)
toHex[i] = i + 10 - 'A';
/* start-sanitize-v9 */
#ifndef NO_V9
qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
sizeof (priv_reg_table[0]), cmp_reg_entry);
#endif
/* end-sanitize-v9 */
} /* md_begin() */
void md_end() {
@ -526,6 +566,115 @@ static void sparc_ip(str)
for (args = insn->args; ; ++args) {
switch (*args) {
/* start-sanitize-v9 */
#ifndef NO_V9
case 'K':
{
/* Load is 0; Store is 1.
We compute the mask based on the values
we find in S. OK is set set
if we see something we don't like. */
int ok = 1;
int mask = 0;
while (ok == 1)
{
int lo = 0, hi = 0;
if (*s == '#')
{
s += 1;
if (! (lo = (s[0] == 'S')))
ok = (s[0] == 'L');
if (! (hi = (s[1] == 'S')))
ok = (s[1] == 'L');
mask |= (1 << ((hi<<1) | lo));
s += 2;
}
else
{
/* Parse a number, somehow. */
ok = 0;
}
if (s[2] != '|')
break;
}
if (! ok)
{
error_message = "unrecognizable mmask";
goto error;
}
opcode |= SIMM13(mask);
continue;
}
case '*':
/* Parse a prefetch function. */
if (*s == '#')
{
int prefetch_fcn = 0;
s += 1;
if (! strncmp (s, "n_reads", 7))
prefetch_fcn = 0, s += 7;
else if (! strncmp (s, "one_read", 8))
prefetch_fcn = 1, s += 8;
else if (! strncmp (s, "n_writes", 8))
prefetch_fcn = 2, s += 8;
else if (! strncmp (s, "one_write", 9))
prefetch_fcn = 3, s += 9;
else if (! strncmp (s, "page", 4))
prefetch_fcn = 4, s += 4;
else
{
error_message = "unrecognizable prefetch fucntion";
goto error;
}
}
else
{
/* Parse a number, somehow. */
error_message = "unrecognizable prefetch fucntion";
goto error;
}
continue;
case '!':
case '?':
/* Parse a privileged register. */
if (*s == '%')
{
struct priv_reg_entry *p = priv_reg_table;
int len;
s += 1;
while (p->name[0] > s[0])
p++;
while (p->name[0] == s[0])
{
len = strlen (p->name);
if (strncmp (p->name, s, len) == 0)
break;
p++;
}
if (p->name[0] != s[0])
{
error_message = "unrecognizable privileged register";
goto error;
}
if (*args == '?')
opcode |= (p->regnum << 14);
else
opcode |= (p->regnum << 25);
s += len;
continue;
}
else
{
error_message = "unrecognizable privileged register";
goto error;
}
#endif
/* end-sanitize-v9 */
case 'M':
case 'm':
if (strncmp(s, "%asr", 4) == 0) {
@ -1120,6 +1269,22 @@ static void sparc_ip(str)
}
break;
/* start-sanitize-v9 */
#ifndef NO_V9
case 's':
if (strncmp (s, "%usr", 4) != 0)
break;
s += 4;
continue;
case 'o':
if (strncmp (s, "%asi", 4) != 0)
break;
s += 4;
continue;
#endif /* NO_V9 */
/* end-sanitize-v9 */
case 't':
if (strncmp(s, "%tbr", 4) != 0)
break;
@ -1157,8 +1322,19 @@ static void sparc_ip(str)
}
} else {
if (insn->architecture > current_architecture) {
if (!architecture_requested || warn_on_bump) {
if ((!architecture_requested || warn_on_bump)
&&
/* start-sanitize-v9 */
#ifndef NO_V9
! ARCHITECTURES_CONFLICT_P (current_architecture,
insn->architecture)
#else
/* end-sanitize-v9 */
1
/* start-sanitize-v9 */
#endif
/* end-sanitize-v9 */
) {
if (warn_on_bump) {
as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
architecture_pname[current_architecture],
@ -1491,7 +1667,8 @@ void md_create_short_jump(ptr, from_addr, to_addr, frag, 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 tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
void
tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
char *where;
fixS *fixP;
relax_addressT segment_address_in_file;
@ -1503,7 +1680,7 @@ void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
know(fixP->fx_addsy);
if ((S_GET_TYPE(fixP->fx_addsy)) == N_UNDF) {
if (!S_IS_DEFINED(fixP->fx_addsy)) {
r_extern = 1;
r_index = fixP->fx_addsy->sy_number;
} else {
@ -1528,7 +1705,7 @@ void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
}
if (fixP->fx_pcrel) {
r_addend -= r_address;
r_addend += fixP->fx_offset - r_address;
} else {
r_addend = fixP->fx_addnumber;
}
@ -1690,7 +1867,7 @@ void emit_sparc_reloc(fixP, segment_address_in_file)
* -bump
* Warn on architecture bumps. See also -A.
*
* -Av6, -Av7, -Av8
* -Av6, -Av7, -Av8, -Asparclite
* Select the architecture. Instructions or features not
* supported by the selected architecture cause fatal errors.
*
@ -1708,6 +1885,10 @@ void emit_sparc_reloc(fixP, segment_address_in_file)
* architecture starts at the specified level, but bumps are
* warnings.
*
* start-sanitize-v9
* Bumping between incompatible architectures is always an
* error. For example, from sparclite to v9.
* end-sanitize-v9
*/
/* start-sanitize-v9 */
/* There is also a -Av9 architecture option. xoxorich. */